aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bearer.c105
-rw-r--r--net/tipc/bearer.h11
-rw-r--r--net/tipc/core.c8
-rw-r--r--net/tipc/eth_media.c199
-rw-r--r--net/tipc/ib_media.c192
5 files changed, 114 insertions, 401 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 2411bac2b8f9..e95e0b91ef30 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -367,7 +367,7 @@ exit:
367/** 367/**
368 * tipc_reset_bearer - Reset all links established over this bearer 368 * tipc_reset_bearer - Reset all links established over this bearer
369 */ 369 */
370int tipc_reset_bearer(struct tipc_bearer *b_ptr) 370static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
371{ 371{
372 struct tipc_link *l_ptr; 372 struct tipc_link *l_ptr;
373 struct tipc_link *temp_l_ptr; 373 struct tipc_link *temp_l_ptr;
@@ -432,7 +432,110 @@ int tipc_disable_bearer(const char *name)
432 return res; 432 return res;
433} 433}
434 434
435/**
436 * tipc_l2_rcv_msg - handle incoming TIPC message from an interface
437 * @buf: the received packet
438 * @dev: the net device that the packet was received on
439 * @pt: the packet_type structure which was used to register this handler
440 * @orig_dev: the original receive net device in case the device is a bond
441 *
442 * Accept only packets explicitly sent to this node, or broadcast packets;
443 * ignores packets sent using interface multicast, and traffic sent to other
444 * nodes (which can happen if interface is running in promiscuous mode).
445 */
446static int tipc_l2_rcv_msg(struct sk_buff *buf, struct net_device *dev,
447 struct packet_type *pt, struct net_device *orig_dev)
448{
449 struct tipc_bearer *b_ptr;
450
451 if (!net_eq(dev_net(dev), &init_net)) {
452 kfree_skb(buf);
453 return NET_RX_DROP;
454 }
455
456 rcu_read_lock();
457 b_ptr = rcu_dereference(dev->tipc_ptr);
458 if (likely(b_ptr)) {
459 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
460 buf->next = NULL;
461 tipc_recv_msg(buf, b_ptr);
462 rcu_read_unlock();
463 return NET_RX_SUCCESS;
464 }
465 }
466 rcu_read_unlock();
467
468 kfree_skb(buf);
469 return NET_RX_DROP;
470}
471
472/**
473 * tipc_l2_device_event - handle device events from network device
474 * @nb: the context of the notification
475 * @evt: the type of event
476 * @ptr: the net device that the event was on
477 *
478 * This function is called by the Ethernet driver in case of link
479 * change event.
480 */
481static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
482 void *ptr)
483{
484 struct tipc_bearer *b_ptr;
485 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
435 486
487 if (!net_eq(dev_net(dev), &init_net))
488 return NOTIFY_DONE;
489
490 rcu_read_lock();
491 b_ptr = rcu_dereference(dev->tipc_ptr);
492 if (!b_ptr) {
493 rcu_read_unlock();
494 return NOTIFY_DONE;
495 }
496
497 b_ptr->mtu = dev->mtu;
498
499 switch (evt) {
500 case NETDEV_CHANGE:
501 if (netif_carrier_ok(dev))
502 break;
503 case NETDEV_DOWN:
504 case NETDEV_CHANGEMTU:
505 case NETDEV_CHANGEADDR:
506 tipc_reset_bearer(b_ptr);
507 break;
508 case NETDEV_UNREGISTER:
509 case NETDEV_CHANGENAME:
510 tipc_disable_bearer(b_ptr->name);
511 break;
512 }
513 rcu_read_unlock();
514
515 return NOTIFY_OK;
516}
517
518static struct packet_type tipc_packet_type __read_mostly = {
519 .type = __constant_htons(ETH_P_TIPC),
520 .func = tipc_l2_rcv_msg,
521};
522
523static struct notifier_block notifier = {
524 .notifier_call = tipc_l2_device_event,
525 .priority = 0,
526};
527
528int tipc_bearer_setup(void)
529{
530 dev_add_pack(&tipc_packet_type);
531 return register_netdevice_notifier(&notifier);
532}
533
534void tipc_bearer_cleanup(void)
535{
536 unregister_netdevice_notifier(&notifier);
537 dev_remove_pack(&tipc_packet_type);
538}
436 539
437void tipc_bearer_stop(void) 540void tipc_bearer_stop(void)
438{ 541{
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 91b8d8b92373..0974c2f2bbe5 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -162,25 +162,16 @@ extern struct tipc_bearer tipc_bearers[];
162 162
163void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr); 163void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
164 164
165int tipc_reset_bearer(struct tipc_bearer *b_ptr);
166
167int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority); 165int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
168int tipc_disable_bearer(const char *name); 166int tipc_disable_bearer(const char *name);
169 167
170/* 168/*
171 * Routines made available to TIPC by supported media types 169 * Routines made available to TIPC by supported media types
172 */ 170 */
173int tipc_eth_media_start(void);
174void tipc_eth_media_stop(void);
175extern struct tipc_media eth_media_info; 171extern struct tipc_media eth_media_info;
176 172
177#ifdef CONFIG_TIPC_MEDIA_IB 173#ifdef CONFIG_TIPC_MEDIA_IB
178int tipc_ib_media_start(void);
179void tipc_ib_media_stop(void);
180extern struct tipc_media ib_media_info; 174extern struct tipc_media ib_media_info;
181#else
182static inline int tipc_ib_media_start(void) { return 0; }
183static inline void tipc_ib_media_stop(void) { return; }
184#endif 175#endif
185 176
186int tipc_media_set_priority(const char *name, u32 new_value); 177int tipc_media_set_priority(const char *name, u32 new_value);
@@ -194,6 +185,8 @@ void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest);
194struct tipc_bearer *tipc_bearer_find(const char *name); 185struct tipc_bearer *tipc_bearer_find(const char *name);
195struct tipc_bearer *tipc_bearer_find_interface(const char *if_name); 186struct tipc_bearer *tipc_bearer_find_interface(const char *if_name);
196struct tipc_media *tipc_media_find(const char *name); 187struct tipc_media *tipc_media_find(const char *name);
188int tipc_bearer_setup(void);
189void tipc_bearer_cleanup(void);
197void tipc_bearer_stop(void); 190void tipc_bearer_stop(void);
198 191
199/** 192/**
diff --git a/net/tipc/core.c b/net/tipc/core.c
index fd4eeeaa972a..68977c423022 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -82,8 +82,7 @@ struct sk_buff *tipc_buf_acquire(u32 size)
82static void tipc_core_stop_net(void) 82static void tipc_core_stop_net(void)
83{ 83{
84 tipc_net_stop(); 84 tipc_net_stop();
85 tipc_eth_media_stop(); 85 tipc_bearer_cleanup();
86 tipc_ib_media_stop();
87} 86}
88 87
89/** 88/**
@@ -94,10 +93,7 @@ int tipc_core_start_net(unsigned long addr)
94 int res; 93 int res;
95 94
96 tipc_net_start(addr); 95 tipc_net_start(addr);
97 res = tipc_eth_media_start(); 96 res = tipc_bearer_setup();
98 if (res < 0)
99 goto err;
100 res = tipc_ib_media_start();
101 if (res < 0) 97 if (res < 0)
102 goto err; 98 goto err;
103 return res; 99 return res;
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index c5f685dee15b..f28f7160adba 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -37,49 +37,9 @@
37#include "core.h" 37#include "core.h"
38#include "bearer.h" 38#include "bearer.h"
39 39
40#define MAX_ETH_MEDIA MAX_BEARERS
41
42#define ETH_ADDR_OFFSET 4 /* message header offset of MAC address */ 40#define ETH_ADDR_OFFSET 4 /* message header offset of MAC address */
43 41
44/** 42/**
45 * struct eth_media - Ethernet bearer data structure
46 * @bearer: ptr to associated "generic" bearer structure
47 * @dev: ptr to associated Ethernet network device
48 * @tipc_packet_type: used in binding TIPC to Ethernet driver
49 * @setup: work item used when enabling bearer
50 * @cleanup: work item used when disabling bearer
51 */
52struct eth_media {
53 struct tipc_bearer *bearer;
54 struct net_device *dev;
55 struct packet_type tipc_packet_type;
56 struct work_struct setup;
57 struct work_struct cleanup;
58};
59
60
61static struct eth_media eth_media_array[MAX_ETH_MEDIA];
62static int eth_started;
63
64static int recv_notification(struct notifier_block *nb, unsigned long evt,
65 void *dv);
66static int recv_msg(struct sk_buff *buf, struct net_device *dev,
67 struct packet_type *pt, struct net_device *orig_dev);
68
69/*
70 * Network device notifier info
71 */
72static struct notifier_block notifier = {
73 .notifier_call = recv_notification,
74 .priority = 0
75};
76
77static struct packet_type tipc_packet_type __read_mostly = {
78 .type = __constant_htons(ETH_P_TIPC),
79 .func = recv_msg,
80};
81
82/**
83 * eth_media_addr_set - initialize Ethernet media address structure 43 * eth_media_addr_set - initialize Ethernet media address structure
84 * 44 *
85 * Media-dependent "value" field stores MAC address in first 6 bytes 45 * Media-dependent "value" field stores MAC address in first 6 bytes
@@ -101,16 +61,14 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
101 struct tipc_media_addr *dest) 61 struct tipc_media_addr *dest)
102{ 62{
103 struct sk_buff *clone; 63 struct sk_buff *clone;
104 struct net_device *dev;
105 int delta; 64 int delta;
65 struct net_device *dev = tb_ptr->dev;
106 66
107 clone = skb_clone(buf, GFP_ATOMIC); 67 clone = skb_clone(buf, GFP_ATOMIC);
108 if (!clone) 68 if (!clone)
109 return 0; 69 return 0;
110 70
111 dev = ((struct eth_media *)(tb_ptr->usr_handle))->dev;
112 delta = dev->hard_header_len - skb_headroom(buf); 71 delta = dev->hard_header_len - skb_headroom(buf);
113
114 if ((delta > 0) && 72 if ((delta > 0) &&
115 pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { 73 pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
116 kfree_skb(clone); 74 kfree_skb(clone);
@@ -127,79 +85,21 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
127} 85}
128 86
129/** 87/**
130 * recv_msg - handle incoming TIPC message from an Ethernet interface
131 *
132 * Accept only packets explicitly sent to this node, or broadcast packets;
133 * ignores packets sent using Ethernet multicast, and traffic sent to other
134 * nodes (which can happen if interface is running in promiscuous mode).
135 */
136static int recv_msg(struct sk_buff *buf, struct net_device *dev,
137 struct packet_type *pt, struct net_device *orig_dev)
138{
139 struct tipc_bearer *b_ptr;
140
141 if (!net_eq(dev_net(dev), &init_net)) {
142 kfree_skb(buf);
143 return NET_RX_DROP;
144 }
145
146 rcu_read_lock();
147 b_ptr = rcu_dereference(dev->tipc_ptr);
148 if (likely(b_ptr)) {
149 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
150 buf->next = NULL;
151 tipc_recv_msg(buf, b_ptr);
152 rcu_read_unlock();
153 return NET_RX_SUCCESS;
154 }
155 }
156 rcu_read_unlock();
157
158 kfree_skb(buf);
159 return NET_RX_DROP;
160}
161
162/**
163 * setup_media - setup association between Ethernet bearer and interface
164 */
165static void setup_media(struct work_struct *work)
166{
167 dev_add_pack(&tipc_packet_type);
168}
169
170/**
171 * enable_media - attach TIPC bearer to an Ethernet interface 88 * enable_media - attach TIPC bearer to an Ethernet interface
172 */ 89 */
173static int enable_media(struct tipc_bearer *tb_ptr) 90static int enable_media(struct tipc_bearer *tb_ptr)
174{ 91{
175 struct net_device *dev; 92 struct net_device *dev;
176 struct eth_media *eb_ptr = &eth_media_array[0];
177 struct eth_media *stop = &eth_media_array[MAX_ETH_MEDIA];
178 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; 93 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
179 int pending_dev = 0;
180
181 /* Find unused Ethernet bearer structure */
182 while (eb_ptr->dev) {
183 if (!eb_ptr->bearer)
184 pending_dev++;
185 if (++eb_ptr == stop)
186 return pending_dev ? -EAGAIN : -EDQUOT;
187 }
188 94
189 /* Find device with specified name */ 95 /* Find device with specified name */
190 dev = dev_get_by_name(&init_net, driver_name); 96 dev = dev_get_by_name(&init_net, driver_name);
191 if (!dev) 97 if (!dev)
192 return -ENODEV; 98 return -ENODEV;
193 99
194 /* Create Ethernet bearer for device */
195 eb_ptr->dev = dev;
196 INIT_WORK(&eb_ptr->setup, setup_media);
197 schedule_work(&eb_ptr->setup);
198
199 /* Associate TIPC bearer with Ethernet bearer */ 100 /* Associate TIPC bearer with Ethernet bearer */
200 tb_ptr->dev = dev; 101 tb_ptr->dev = dev;
201 eb_ptr->bearer = tb_ptr; 102 tb_ptr->usr_handle = NULL;
202 tb_ptr->usr_handle = (void *)eb_ptr;
203 memset(tb_ptr->bcast_addr.value, 0, sizeof(tb_ptr->bcast_addr.value)); 103 memset(tb_ptr->bcast_addr.value, 0, sizeof(tb_ptr->bcast_addr.value));
204 memcpy(tb_ptr->bcast_addr.value, dev->broadcast, ETH_ALEN); 104 memcpy(tb_ptr->bcast_addr.value, dev->broadcast, ETH_ALEN);
205 tb_ptr->bcast_addr.media_id = TIPC_MEDIA_TYPE_ETH; 105 tb_ptr->bcast_addr.media_id = TIPC_MEDIA_TYPE_ETH;
@@ -211,21 +111,6 @@ static int enable_media(struct tipc_bearer *tb_ptr)
211} 111}
212 112
213/** 113/**
214 * cleanup_media - break association between Ethernet bearer and interface
215 *
216 * This routine must be invoked from a work queue because it can sleep.
217 */
218static void cleanup_media(struct work_struct *work)
219{
220 struct eth_media *eb_ptr =
221 container_of(work, struct eth_media, cleanup);
222
223 dev_remove_pack(&tipc_packet_type);
224 dev_put(eb_ptr->dev);
225 eb_ptr->dev = NULL;
226}
227
228/**
229 * disable_media - detach TIPC bearer from an Ethernet interface 114 * disable_media - detach TIPC bearer from an Ethernet interface
230 * 115 *
231 * Mark Ethernet bearer as inactive so that incoming buffers are thrown away, 116 * Mark Ethernet bearer as inactive so that incoming buffers are thrown away,
@@ -234,55 +119,8 @@ static void cleanup_media(struct work_struct *work)
234 */ 119 */
235static void disable_media(struct tipc_bearer *tb_ptr) 120static void disable_media(struct tipc_bearer *tb_ptr)
236{ 121{
237 struct eth_media *eb_ptr = (struct eth_media *)tb_ptr->usr_handle;
238
239 eb_ptr->bearer = NULL;
240 INIT_WORK(&eb_ptr->cleanup, cleanup_media);
241 schedule_work(&eb_ptr->cleanup);
242 RCU_INIT_POINTER(tb_ptr->dev->tipc_ptr, NULL); 122 RCU_INIT_POINTER(tb_ptr->dev->tipc_ptr, NULL);
243} 123 dev_put(tb_ptr->dev);
244
245/**
246 * recv_notification - handle device updates from OS
247 *
248 * Change the state of the Ethernet bearer (if any) associated with the
249 * specified device.
250 */
251static int recv_notification(struct notifier_block *nb, unsigned long evt,
252 void *ptr)
253{
254 struct tipc_bearer *b_ptr;
255 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
256
257 if (!net_eq(dev_net(dev), &init_net))
258 return NOTIFY_DONE;
259
260 rcu_read_lock();
261 b_ptr = rcu_dereference(dev->tipc_ptr);
262 if (!b_ptr) {
263 rcu_read_unlock();
264 return NOTIFY_DONE; /* bearer had been disabled */
265 }
266
267 b_ptr->mtu = dev->mtu;
268
269 switch (evt) {
270 case NETDEV_CHANGE:
271 if (netif_carrier_ok(dev))
272 break;
273 case NETDEV_DOWN:
274 case NETDEV_CHANGEMTU:
275 case NETDEV_CHANGEADDR:
276 tipc_reset_bearer(b_ptr);
277 break;
278 case NETDEV_UNREGISTER:
279 case NETDEV_CHANGENAME:
280 tipc_disable_bearer(b_ptr->name);
281 break;
282 }
283 rcu_read_unlock();
284
285 return NOTIFY_OK;
286} 124}
287 125
288/** 126/**
@@ -338,34 +176,3 @@ struct tipc_media eth_media_info = {
338 .name = "eth" 176 .name = "eth"
339}; 177};
340 178
341/**
342 * tipc_eth_media_start - activate Ethernet bearer support
343 *
344 * Register Ethernet media type with TIPC bearer code. Also register
345 * with OS for notifications about device state changes.
346 */
347int tipc_eth_media_start(void)
348{
349 int res;
350
351 if (eth_started)
352 return -EINVAL;
353
354 res = register_netdevice_notifier(&notifier);
355 if (!res)
356 eth_started = 1;
357 return res;
358}
359
360/**
361 * tipc_eth_media_stop - deactivate Ethernet bearer support
362 */
363void tipc_eth_media_stop(void)
364{
365 if (!eth_started)
366 return;
367
368 flush_scheduled_work();
369 unregister_netdevice_notifier(&notifier);
370 eth_started = 0;
371}
diff --git a/net/tipc/ib_media.c b/net/tipc/ib_media.c
index 9fdf03cd672b..62d91aeda058 100644
--- a/net/tipc/ib_media.c
+++ b/net/tipc/ib_media.c
@@ -42,34 +42,6 @@
42#include "core.h" 42#include "core.h"
43#include "bearer.h" 43#include "bearer.h"
44 44
45#define MAX_IB_MEDIA MAX_BEARERS
46
47/**
48 * struct ib_media - Infiniband media data structure
49 * @bearer: ptr to associated "generic" bearer structure
50 * @dev: ptr to associated Infiniband network device
51 * @tipc_packet_type: used in binding TIPC to Infiniband driver
52 * @cleanup: work item used when disabling bearer
53 */
54
55struct ib_media {
56 struct tipc_bearer *bearer;
57 struct net_device *dev;
58 struct packet_type tipc_packet_type;
59 struct work_struct setup;
60 struct work_struct cleanup;
61};
62
63static struct ib_media ib_media_array[MAX_IB_MEDIA];
64static int ib_started;
65static int recv_msg(struct sk_buff *buf, struct net_device *dev,
66 struct packet_type *pt, struct net_device *orig_dev);
67
68static struct packet_type tipc_packet_type __read_mostly = {
69 .type = __constant_htons(ETH_P_TIPC),
70 .func = recv_msg,
71};
72
73/** 45/**
74 * ib_media_addr_set - initialize Infiniband media address structure 46 * ib_media_addr_set - initialize Infiniband media address structure
75 * 47 *
@@ -92,16 +64,14 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
92 struct tipc_media_addr *dest) 64 struct tipc_media_addr *dest)
93{ 65{
94 struct sk_buff *clone; 66 struct sk_buff *clone;
95 struct net_device *dev;
96 int delta; 67 int delta;
68 struct net_device *dev = tb_ptr->dev;
97 69
98 clone = skb_clone(buf, GFP_ATOMIC); 70 clone = skb_clone(buf, GFP_ATOMIC);
99 if (!clone) 71 if (!clone)
100 return 0; 72 return 0;
101 73
102 dev = ((struct ib_media *)(tb_ptr->usr_handle))->dev;
103 delta = dev->hard_header_len - skb_headroom(buf); 74 delta = dev->hard_header_len - skb_headroom(buf);
104
105 if ((delta > 0) && 75 if ((delta > 0) &&
106 pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { 76 pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
107 kfree_skb(clone); 77 kfree_skb(clone);
@@ -118,79 +88,21 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
118} 88}
119 89
120/** 90/**
121 * recv_msg - handle incoming TIPC message from an InfiniBand interface
122 *
123 * Accept only packets explicitly sent to this node, or broadcast packets;
124 * ignores packets sent using InfiniBand multicast, and traffic sent to other
125 * nodes (which can happen if interface is running in promiscuous mode).
126 */
127static int recv_msg(struct sk_buff *buf, struct net_device *dev,
128 struct packet_type *pt, struct net_device *orig_dev)
129{
130 struct tipc_bearer *b_ptr;
131
132 if (!net_eq(dev_net(dev), &init_net)) {
133 kfree_skb(buf);
134 return NET_RX_DROP;
135 }
136
137 rcu_read_lock();
138 b_ptr = rcu_dereference(dev->tipc_ptr);
139 if (likely(b_ptr)) {
140 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
141 buf->next = NULL;
142 tipc_recv_msg(buf, b_ptr);
143 rcu_read_unlock();
144 return NET_RX_SUCCESS;
145 }
146 }
147 rcu_read_unlock();
148
149 kfree_skb(buf);
150 return NET_RX_DROP;
151}
152
153/**
154 * setup_bearer - setup association between InfiniBand bearer and interface
155 */
156static void setup_media(struct work_struct *work)
157{
158 dev_add_pack(&tipc_packet_type);
159}
160
161/**
162 * enable_media - attach TIPC bearer to an InfiniBand interface 91 * enable_media - attach TIPC bearer to an InfiniBand interface
163 */ 92 */
164static int enable_media(struct tipc_bearer *tb_ptr) 93static int enable_media(struct tipc_bearer *tb_ptr)
165{ 94{
166 struct net_device *dev; 95 struct net_device *dev;
167 struct ib_media *ib_ptr = &ib_media_array[0];
168 struct ib_media *stop = &ib_media_array[MAX_IB_MEDIA];
169 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; 96 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
170 int pending_dev = 0;
171
172 /* Find unused InfiniBand bearer structure */
173 while (ib_ptr->dev) {
174 if (!ib_ptr->bearer)
175 pending_dev++;
176 if (++ib_ptr == stop)
177 return pending_dev ? -EAGAIN : -EDQUOT;
178 }
179 97
180 /* Find device with specified name */ 98 /* Find device with specified name */
181 dev = dev_get_by_name(&init_net, driver_name); 99 dev = dev_get_by_name(&init_net, driver_name);
182 if (!dev) 100 if (!dev)
183 return -ENODEV; 101 return -ENODEV;
184 102
185 /* Create InfiniBand bearer for device */
186 ib_ptr->dev = dev;
187 INIT_WORK(&ib_ptr->setup, setup_media);
188 schedule_work(&ib_ptr->setup);
189
190 /* Associate TIPC bearer with InfiniBand bearer */ 103 /* Associate TIPC bearer with InfiniBand bearer */
191 tb_ptr->dev = dev; 104 tb_ptr->dev = dev;
192 ib_ptr->bearer = tb_ptr; 105 tb_ptr->usr_handle = NULL;
193 tb_ptr->usr_handle = (void *)ib_ptr;
194 memset(tb_ptr->bcast_addr.value, 0, sizeof(tb_ptr->bcast_addr.value)); 106 memset(tb_ptr->bcast_addr.value, 0, sizeof(tb_ptr->bcast_addr.value));
195 memcpy(tb_ptr->bcast_addr.value, dev->broadcast, INFINIBAND_ALEN); 107 memcpy(tb_ptr->bcast_addr.value, dev->broadcast, INFINIBAND_ALEN);
196 tb_ptr->bcast_addr.media_id = TIPC_MEDIA_TYPE_IB; 108 tb_ptr->bcast_addr.media_id = TIPC_MEDIA_TYPE_IB;
@@ -202,21 +114,6 @@ static int enable_media(struct tipc_bearer *tb_ptr)
202} 114}
203 115
204/** 116/**
205 * cleanup_bearer - break association between InfiniBand bearer and interface
206 *
207 * This routine must be invoked from a work queue because it can sleep.
208 */
209static void cleanup_bearer(struct work_struct *work)
210{
211 struct ib_media *ib_ptr =
212 container_of(work, struct ib_media, cleanup);
213
214 dev_remove_pack(&tipc_packet_type);
215 dev_put(ib_ptr->dev);
216 ib_ptr->dev = NULL;
217}
218
219/**
220 * disable_media - detach TIPC bearer from an InfiniBand interface 117 * disable_media - detach TIPC bearer from an InfiniBand interface
221 * 118 *
222 * Mark InfiniBand bearer as inactive so that incoming buffers are thrown away, 119 * Mark InfiniBand bearer as inactive so that incoming buffers are thrown away,
@@ -225,63 +122,11 @@ static void cleanup_bearer(struct work_struct *work)
225 */ 122 */
226static void disable_media(struct tipc_bearer *tb_ptr) 123static void disable_media(struct tipc_bearer *tb_ptr)
227{ 124{
228 struct ib_media *ib_ptr = (struct ib_media *)tb_ptr->usr_handle;
229
230 ib_ptr->bearer = NULL;
231 INIT_WORK(&ib_ptr->cleanup, cleanup_bearer);
232 schedule_work(&ib_ptr->cleanup);
233 RCU_INIT_POINTER(tb_ptr->dev->tipc_ptr, NULL); 125 RCU_INIT_POINTER(tb_ptr->dev->tipc_ptr, NULL);
126 dev_put(tb_ptr->dev);
234} 127}
235 128
236/** 129/**
237 * recv_notification - handle device updates from OS
238 *
239 * Change the state of the InfiniBand bearer (if any) associated with the
240 * specified device.
241 */
242static int recv_notification(struct notifier_block *nb, unsigned long evt,
243 void *ptr)
244{
245 struct tipc_bearer *b_ptr;
246 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
247
248 if (!net_eq(dev_net(dev), &init_net))
249 return NOTIFY_DONE;
250
251 rcu_read_lock();
252 b_ptr = rcu_dereference(dev->tipc_ptr);
253 if (!b_ptr) {
254 rcu_read_unlock();
255 return NOTIFY_DONE; /* bearer had been disabled */
256 }
257
258 b_ptr->mtu = dev->mtu;
259
260 switch (evt) {
261 case NETDEV_CHANGE:
262 if (netif_carrier_ok(dev))
263 break;
264 case NETDEV_DOWN:
265 case NETDEV_CHANGEMTU:
266 case NETDEV_CHANGEADDR:
267 tipc_reset_bearer(b_ptr);
268 break;
269 case NETDEV_UNREGISTER:
270 case NETDEV_CHANGENAME:
271 tipc_disable_bearer(b_ptr->name);
272 break;
273 }
274 rcu_read_unlock();
275
276 return NOTIFY_OK;
277}
278
279static struct notifier_block notifier = {
280 .notifier_call = recv_notification,
281 .priority = 0,
282};
283
284/**
285 * ib_addr2str - convert InfiniBand address to string 130 * ib_addr2str - convert InfiniBand address to string
286 */ 131 */
287static int ib_addr2str(struct tipc_media_addr *a, char *str_buf, int str_size) 132static int ib_addr2str(struct tipc_media_addr *a, char *str_buf, int str_size)
@@ -332,34 +177,3 @@ struct tipc_media ib_media_info = {
332 .name = "ib" 177 .name = "ib"
333}; 178};
334 179
335/**
336 * tipc_ib_media_start - activate InfiniBand bearer support
337 *
338 * Register InfiniBand media type with TIPC bearer code. Also register
339 * with OS for notifications about device state changes.
340 */
341int tipc_ib_media_start(void)
342{
343 int res;
344
345 if (ib_started)
346 return -EINVAL;
347
348 res = register_netdevice_notifier(&notifier);
349 if (!res)
350 ib_started = 1;
351 return res;
352}
353
354/**
355 * tipc_ib_media_stop - deactivate InfiniBand bearer support
356 */
357void tipc_ib_media_stop(void)
358{
359 if (!ib_started)
360 return;
361
362 flush_scheduled_work();
363 unregister_netdevice_notifier(&notifier);
364 ib_started = 0;
365}