Loading net/bridge/br_netfilter.c +63 −53 Original line number Diff line number Diff line Loading @@ -218,12 +218,17 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; if (dnat_took_place(skb)) { if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) { if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) { struct rtable *rt; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = 0 , .tos = RT_TOS(iph->tos)} }, .proto = 0}; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = 0, .tos = RT_TOS(iph->tos) }, }, .proto = 0, }; if (!ip_route_output_key(&rt, &fl)) { /* - Bridged-and-DNAT'ed traffic doesn't Loading Loading @@ -257,8 +262,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) 1); return 0; } memcpy(eth_hdr(skb)->h_dest, dev->dev_addr, ETH_ALEN); memcpy(eth_hdr(skb)->h_dest, dev->dev_addr, ETH_ALEN); skb->pkt_type = PACKET_HOST; } } else { Loading Loading @@ -350,8 +354,10 @@ static int check_hbh_len(struct sk_buff *skb) /* Replicate the checks that IPv6 does on packet reception and pass the packet * to ip6tables, which doesn't support NAT, so things are fairly simple. */ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct ipv6hdr *hdr; u32 pkt_len; Loading Loading @@ -496,7 +502,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, * register an IPv4 PRE_ROUTING 'sabotage' hook that will * prevent this from happening. */ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading @@ -509,7 +516,6 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb, return NF_ACCEPT; } /* PF_BRIDGE/FORWARD *************************************************/ static int br_nf_forward_finish(struct sk_buff *skb) { Loading Loading @@ -541,7 +547,8 @@ static int br_nf_forward_finish(struct sk_buff *skb) * because of the physdev module. For ARP, indev and outdev are the * bridge ports. */ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading Loading @@ -584,7 +591,8 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, } static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading Loading @@ -617,7 +625,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, return NF_STOLEN; } /* PF_BRIDGE/LOCAL_OUT ***********************************************/ static int br_nf_local_out_finish(struct sk_buff *skb) { Loading Loading @@ -653,7 +660,8 @@ static int br_nf_local_out_finish(struct sk_buff *skb) * even routed packets that didn't arrive on a bridge interface have their * nf_bridge->physindev set. */ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct net_device *realindev, *realoutdev; Loading Loading @@ -738,7 +746,8 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, /* PF_BRIDGE/POST_ROUTING ********************************************/ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading Loading @@ -811,12 +820,12 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, #endif } /* IP/SABOTAGE *****************************************************/ /* Don't hand locally destined packets to PF_INET(6)/PRE_ROUTING * for the second time. */ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { if ((*pskb)->nf_bridge && Loading @@ -831,15 +840,15 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb, * and PF_INET(6)/POST_ROUTING until we have done the forwarding * decision in the bridge code and have determined nf_bridge->physoutdev. */ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; if ((out->hard_start_xmit == br_dev_xmit && okfn != br_nf_forward_finish && okfn != br_nf_local_out_finish && okfn != br_dev_queue_push_xmit) okfn != br_nf_local_out_finish && okfn != br_dev_queue_push_xmit) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) || ((out->priv_flags & IFF_802_1Q_VLAN) && VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) Loading Loading @@ -1055,7 +1064,8 @@ int br_netfilter_init(void) #ifdef CONFIG_SYSCTL brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0); if (brnf_sysctl_header == NULL) { printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) nf_unregister_hook(&br_nf_ops[i]); return -EFAULT; Loading Loading
net/bridge/br_netfilter.c +63 −53 Original line number Diff line number Diff line Loading @@ -218,12 +218,17 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; if (dnat_took_place(skb)) { if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) { if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) { struct rtable *rt; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = 0 , .tos = RT_TOS(iph->tos)} }, .proto = 0}; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = 0, .tos = RT_TOS(iph->tos) }, }, .proto = 0, }; if (!ip_route_output_key(&rt, &fl)) { /* - Bridged-and-DNAT'ed traffic doesn't Loading Loading @@ -257,8 +262,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) 1); return 0; } memcpy(eth_hdr(skb)->h_dest, dev->dev_addr, ETH_ALEN); memcpy(eth_hdr(skb)->h_dest, dev->dev_addr, ETH_ALEN); skb->pkt_type = PACKET_HOST; } } else { Loading Loading @@ -350,8 +354,10 @@ static int check_hbh_len(struct sk_buff *skb) /* Replicate the checks that IPv6 does on packet reception and pass the packet * to ip6tables, which doesn't support NAT, so things are fairly simple. */ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct ipv6hdr *hdr; u32 pkt_len; Loading Loading @@ -496,7 +502,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, * register an IPv4 PRE_ROUTING 'sabotage' hook that will * prevent this from happening. */ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading @@ -509,7 +516,6 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb, return NF_ACCEPT; } /* PF_BRIDGE/FORWARD *************************************************/ static int br_nf_forward_finish(struct sk_buff *skb) { Loading Loading @@ -541,7 +547,8 @@ static int br_nf_forward_finish(struct sk_buff *skb) * because of the physdev module. For ARP, indev and outdev are the * bridge ports. */ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading Loading @@ -584,7 +591,8 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, } static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading Loading @@ -617,7 +625,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, return NF_STOLEN; } /* PF_BRIDGE/LOCAL_OUT ***********************************************/ static int br_nf_local_out_finish(struct sk_buff *skb) { Loading Loading @@ -653,7 +660,8 @@ static int br_nf_local_out_finish(struct sk_buff *skb) * even routed packets that didn't arrive on a bridge interface have their * nf_bridge->physindev set. */ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct net_device *realindev, *realoutdev; Loading Loading @@ -738,7 +746,8 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, /* PF_BRIDGE/POST_ROUTING ********************************************/ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; Loading Loading @@ -811,12 +820,12 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, #endif } /* IP/SABOTAGE *****************************************************/ /* Don't hand locally destined packets to PF_INET(6)/PRE_ROUTING * for the second time. */ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { if ((*pskb)->nf_bridge && Loading @@ -831,15 +840,15 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb, * and PF_INET(6)/POST_ROUTING until we have done the forwarding * decision in the bridge code and have determined nf_bridge->physoutdev. */ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *skb = *pskb; if ((out->hard_start_xmit == br_dev_xmit && okfn != br_nf_forward_finish && okfn != br_nf_local_out_finish && okfn != br_dev_queue_push_xmit) okfn != br_nf_local_out_finish && okfn != br_dev_queue_push_xmit) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) || ((out->priv_flags & IFF_802_1Q_VLAN) && VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) Loading Loading @@ -1055,7 +1064,8 @@ int br_netfilter_init(void) #ifdef CONFIG_SYSCTL brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0); if (brnf_sysctl_header == NULL) { printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) nf_unregister_hook(&br_nf_ops[i]); return -EFAULT; Loading