In order to make netfilter happy, we have to create a fake routing table
entry. Unfortunately, the kernel really doesn't like this when it actually
needs to make use of it. This code now removes the link between the packet
and the fake routing entry when the packet is being sent to a local port.
case OFPP_LOCAL: {
struct net_device *dev = dp->netdev;
case OFPP_LOCAL: {
struct net_device *dev = dp->netdev;
+#ifdef SUPPORT_SNAT
+ snat_local_in(skb);
+#endif
return dev ? dp_dev_recv(dev, skb) : -ESRCH;
}
return dev ? dp_dev_recv(dev, skb) : -ESRCH;
}
spin_unlock_irqrestore(&p->lock, flags);
}
spin_unlock_irqrestore(&p->lock, flags);
}
+/* When the packet is bound for a local interface, strip off the fake
+ * routing table.
+ */
+void snat_local_in(struct sk_buff *skb)
+{
+ if (skb->dst == (struct dst_entry *)&__fake_rtable) {
+ dst_release(skb->dst);
+ skb->dst = NULL;
+ }
+}
+
/* Check whether destination IP's address is in the IP->MAC mappings.
* If it is, then overwrite the destination MAC with the value from the
* cache.
/* Check whether destination IP's address is in the IP->MAC mappings.
* If it is, then overwrite the destination MAC with the value from the
* cache.
{
struct net_bridge_port *p = skb->dev->br_port;
{
struct net_bridge_port *p = skb->dev->br_port;
+ skb->dst = (struct dst_entry *)&__fake_rtable;
+ dst_hold(skb->dst);
+
/* If SNAT is configured for this input device, check the IP->MAC
* mappings to see if we should update the destination MAC. */
if (p->snat)
/* If SNAT is configured for this input device, check the IP->MAC
* mappings to see if we should update the destination MAC. */
if (p->snat)
if (pskb_trim_rcsum(skb, len))
goto ipv4_error;
if (pskb_trim_rcsum(skb, len))
goto ipv4_error;
- skb->dst = (struct dst_entry *)&__fake_rtable;
- dst_hold(skb->dst);
-
return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
snat_pre_route_finish);
return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
snat_pre_route_finish);
#define MAC_TIMEOUT_DEFAULT 120
#define MAC_TIMEOUT_DEFAULT 120
+void snat_local_in(struct sk_buff *skb);
int snat_pre_route(struct sk_buff *skb);
void snat_skb(struct datapath *dp, struct sk_buff *skb, int out_port);
void snat_maint(struct net_bridge_port *p);
int snat_pre_route(struct sk_buff *skb);
void snat_skb(struct datapath *dp, struct sk_buff *skb, int out_port);
void snat_maint(struct net_bridge_port *p);