aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorParthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>2017-08-28 11:57:02 -0400
committerDavid S. Miller <davem@davemloft.net>2017-08-29 18:07:33 -0400
commitd55c60eba0ef44ec21831ce26db300763eafd865 (patch)
tree004c053b1510454aa4629f4bc230c64799dd377b /net/tipc
parente8d411d2980723b8f8ba8e4dd78b694c5fd9ea3e (diff)
tipc: permit bond slave as bearer
For a bond slave device as a tipc bearer, the dev represents the bond interface and orig_dev represents the slave in tipc_l2_rcv_msg(). Since we decode the tipc_ptr from bonding device (dev), we fail to find the bearer and thus tipc links are not established. In this commit, we register the tipc protocol callback per device and look for tipc bearer from both the devices. Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bearer.c26
-rw-r--r--net/tipc/bearer.h2
2 files changed, 13 insertions, 15 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;