Merge branch 'for-4.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj...
[sfrench/cifs-2.6.git] / net / tipc / bearer.c
index 767e0537dde5a8d0cfac97f6b11ee1d568ef87ed..47ec121574ce4ef95850f688d85b50eff766a710 100644 (file)
@@ -65,6 +65,8 @@ static struct tipc_bearer *bearer_get(struct net *net, int bearer_id)
 }
 
 static void bearer_disable(struct net *net, struct tipc_bearer *b);
+static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
+                          struct packet_type *pt, struct net_device *orig_dev);
 
 /**
  * tipc_media_find - locates specified media object by name
@@ -365,30 +367,6 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b)
        return 0;
 }
 
-/* tipc_bearer_reset_all - reset all links on all bearers
- */
-void tipc_bearer_reset_all(struct net *net)
-{
-       struct tipc_bearer *b;
-       int i;
-
-       for (i = 0; i < MAX_BEARERS; i++) {
-               b = bearer_get(net, i);
-               if (b)
-                       clear_bit_unlock(0, &b->up);
-       }
-       for (i = 0; i < MAX_BEARERS; i++) {
-               b = bearer_get(net, i);
-               if (b)
-                       tipc_reset_bearer(net, b);
-       }
-       for (i = 0; i < MAX_BEARERS; i++) {
-               b = bearer_get(net, i);
-               if (b)
-                       test_and_set_bit_lock(0, &b->up);
-       }
-}
-
 /**
  * bearer_disable
  *
@@ -428,6 +406,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
 
        /* Associate TIPC bearer with L2 bearer */
        rcu_assign_pointer(b->media_ptr, dev);
+       b->pt.dev = dev;
+       b->pt.type = htons(ETH_P_TIPC);
+       b->pt.func = tipc_l2_rcv_msg;
+       dev_add_pack(&b->pt);
        memset(&b->bcast_addr, 0, sizeof(b->bcast_addr));
        memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len);
        b->bcast_addr.media_id = b->media->type_id;
@@ -447,6 +429,7 @@ void tipc_disable_l2_media(struct tipc_bearer *b)
        struct net_device *dev;
 
        dev = (struct net_device *)rtnl_dereference(b->media_ptr);
+       dev_remove_pack(&b->pt);
        RCU_INIT_POINTER(dev->tipc_ptr, NULL);
        synchronize_net();
        dev_put(dev);
@@ -594,11 +577,12 @@ static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
        struct tipc_bearer *b;
 
        rcu_read_lock();
-       b = rcu_dereference_rtnl(dev->tipc_ptr);
+       b = rcu_dereference_rtnl(dev->tipc_ptr) ?:
+               rcu_dereference_rtnl(orig_dev->tipc_ptr);
        if (likely(b && test_bit(0, &b->up) &&
                   (skb->pkt_type <= PACKET_MULTICAST))) {
                skb->next = NULL;
-               tipc_rcv(dev_net(dev), skb, b);
+               tipc_rcv(dev_net(b->pt.dev), skb, b);
                rcu_read_unlock();
                return NET_RX_SUCCESS;
        }
@@ -653,17 +637,12 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
                break;
        case NETDEV_UNREGISTER:
        case NETDEV_CHANGENAME:
-               bearer_disable(dev_net(dev), b);
+               bearer_disable(net, b);
                break;
        }
        return NOTIFY_OK;
 }
 
-static struct packet_type tipc_packet_type __read_mostly = {
-       .type = htons(ETH_P_TIPC),
-       .func = tipc_l2_rcv_msg,
-};
-
 static struct notifier_block notifier = {
        .notifier_call  = tipc_l2_device_event,
        .priority       = 0,
@@ -671,19 +650,12 @@ static struct notifier_block notifier = {
 
 int tipc_bearer_setup(void)
 {
-       int err;
-
-       err = register_netdevice_notifier(&notifier);
-       if (err)
-               return err;
-       dev_add_pack(&tipc_packet_type);
-       return 0;
+       return register_netdevice_notifier(&notifier);
 }
 
 void tipc_bearer_cleanup(void)
 {
        unregister_netdevice_notifier(&notifier);
-       dev_remove_pack(&tipc_packet_type);
 }
 
 void tipc_bearer_stop(struct net *net)