diff options
author | David S. Miller <davem@davemloft.net> | 2015-08-01 02:52:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-01 02:52:20 -0400 |
commit | 5510b3c2a173921374ec847848fb20b98e1c698a (patch) | |
tree | c9e185281ef17280ce0dc30be7923124874736b0 /net/bridge | |
parent | 17f901e8915cb922c2ca710835ef34f166f53ee9 (diff) | |
parent | 7c764cec3703583247c4ab837c652975a3d41f4b (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
arch/s390/net/bpf_jit_comp.c
drivers/net/ethernet/ti/netcp_ethss.c
net/bridge/br_multicast.c
net/ipv4/ip_fragment.c
All four conflicts were cases of simple overlapping
changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_forward.c | 29 | ||||
-rw-r--r-- | net/bridge/br_mdb.c | 1 | ||||
-rw-r--r-- | net/bridge/br_multicast.c | 52 | ||||
-rw-r--r-- | net/bridge/br_netlink.c | 10 | ||||
-rw-r--r-- | net/bridge/br_stp.c | 5 | ||||
-rw-r--r-- | net/bridge/br_stp_if.c | 13 | ||||
-rw-r--r-- | net/bridge/br_stp_timer.c | 4 |
7 files changed, 77 insertions, 37 deletions
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 0ff6e1bbca91..fa7bfced888e 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
@@ -37,15 +37,30 @@ static inline int should_deliver(const struct net_bridge_port *p, | |||
37 | 37 | ||
38 | int br_dev_queue_push_xmit(struct sock *sk, struct sk_buff *skb) | 38 | int br_dev_queue_push_xmit(struct sock *sk, struct sk_buff *skb) |
39 | { | 39 | { |
40 | if (!is_skb_forwardable(skb->dev, skb)) { | 40 | if (!is_skb_forwardable(skb->dev, skb)) |
41 | kfree_skb(skb); | 41 | goto drop; |
42 | } else { | 42 | |
43 | skb_push(skb, ETH_HLEN); | 43 | skb_push(skb, ETH_HLEN); |
44 | br_drop_fake_rtable(skb); | 44 | br_drop_fake_rtable(skb); |
45 | skb_sender_cpu_clear(skb); | 45 | skb_sender_cpu_clear(skb); |
46 | dev_queue_xmit(skb); | 46 | |
47 | if (skb->ip_summed == CHECKSUM_PARTIAL && | ||
48 | (skb->protocol == htons(ETH_P_8021Q) || | ||
49 | skb->protocol == htons(ETH_P_8021AD))) { | ||
50 | int depth; | ||
51 | |||
52 | if (!__vlan_get_protocol(skb, skb->protocol, &depth)) | ||
53 | goto drop; | ||
54 | |||
55 | skb_set_network_header(skb, depth); | ||
47 | } | 56 | } |
48 | 57 | ||
58 | dev_queue_xmit(skb); | ||
59 | |||
60 | return 0; | ||
61 | |||
62 | drop: | ||
63 | kfree_skb(skb); | ||
49 | return 0; | 64 | return 0; |
50 | } | 65 | } |
51 | EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit); | 66 | EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit); |
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index 5e9d1c5e1194..6a592856da1c 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c | |||
@@ -519,6 +519,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) | |||
519 | if (p->port->state == BR_STATE_DISABLED) | 519 | if (p->port->state == BR_STATE_DISABLED) |
520 | goto unlock; | 520 | goto unlock; |
521 | 521 | ||
522 | entry->state = p->state; | ||
522 | rcu_assign_pointer(*pp, p->next); | 523 | rcu_assign_pointer(*pp, p->next); |
523 | hlist_del_init(&p->mglist); | 524 | hlist_del_init(&p->mglist); |
524 | del_timer(&p->timer); | 525 | del_timer(&p->timer); |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index fd238587e032..0752796fe0ba 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1432,8 +1432,7 @@ br_multicast_leave_group(struct net_bridge *br, | |||
1432 | 1432 | ||
1433 | spin_lock(&br->multicast_lock); | 1433 | spin_lock(&br->multicast_lock); |
1434 | if (!netif_running(br->dev) || | 1434 | if (!netif_running(br->dev) || |
1435 | (port && port->state == BR_STATE_DISABLED) || | 1435 | (port && port->state == BR_STATE_DISABLED)) |
1436 | timer_pending(&other_query->timer)) | ||
1437 | goto out; | 1436 | goto out; |
1438 | 1437 | ||
1439 | mdb = mlock_dereference(br->mdb, br); | 1438 | mdb = mlock_dereference(br->mdb, br); |
@@ -1441,6 +1440,32 @@ br_multicast_leave_group(struct net_bridge *br, | |||
1441 | if (!mp) | 1440 | if (!mp) |
1442 | goto out; | 1441 | goto out; |
1443 | 1442 | ||
1443 | if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) { | ||
1444 | struct net_bridge_port_group __rcu **pp; | ||
1445 | |||
1446 | for (pp = &mp->ports; | ||
1447 | (p = mlock_dereference(*pp, br)) != NULL; | ||
1448 | pp = &p->next) { | ||
1449 | if (p->port != port) | ||
1450 | continue; | ||
1451 | |||
1452 | rcu_assign_pointer(*pp, p->next); | ||
1453 | hlist_del_init(&p->mglist); | ||
1454 | del_timer(&p->timer); | ||
1455 | call_rcu_bh(&p->rcu, br_multicast_free_pg); | ||
1456 | br_mdb_notify(br->dev, port, group, RTM_DELMDB, | ||
1457 | p->state); | ||
1458 | |||
1459 | if (!mp->ports && !mp->mglist && | ||
1460 | netif_running(br->dev)) | ||
1461 | mod_timer(&mp->timer, jiffies); | ||
1462 | } | ||
1463 | goto out; | ||
1464 | } | ||
1465 | |||
1466 | if (timer_pending(&other_query->timer)) | ||
1467 | goto out; | ||
1468 | |||
1444 | if (br->multicast_querier) { | 1469 | if (br->multicast_querier) { |
1445 | __br_multicast_send_query(br, port, &mp->addr); | 1470 | __br_multicast_send_query(br, port, &mp->addr); |
1446 | 1471 | ||
@@ -1466,29 +1491,6 @@ br_multicast_leave_group(struct net_bridge *br, | |||
1466 | } | 1491 | } |
1467 | } | 1492 | } |
1468 | 1493 | ||
1469 | if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) { | ||
1470 | struct net_bridge_port_group __rcu **pp; | ||
1471 | |||
1472 | for (pp = &mp->ports; | ||
1473 | (p = mlock_dereference(*pp, br)) != NULL; | ||
1474 | pp = &p->next) { | ||
1475 | if (p->port != port) | ||
1476 | continue; | ||
1477 | |||
1478 | rcu_assign_pointer(*pp, p->next); | ||
1479 | hlist_del_init(&p->mglist); | ||
1480 | del_timer(&p->timer); | ||
1481 | br_mdb_notify(br->dev, port, group, RTM_DELMDB, | ||
1482 | p->state); | ||
1483 | call_rcu_bh(&p->rcu, br_multicast_free_pg); | ||
1484 | |||
1485 | if (!mp->ports && !mp->mglist && | ||
1486 | netif_running(br->dev)) | ||
1487 | mod_timer(&mp->timer, jiffies); | ||
1488 | } | ||
1489 | goto out; | ||
1490 | } | ||
1491 | |||
1492 | now = jiffies; | 1494 | now = jiffies; |
1493 | time = now + br->multicast_last_member_count * | 1495 | time = now + br->multicast_last_member_count * |
1494 | br->multicast_last_member_interval; | 1496 | br->multicast_last_member_interval; |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 793d247ac2ca..91a2e08c2bb8 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -691,9 +691,17 @@ static int br_port_slave_changelink(struct net_device *brdev, | |||
691 | struct nlattr *tb[], | 691 | struct nlattr *tb[], |
692 | struct nlattr *data[]) | 692 | struct nlattr *data[]) |
693 | { | 693 | { |
694 | struct net_bridge *br = netdev_priv(brdev); | ||
695 | int ret; | ||
696 | |||
694 | if (!data) | 697 | if (!data) |
695 | return 0; | 698 | return 0; |
696 | return br_setport(br_port_get_rtnl(dev), data); | 699 | |
700 | spin_lock_bh(&br->lock); | ||
701 | ret = br_setport(br_port_get_rtnl(dev), data); | ||
702 | spin_unlock_bh(&br->lock); | ||
703 | |||
704 | return ret; | ||
697 | } | 705 | } |
698 | 706 | ||
699 | static int br_port_fill_slave_info(struct sk_buff *skb, | 707 | static int br_port_fill_slave_info(struct sk_buff *skb, |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index b4b6dab9c285..ed74ffaa851f 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -209,8 +209,9 @@ void br_transmit_config(struct net_bridge_port *p) | |||
209 | br_send_config_bpdu(p, &bpdu); | 209 | br_send_config_bpdu(p, &bpdu); |
210 | p->topology_change_ack = 0; | 210 | p->topology_change_ack = 0; |
211 | p->config_pending = 0; | 211 | p->config_pending = 0; |
212 | mod_timer(&p->hold_timer, | 212 | if (p->br->stp_enabled == BR_KERNEL_STP) |
213 | round_jiffies(jiffies + BR_HOLD_TIME)); | 213 | mod_timer(&p->hold_timer, |
214 | round_jiffies(jiffies + BR_HOLD_TIME)); | ||
214 | } | 215 | } |
215 | } | 216 | } |
216 | 217 | ||
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index a2730e7196cd..4ca449a16132 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
@@ -48,7 +48,8 @@ void br_stp_enable_bridge(struct net_bridge *br) | |||
48 | struct net_bridge_port *p; | 48 | struct net_bridge_port *p; |
49 | 49 | ||
50 | spin_lock_bh(&br->lock); | 50 | spin_lock_bh(&br->lock); |
51 | mod_timer(&br->hello_timer, jiffies + br->hello_time); | 51 | if (br->stp_enabled == BR_KERNEL_STP) |
52 | mod_timer(&br->hello_timer, jiffies + br->hello_time); | ||
52 | mod_timer(&br->gc_timer, jiffies + HZ/10); | 53 | mod_timer(&br->gc_timer, jiffies + HZ/10); |
53 | 54 | ||
54 | br_config_bpdu_generation(br); | 55 | br_config_bpdu_generation(br); |
@@ -127,6 +128,7 @@ static void br_stp_start(struct net_bridge *br) | |||
127 | int r; | 128 | int r; |
128 | char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL }; | 129 | char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL }; |
129 | char *envp[] = { NULL }; | 130 | char *envp[] = { NULL }; |
131 | struct net_bridge_port *p; | ||
130 | 132 | ||
131 | r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); | 133 | r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); |
132 | 134 | ||
@@ -140,6 +142,10 @@ static void br_stp_start(struct net_bridge *br) | |||
140 | if (r == 0) { | 142 | if (r == 0) { |
141 | br->stp_enabled = BR_USER_STP; | 143 | br->stp_enabled = BR_USER_STP; |
142 | br_debug(br, "userspace STP started\n"); | 144 | br_debug(br, "userspace STP started\n"); |
145 | /* Stop hello and hold timers */ | ||
146 | del_timer(&br->hello_timer); | ||
147 | list_for_each_entry(p, &br->port_list, list) | ||
148 | del_timer(&p->hold_timer); | ||
143 | } else { | 149 | } else { |
144 | br->stp_enabled = BR_KERNEL_STP; | 150 | br->stp_enabled = BR_KERNEL_STP; |
145 | br_debug(br, "using kernel STP\n"); | 151 | br_debug(br, "using kernel STP\n"); |
@@ -156,12 +162,17 @@ static void br_stp_stop(struct net_bridge *br) | |||
156 | int r; | 162 | int r; |
157 | char *argv[] = { BR_STP_PROG, br->dev->name, "stop", NULL }; | 163 | char *argv[] = { BR_STP_PROG, br->dev->name, "stop", NULL }; |
158 | char *envp[] = { NULL }; | 164 | char *envp[] = { NULL }; |
165 | struct net_bridge_port *p; | ||
159 | 166 | ||
160 | if (br->stp_enabled == BR_USER_STP) { | 167 | if (br->stp_enabled == BR_USER_STP) { |
161 | r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); | 168 | r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); |
162 | br_info(br, "userspace STP stopped, return code %d\n", r); | 169 | br_info(br, "userspace STP stopped, return code %d\n", r); |
163 | 170 | ||
164 | /* To start timers on any ports left in blocking */ | 171 | /* To start timers on any ports left in blocking */ |
172 | mod_timer(&br->hello_timer, jiffies + br->hello_time); | ||
173 | list_for_each_entry(p, &br->port_list, list) | ||
174 | mod_timer(&p->hold_timer, | ||
175 | round_jiffies(jiffies + BR_HOLD_TIME)); | ||
165 | spin_lock_bh(&br->lock); | 176 | spin_lock_bh(&br->lock); |
166 | br_port_state_selection(br); | 177 | br_port_state_selection(br); |
167 | spin_unlock_bh(&br->lock); | 178 | spin_unlock_bh(&br->lock); |
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c index 7caf7fae2d5b..5f0f5af0ec35 100644 --- a/net/bridge/br_stp_timer.c +++ b/net/bridge/br_stp_timer.c | |||
@@ -40,7 +40,9 @@ static void br_hello_timer_expired(unsigned long arg) | |||
40 | if (br->dev->flags & IFF_UP) { | 40 | if (br->dev->flags & IFF_UP) { |
41 | br_config_bpdu_generation(br); | 41 | br_config_bpdu_generation(br); |
42 | 42 | ||
43 | mod_timer(&br->hello_timer, round_jiffies(jiffies + br->hello_time)); | 43 | if (br->stp_enabled != BR_USER_STP) |
44 | mod_timer(&br->hello_timer, | ||
45 | round_jiffies(jiffies + br->hello_time)); | ||
44 | } | 46 | } |
45 | spin_unlock(&br->lock); | 47 | spin_unlock(&br->lock); |
46 | } | 48 | } |