diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bearer.c | 26 | ||||
-rw-r--r-- | net/tipc/bearer.h | 2 | ||||
-rw-r--r-- | net/tipc/msg.c | 7 | ||||
-rw-r--r-- | net/tipc/node.c | 4 | ||||
-rw-r--r-- | net/tipc/socket.c | 6 | ||||
-rw-r--r-- | net/tipc/subscr.c | 21 |
6 files changed, 33 insertions, 33 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 767e0537dde5..89cd061c4468 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -65,6 +65,8 @@ static struct tipc_bearer *bearer_get(struct net *net, int bearer_id) | |||
65 | } | 65 | } |
66 | 66 | ||
67 | static void bearer_disable(struct net *net, struct tipc_bearer *b); | 67 | static void bearer_disable(struct net *net, struct tipc_bearer *b); |
68 | static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev, | ||
69 | struct packet_type *pt, struct net_device *orig_dev); | ||
68 | 70 | ||
69 | /** | 71 | /** |
70 | * tipc_media_find - locates specified media object by name | 72 | * tipc_media_find - locates specified media object by name |
@@ -428,6 +430,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, | |||
428 | 430 | ||
429 | /* Associate TIPC bearer with L2 bearer */ | 431 | /* Associate TIPC bearer with L2 bearer */ |
430 | rcu_assign_pointer(b->media_ptr, dev); | 432 | rcu_assign_pointer(b->media_ptr, dev); |
433 | b->pt.dev = dev; | ||
434 | b->pt.type = htons(ETH_P_TIPC); | ||
435 | b->pt.func = tipc_l2_rcv_msg; | ||
436 | dev_add_pack(&b->pt); | ||
431 | memset(&b->bcast_addr, 0, sizeof(b->bcast_addr)); | 437 | memset(&b->bcast_addr, 0, sizeof(b->bcast_addr)); |
432 | memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len); | 438 | memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len); |
433 | b->bcast_addr.media_id = b->media->type_id; | 439 | b->bcast_addr.media_id = b->media->type_id; |
@@ -447,6 +453,7 @@ void tipc_disable_l2_media(struct tipc_bearer *b) | |||
447 | struct net_device *dev; | 453 | struct net_device *dev; |
448 | 454 | ||
449 | dev = (struct net_device *)rtnl_dereference(b->media_ptr); | 455 | dev = (struct net_device *)rtnl_dereference(b->media_ptr); |
456 | dev_remove_pack(&b->pt); | ||
450 | RCU_INIT_POINTER(dev->tipc_ptr, NULL); | 457 | RCU_INIT_POINTER(dev->tipc_ptr, NULL); |
451 | synchronize_net(); | 458 | synchronize_net(); |
452 | dev_put(dev); | 459 | dev_put(dev); |
@@ -594,11 +601,12 @@ static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev, | |||
594 | struct tipc_bearer *b; | 601 | struct tipc_bearer *b; |
595 | 602 | ||
596 | rcu_read_lock(); | 603 | rcu_read_lock(); |
597 | b = rcu_dereference_rtnl(dev->tipc_ptr); | 604 | b = rcu_dereference_rtnl(dev->tipc_ptr) ?: |
605 | rcu_dereference_rtnl(orig_dev->tipc_ptr); | ||
598 | if (likely(b && test_bit(0, &b->up) && | 606 | if (likely(b && test_bit(0, &b->up) && |
599 | (skb->pkt_type <= PACKET_MULTICAST))) { | 607 | (skb->pkt_type <= PACKET_MULTICAST))) { |
600 | skb->next = NULL; | 608 | skb->next = NULL; |
601 | tipc_rcv(dev_net(dev), skb, b); | 609 | tipc_rcv(dev_net(b->pt.dev), skb, b); |
602 | rcu_read_unlock(); | 610 | rcu_read_unlock(); |
603 | return NET_RX_SUCCESS; | 611 | return NET_RX_SUCCESS; |
604 | } | 612 | } |
@@ -659,11 +667,6 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt, | |||
659 | return NOTIFY_OK; | 667 | return NOTIFY_OK; |
660 | } | 668 | } |
661 | 669 | ||
662 | static struct packet_type tipc_packet_type __read_mostly = { | ||
663 | .type = htons(ETH_P_TIPC), | ||
664 | .func = tipc_l2_rcv_msg, | ||
665 | }; | ||
666 | |||
667 | static struct notifier_block notifier = { | 670 | static struct notifier_block notifier = { |
668 | .notifier_call = tipc_l2_device_event, | 671 | .notifier_call = tipc_l2_device_event, |
669 | .priority = 0, | 672 | .priority = 0, |
@@ -671,19 +674,12 @@ static struct notifier_block notifier = { | |||
671 | 674 | ||
672 | int tipc_bearer_setup(void) | 675 | int tipc_bearer_setup(void) |
673 | { | 676 | { |
674 | int err; | 677 | return register_netdevice_notifier(¬ifier); |
675 | |||
676 | err = register_netdevice_notifier(¬ifier); | ||
677 | if (err) | ||
678 | return err; | ||
679 | dev_add_pack(&tipc_packet_type); | ||
680 | return 0; | ||
681 | } | 678 | } |
682 | 679 | ||
683 | void tipc_bearer_cleanup(void) | 680 | void tipc_bearer_cleanup(void) |
684 | { | 681 | { |
685 | unregister_netdevice_notifier(¬ifier); | 682 | unregister_netdevice_notifier(¬ifier); |
686 | dev_remove_pack(&tipc_packet_type); | ||
687 | } | 683 | } |
688 | 684 | ||
689 | void tipc_bearer_stop(struct net *net) | 685 | void tipc_bearer_stop(struct net *net) |
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 635c9086e19a..e07a55a80c18 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h | |||
@@ -131,6 +131,7 @@ struct tipc_media { | |||
131 | * @name: bearer name (format = media:interface) | 131 | * @name: bearer name (format = media:interface) |
132 | * @media: ptr to media structure associated with bearer | 132 | * @media: ptr to media structure associated with bearer |
133 | * @bcast_addr: media address used in broadcasting | 133 | * @bcast_addr: media address used in broadcasting |
134 | * @pt: packet type for bearer | ||
134 | * @rcu: rcu struct for tipc_bearer | 135 | * @rcu: rcu struct for tipc_bearer |
135 | * @priority: default link priority for bearer | 136 | * @priority: default link priority for bearer |
136 | * @window: default window size for bearer | 137 | * @window: default window size for bearer |
@@ -151,6 +152,7 @@ struct tipc_bearer { | |||
151 | char name[TIPC_MAX_BEARER_NAME]; | 152 | char name[TIPC_MAX_BEARER_NAME]; |
152 | struct tipc_media *media; | 153 | struct tipc_media *media; |
153 | struct tipc_media_addr bcast_addr; | 154 | struct tipc_media_addr bcast_addr; |
155 | struct packet_type pt; | ||
154 | struct rcu_head rcu; | 156 | struct rcu_head rcu; |
155 | u32 priority; | 157 | u32 priority; |
156 | u32 window; | 158 | u32 window; |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index dcd90e6fa7c3..6ef379f004ac 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -479,13 +479,14 @@ bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg, | |||
479 | bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) | 479 | bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) |
480 | { | 480 | { |
481 | struct sk_buff *_skb = *skb; | 481 | struct sk_buff *_skb = *skb; |
482 | struct tipc_msg *hdr = buf_msg(_skb); | 482 | struct tipc_msg *hdr; |
483 | struct tipc_msg ohdr; | 483 | struct tipc_msg ohdr; |
484 | int dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE); | 484 | int dlen; |
485 | 485 | ||
486 | if (skb_linearize(_skb)) | 486 | if (skb_linearize(_skb)) |
487 | goto exit; | 487 | goto exit; |
488 | hdr = buf_msg(_skb); | 488 | hdr = buf_msg(_skb); |
489 | dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE); | ||
489 | if (msg_dest_droppable(hdr)) | 490 | if (msg_dest_droppable(hdr)) |
490 | goto exit; | 491 | goto exit; |
491 | if (msg_errcode(hdr)) | 492 | if (msg_errcode(hdr)) |
@@ -511,6 +512,8 @@ bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) | |||
511 | pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC)) | 512 | pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC)) |
512 | goto exit; | 513 | goto exit; |
513 | 514 | ||
515 | /* reassign after skb header modifications */ | ||
516 | hdr = buf_msg(_skb); | ||
514 | /* Now reverse the concerned fields */ | 517 | /* Now reverse the concerned fields */ |
515 | msg_set_errcode(hdr, err); | 518 | msg_set_errcode(hdr, err); |
516 | msg_set_non_seq(hdr, 0); | 519 | msg_set_non_seq(hdr, 0); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index 9b4dcb6a16b5..7dd22330a6b4 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -1126,8 +1126,8 @@ int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr, | |||
1126 | strncpy(linkname, tipc_link_name(link), len); | 1126 | strncpy(linkname, tipc_link_name(link), len); |
1127 | err = 0; | 1127 | err = 0; |
1128 | } | 1128 | } |
1129 | exit: | ||
1130 | tipc_node_read_unlock(node); | 1129 | tipc_node_read_unlock(node); |
1130 | exit: | ||
1131 | tipc_node_put(node); | 1131 | tipc_node_put(node); |
1132 | return err; | 1132 | return err; |
1133 | } | 1133 | } |
@@ -1557,6 +1557,8 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
1557 | 1557 | ||
1558 | /* Check/update node state before receiving */ | 1558 | /* Check/update node state before receiving */ |
1559 | if (unlikely(skb)) { | 1559 | if (unlikely(skb)) { |
1560 | if (unlikely(skb_linearize(skb))) | ||
1561 | goto discard; | ||
1560 | tipc_node_write_lock(n); | 1562 | tipc_node_write_lock(n); |
1561 | if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { | 1563 | if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { |
1562 | if (le->link) { | 1564 | if (le->link) { |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 101e3597338f..d50edd6e0019 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2255,8 +2255,8 @@ void tipc_sk_reinit(struct net *net) | |||
2255 | 2255 | ||
2256 | do { | 2256 | do { |
2257 | tsk = ERR_PTR(rhashtable_walk_start(&iter)); | 2257 | tsk = ERR_PTR(rhashtable_walk_start(&iter)); |
2258 | if (tsk) | 2258 | if (IS_ERR(tsk)) |
2259 | continue; | 2259 | goto walk_stop; |
2260 | 2260 | ||
2261 | while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { | 2261 | while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { |
2262 | spin_lock_bh(&tsk->sk.sk_lock.slock); | 2262 | spin_lock_bh(&tsk->sk.sk_lock.slock); |
@@ -2265,7 +2265,7 @@ void tipc_sk_reinit(struct net *net) | |||
2265 | msg_set_orignode(msg, tn->own_addr); | 2265 | msg_set_orignode(msg, tn->own_addr); |
2266 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | 2266 | spin_unlock_bh(&tsk->sk.sk_lock.slock); |
2267 | } | 2267 | } |
2268 | 2268 | walk_stop: | |
2269 | rhashtable_walk_stop(&iter); | 2269 | rhashtable_walk_stop(&iter); |
2270 | } while (tsk == ERR_PTR(-EAGAIN)); | 2270 | } while (tsk == ERR_PTR(-EAGAIN)); |
2271 | } | 2271 | } |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 0bf91cd3733c..be3d9e3183dc 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -52,7 +52,6 @@ struct tipc_subscriber { | |||
52 | struct list_head subscrp_list; | 52 | struct list_head subscrp_list; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static void tipc_subscrp_delete(struct tipc_subscription *sub); | ||
56 | static void tipc_subscrb_put(struct tipc_subscriber *subscriber); | 55 | static void tipc_subscrb_put(struct tipc_subscriber *subscriber); |
57 | 56 | ||
58 | /** | 57 | /** |
@@ -197,15 +196,19 @@ static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber, | |||
197 | { | 196 | { |
198 | struct list_head *subscription_list = &subscriber->subscrp_list; | 197 | struct list_head *subscription_list = &subscriber->subscrp_list; |
199 | struct tipc_subscription *sub, *temp; | 198 | struct tipc_subscription *sub, *temp; |
199 | u32 timeout; | ||
200 | 200 | ||
201 | spin_lock_bh(&subscriber->lock); | 201 | spin_lock_bh(&subscriber->lock); |
202 | list_for_each_entry_safe(sub, temp, subscription_list, subscrp_list) { | 202 | list_for_each_entry_safe(sub, temp, subscription_list, subscrp_list) { |
203 | if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) | 203 | if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) |
204 | continue; | 204 | continue; |
205 | 205 | ||
206 | tipc_nametbl_unsubscribe(sub); | 206 | timeout = htohl(sub->evt.s.timeout, sub->swap); |
207 | list_del(&sub->subscrp_list); | 207 | if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer)) { |
208 | tipc_subscrp_delete(sub); | 208 | tipc_nametbl_unsubscribe(sub); |
209 | list_del(&sub->subscrp_list); | ||
210 | tipc_subscrp_put(sub); | ||
211 | } | ||
209 | 212 | ||
210 | if (s) | 213 | if (s) |
211 | break; | 214 | break; |
@@ -236,18 +239,12 @@ static void tipc_subscrb_delete(struct tipc_subscriber *subscriber) | |||
236 | tipc_subscrb_put(subscriber); | 239 | tipc_subscrb_put(subscriber); |
237 | } | 240 | } |
238 | 241 | ||
239 | static void tipc_subscrp_delete(struct tipc_subscription *sub) | ||
240 | { | ||
241 | u32 timeout = htohl(sub->evt.s.timeout, sub->swap); | ||
242 | |||
243 | if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer)) | ||
244 | tipc_subscrp_put(sub); | ||
245 | } | ||
246 | |||
247 | static void tipc_subscrp_cancel(struct tipc_subscr *s, | 242 | static void tipc_subscrp_cancel(struct tipc_subscr *s, |
248 | struct tipc_subscriber *subscriber) | 243 | struct tipc_subscriber *subscriber) |
249 | { | 244 | { |
245 | tipc_subscrb_get(subscriber); | ||
250 | tipc_subscrb_subscrp_delete(subscriber, s); | 246 | tipc_subscrb_subscrp_delete(subscriber, s); |
247 | tipc_subscrb_put(subscriber); | ||
251 | } | 248 | } |
252 | 249 | ||
253 | static struct tipc_subscription *tipc_subscrp_create(struct net *net, | 250 | static struct tipc_subscription *tipc_subscrp_create(struct net *net, |