aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bearer.c26
-rw-r--r--net/tipc/bearer.h2
-rw-r--r--net/tipc/msg.c7
-rw-r--r--net/tipc/node.c4
-rw-r--r--net/tipc/socket.c6
-rw-r--r--net/tipc/subscr.c21
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
67static void bearer_disable(struct net *net, struct tipc_bearer *b); 67static void bearer_disable(struct net *net, struct tipc_bearer *b);
68static 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
662static struct packet_type tipc_packet_type __read_mostly = {
663 .type = htons(ETH_P_TIPC),
664 .func = tipc_l2_rcv_msg,
665};
666
667static struct notifier_block notifier = { 670static 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
672int tipc_bearer_setup(void) 675int tipc_bearer_setup(void)
673{ 676{
674 int err; 677 return register_netdevice_notifier(&notifier);
675
676 err = register_netdevice_notifier(&notifier);
677 if (err)
678 return err;
679 dev_add_pack(&tipc_packet_type);
680 return 0;
681} 678}
682 679
683void tipc_bearer_cleanup(void) 680void tipc_bearer_cleanup(void)
684{ 681{
685 unregister_netdevice_notifier(&notifier); 682 unregister_netdevice_notifier(&notifier);
686 dev_remove_pack(&tipc_packet_type);
687} 683}
688 684
689void tipc_bearer_stop(struct net *net) 685void 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,
479bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) 479bool 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 }
1129exit:
1130 tipc_node_read_unlock(node); 1129 tipc_node_read_unlock(node);
1130exit:
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 2268walk_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
55static void tipc_subscrp_delete(struct tipc_subscription *sub);
56static void tipc_subscrb_put(struct tipc_subscriber *subscriber); 55static 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
239static 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
247static void tipc_subscrp_cancel(struct tipc_subscr *s, 242static 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
253static struct tipc_subscription *tipc_subscrp_create(struct net *net, 250static struct tipc_subscription *tipc_subscrp_create(struct net *net,