diff options
Diffstat (limited to 'net/bridge')
| -rw-r--r-- | net/bridge/br_multicast.c | 4 | ||||
| -rw-r--r-- | net/bridge/br_netfilter.c | 27 | ||||
| -rw-r--r-- | net/bridge/br_stp_timer.c | 2 |
3 files changed, 13 insertions, 20 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 4b6722f8f179..22fd0419b314 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -1072,7 +1072,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, | |||
| 1072 | 1072 | ||
| 1073 | err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, | 1073 | err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, |
| 1074 | vid); | 1074 | vid); |
| 1075 | if (!err) | 1075 | if (err) |
| 1076 | break; | 1076 | break; |
| 1077 | } | 1077 | } |
| 1078 | 1078 | ||
| @@ -1822,7 +1822,7 @@ static void br_multicast_query_expired(struct net_bridge *br, | |||
| 1822 | if (query->startup_sent < br->multicast_startup_query_count) | 1822 | if (query->startup_sent < br->multicast_startup_query_count) |
| 1823 | query->startup_sent++; | 1823 | query->startup_sent++; |
| 1824 | 1824 | ||
| 1825 | RCU_INIT_POINTER(querier, NULL); | 1825 | RCU_INIT_POINTER(querier->port, NULL); |
| 1826 | br_multicast_send_query(br, NULL, query); | 1826 | br_multicast_send_query(br, NULL, query); |
| 1827 | spin_unlock(&br->multicast_lock); | 1827 | spin_unlock(&br->multicast_lock); |
| 1828 | } | 1828 | } |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index ab55e2472beb..60ddfbeb47f5 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -37,10 +37,6 @@ | |||
| 37 | #include <net/route.h> | 37 | #include <net/route.h> |
| 38 | #include <net/netfilter/br_netfilter.h> | 38 | #include <net/netfilter/br_netfilter.h> |
| 39 | 39 | ||
| 40 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | ||
| 41 | #include <net/netfilter/nf_conntrack.h> | ||
| 42 | #endif | ||
| 43 | |||
| 44 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| 45 | #include "br_private.h" | 41 | #include "br_private.h" |
| 46 | #ifdef CONFIG_SYSCTL | 42 | #ifdef CONFIG_SYSCTL |
| @@ -350,24 +346,15 @@ free_skb: | |||
| 350 | return 0; | 346 | return 0; |
| 351 | } | 347 | } |
| 352 | 348 | ||
| 353 | static bool dnat_took_place(const struct sk_buff *skb) | 349 | static bool daddr_was_changed(const struct sk_buff *skb, |
| 350 | const struct nf_bridge_info *nf_bridge) | ||
| 354 | { | 351 | { |
| 355 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | 352 | return ip_hdr(skb)->daddr != nf_bridge->ipv4_daddr; |
| 356 | enum ip_conntrack_info ctinfo; | ||
| 357 | struct nf_conn *ct; | ||
| 358 | |||
| 359 | ct = nf_ct_get(skb, &ctinfo); | ||
| 360 | if (!ct || nf_ct_is_untracked(ct)) | ||
| 361 | return false; | ||
| 362 | |||
| 363 | return test_bit(IPS_DST_NAT_BIT, &ct->status); | ||
| 364 | #else | ||
| 365 | return false; | ||
| 366 | #endif | ||
| 367 | } | 353 | } |
| 368 | 354 | ||
| 369 | /* This requires some explaining. If DNAT has taken place, | 355 | /* This requires some explaining. If DNAT has taken place, |
| 370 | * we will need to fix up the destination Ethernet address. | 356 | * we will need to fix up the destination Ethernet address. |
| 357 | * This is also true when SNAT takes place (for the reply direction). | ||
| 371 | * | 358 | * |
| 372 | * There are two cases to consider: | 359 | * There are two cases to consider: |
| 373 | * 1. The packet was DNAT'ed to a device in the same bridge | 360 | * 1. The packet was DNAT'ed to a device in the same bridge |
| @@ -421,7 +408,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb) | |||
| 421 | nf_bridge->pkt_otherhost = false; | 408 | nf_bridge->pkt_otherhost = false; |
| 422 | } | 409 | } |
| 423 | nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; | 410 | nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; |
| 424 | if (dnat_took_place(skb)) { | 411 | if (daddr_was_changed(skb, nf_bridge)) { |
| 425 | if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { | 412 | if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { |
| 426 | struct in_device *in_dev = __in_dev_get_rcu(dev); | 413 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
| 427 | 414 | ||
| @@ -632,6 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, | |||
| 632 | struct sk_buff *skb, | 619 | struct sk_buff *skb, |
| 633 | const struct nf_hook_state *state) | 620 | const struct nf_hook_state *state) |
| 634 | { | 621 | { |
| 622 | struct nf_bridge_info *nf_bridge; | ||
| 635 | struct net_bridge_port *p; | 623 | struct net_bridge_port *p; |
| 636 | struct net_bridge *br; | 624 | struct net_bridge *br; |
| 637 | __u32 len = nf_bridge_encap_header_len(skb); | 625 | __u32 len = nf_bridge_encap_header_len(skb); |
| @@ -669,6 +657,9 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, | |||
| 669 | if (!setup_pre_routing(skb)) | 657 | if (!setup_pre_routing(skb)) |
| 670 | return NF_DROP; | 658 | return NF_DROP; |
| 671 | 659 | ||
| 660 | nf_bridge = nf_bridge_info_get(skb); | ||
| 661 | nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr; | ||
| 662 | |||
| 672 | skb->protocol = htons(ETH_P_IP); | 663 | skb->protocol = htons(ETH_P_IP); |
| 673 | 664 | ||
| 674 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb, | 665 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb, |
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c index 4fcaa67750fd..7caf7fae2d5b 100644 --- a/net/bridge/br_stp_timer.c +++ b/net/bridge/br_stp_timer.c | |||
| @@ -97,7 +97,9 @@ static void br_forward_delay_timer_expired(unsigned long arg) | |||
| 97 | netif_carrier_on(br->dev); | 97 | netif_carrier_on(br->dev); |
| 98 | } | 98 | } |
| 99 | br_log_state(p); | 99 | br_log_state(p); |
| 100 | rcu_read_lock(); | ||
| 100 | br_ifinfo_notify(RTM_NEWLINK, p); | 101 | br_ifinfo_notify(RTM_NEWLINK, p); |
| 102 | rcu_read_unlock(); | ||
| 101 | spin_unlock(&br->lock); | 103 | spin_unlock(&br->lock); |
| 102 | } | 104 | } |
| 103 | 105 | ||
