|
@@ -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
|
|
@@ -428,6 +430,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 +453,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 +601,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;
|
|
|
}
|
|
@@ -659,11 +667,6 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
|
|
|
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 +674,12 @@ static struct notifier_block notifier = {
|
|
|
|
|
|
int tipc_bearer_setup(void)
|
|
|
{
|
|
|
- int err;
|
|
|
-
|
|
|
- err = register_netdevice_notifier(¬ifier);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
- dev_add_pack(&tipc_packet_type);
|
|
|
- return 0;
|
|
|
+ return register_netdevice_notifier(¬ifier);
|
|
|
}
|
|
|
|
|
|
void tipc_bearer_cleanup(void)
|
|
|
{
|
|
|
unregister_netdevice_notifier(¬ifier);
|
|
|
- dev_remove_pack(&tipc_packet_type);
|
|
|
}
|
|
|
|
|
|
void tipc_bearer_stop(struct net *net)
|