aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bearer.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/bearer.c')
-rw-r--r--net/tipc/bearer.c190
1 files changed, 73 insertions, 117 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index e2202de3d93e..329fb659fae4 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -41,7 +41,7 @@
41 41
42#define MAX_ADDR_STR 32 42#define MAX_ADDR_STR 32
43 43
44static struct media media_list[MAX_MEDIA]; 44static struct tipc_media *media_list[MAX_MEDIA];
45static u32 media_count; 45static u32 media_count;
46 46
47struct tipc_bearer tipc_bearers[MAX_BEARERS]; 47struct tipc_bearer tipc_bearers[MAX_BEARERS];
@@ -65,17 +65,31 @@ static int media_name_valid(const char *name)
65} 65}
66 66
67/** 67/**
68 * media_find - locates specified media object by name 68 * tipc_media_find - locates specified media object by name
69 */ 69 */
70 70
71static struct media *media_find(const char *name) 71struct tipc_media *tipc_media_find(const char *name)
72{ 72{
73 struct media *m_ptr;
74 u32 i; 73 u32 i;
75 74
76 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { 75 for (i = 0; i < media_count; i++) {
77 if (!strcmp(m_ptr->name, name)) 76 if (!strcmp(media_list[i]->name, name))
78 return m_ptr; 77 return media_list[i];
78 }
79 return NULL;
80}
81
82/**
83 * media_find_id - locates specified media object by type identifier
84 */
85
86static struct tipc_media *media_find_id(u8 type)
87{
88 u32 i;
89
90 for (i = 0; i < media_count; i++) {
91 if (media_list[i]->type_id == type)
92 return media_list[i];
79 } 93 }
80 return NULL; 94 return NULL;
81} 95}
@@ -86,87 +100,34 @@ static struct media *media_find(const char *name)
86 * Bearers for this media type must be activated separately at a later stage. 100 * Bearers for this media type must be activated separately at a later stage.
87 */ 101 */
88 102
89int tipc_register_media(u32 media_type, 103int tipc_register_media(struct tipc_media *m_ptr)
90 char *name,
91 int (*enable)(struct tipc_bearer *),
92 void (*disable)(struct tipc_bearer *),
93 int (*send_msg)(struct sk_buff *,
94 struct tipc_bearer *,
95 struct tipc_media_addr *),
96 char *(*addr2str)(struct tipc_media_addr *a,
97 char *str_buf, int str_size),
98 struct tipc_media_addr *bcast_addr,
99 const u32 bearer_priority,
100 const u32 link_tolerance, /* [ms] */
101 const u32 send_window_limit)
102{ 104{
103 struct media *m_ptr;
104 u32 media_id;
105 u32 i;
106 int res = -EINVAL; 105 int res = -EINVAL;
107 106
108 write_lock_bh(&tipc_net_lock); 107 write_lock_bh(&tipc_net_lock);
109 108
110 if (tipc_mode != TIPC_NET_MODE) { 109 if (!media_name_valid(m_ptr->name))
111 warn("Media <%s> rejected, not in networked mode yet\n", name);
112 goto exit; 110 goto exit;
113 } 111 if ((m_ptr->bcast_addr.media_id != m_ptr->type_id) ||
114 if (!media_name_valid(name)) { 112 !m_ptr->bcast_addr.broadcast)
115 warn("Media <%s> rejected, illegal name\n", name);
116 goto exit; 113 goto exit;
117 } 114 if (m_ptr->priority > TIPC_MAX_LINK_PRI)
118 if (!bcast_addr) {
119 warn("Media <%s> rejected, no broadcast address\n", name);
120 goto exit; 115 goto exit;
121 } 116 if ((m_ptr->tolerance < TIPC_MIN_LINK_TOL) ||
122 if ((bearer_priority < TIPC_MIN_LINK_PRI) || 117 (m_ptr->tolerance > TIPC_MAX_LINK_TOL))
123 (bearer_priority > TIPC_MAX_LINK_PRI)) {
124 warn("Media <%s> rejected, illegal priority (%u)\n", name,
125 bearer_priority);
126 goto exit; 118 goto exit;
127 } 119 if (media_count >= MAX_MEDIA)
128 if ((link_tolerance < TIPC_MIN_LINK_TOL) ||
129 (link_tolerance > TIPC_MAX_LINK_TOL)) {
130 warn("Media <%s> rejected, illegal tolerance (%u)\n", name,
131 link_tolerance);
132 goto exit; 120 goto exit;
133 } 121 if (tipc_media_find(m_ptr->name) || media_find_id(m_ptr->type_id))
134
135 media_id = media_count++;
136 if (media_id >= MAX_MEDIA) {
137 warn("Media <%s> rejected, media limit reached (%u)\n", name,
138 MAX_MEDIA);
139 media_count--;
140 goto exit; 122 goto exit;
141 }
142 for (i = 0; i < media_id; i++) {
143 if (media_list[i].type_id == media_type) {
144 warn("Media <%s> rejected, duplicate type (%u)\n", name,
145 media_type);
146 media_count--;
147 goto exit;
148 }
149 if (!strcmp(name, media_list[i].name)) {
150 warn("Media <%s> rejected, duplicate name\n", name);
151 media_count--;
152 goto exit;
153 }
154 }
155 123
156 m_ptr = &media_list[media_id]; 124 media_list[media_count] = m_ptr;
157 m_ptr->type_id = media_type; 125 media_count++;
158 m_ptr->send_msg = send_msg;
159 m_ptr->enable_bearer = enable;
160 m_ptr->disable_bearer = disable;
161 m_ptr->addr2str = addr2str;
162 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr));
163 strcpy(m_ptr->name, name);
164 m_ptr->priority = bearer_priority;
165 m_ptr->tolerance = link_tolerance;
166 m_ptr->window = send_window_limit;
167 res = 0; 126 res = 0;
168exit: 127exit:
169 write_unlock_bh(&tipc_net_lock); 128 write_unlock_bh(&tipc_net_lock);
129 if (res)
130 warn("Media <%s> registration error\n", m_ptr->name);
170 return res; 131 return res;
171} 132}
172 133
@@ -176,27 +137,19 @@ exit:
176 137
177void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) 138void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
178{ 139{
179 struct media *m_ptr; 140 char addr_str[MAX_ADDR_STR];
180 u32 media_type; 141 struct tipc_media *m_ptr;
181 u32 i;
182 142
183 media_type = ntohl(a->type); 143 m_ptr = media_find_id(a->media_id);
184 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) {
185 if (m_ptr->type_id == media_type)
186 break;
187 }
188
189 if ((i < media_count) && (m_ptr->addr2str != NULL)) {
190 char addr_str[MAX_ADDR_STR];
191 144
192 tipc_printf(pb, "%s(%s)", m_ptr->name, 145 if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str)))
193 m_ptr->addr2str(a, addr_str, sizeof(addr_str))); 146 tipc_printf(pb, "%s(%s)", m_ptr->name, addr_str);
194 } else { 147 else {
195 unchar *addr = (unchar *)&a->dev_addr; 148 u32 i;
196 149
197 tipc_printf(pb, "UNKNOWN(%u)", media_type); 150 tipc_printf(pb, "UNKNOWN(%u)", a->media_id);
198 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) 151 for (i = 0; i < sizeof(a->value); i++)
199 tipc_printf(pb, "-%02x", addr[i]); 152 tipc_printf(pb, "-%02x", a->value[i]);
200 } 153 }
201} 154}
202 155
@@ -207,7 +160,6 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
207struct sk_buff *tipc_media_get_names(void) 160struct sk_buff *tipc_media_get_names(void)
208{ 161{
209 struct sk_buff *buf; 162 struct sk_buff *buf;
210 struct media *m_ptr;
211 int i; 163 int i;
212 164
213 buf = tipc_cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME)); 165 buf = tipc_cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME));
@@ -215,9 +167,10 @@ struct sk_buff *tipc_media_get_names(void)
215 return NULL; 167 return NULL;
216 168
217 read_lock_bh(&tipc_net_lock); 169 read_lock_bh(&tipc_net_lock);
218 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { 170 for (i = 0; i < media_count; i++) {
219 tipc_cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, m_ptr->name, 171 tipc_cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME,
220 strlen(m_ptr->name) + 1); 172 media_list[i]->name,
173 strlen(media_list[i]->name) + 1);
221 } 174 }
222 read_unlock_bh(&tipc_net_lock); 175 read_unlock_bh(&tipc_net_lock);
223 return buf; 176 return buf;
@@ -232,7 +185,7 @@ struct sk_buff *tipc_media_get_names(void)
232 */ 185 */
233 186
234static int bearer_name_validate(const char *name, 187static int bearer_name_validate(const char *name,
235 struct bearer_name *name_parts) 188 struct tipc_bearer_names *name_parts)
236{ 189{
237 char name_copy[TIPC_MAX_BEARER_NAME]; 190 char name_copy[TIPC_MAX_BEARER_NAME];
238 char *media_name; 191 char *media_name;
@@ -276,10 +229,10 @@ static int bearer_name_validate(const char *name,
276} 229}
277 230
278/** 231/**
279 * bearer_find - locates bearer object with matching bearer name 232 * tipc_bearer_find - locates bearer object with matching bearer name
280 */ 233 */
281 234
282static struct tipc_bearer *bearer_find(const char *name) 235struct tipc_bearer *tipc_bearer_find(const char *name)
283{ 236{
284 struct tipc_bearer *b_ptr; 237 struct tipc_bearer *b_ptr;
285 u32 i; 238 u32 i;
@@ -318,7 +271,6 @@ struct tipc_bearer *tipc_bearer_find_interface(const char *if_name)
318struct sk_buff *tipc_bearer_get_names(void) 271struct sk_buff *tipc_bearer_get_names(void)
319{ 272{
320 struct sk_buff *buf; 273 struct sk_buff *buf;
321 struct media *m_ptr;
322 struct tipc_bearer *b_ptr; 274 struct tipc_bearer *b_ptr;
323 int i, j; 275 int i, j;
324 276
@@ -327,10 +279,10 @@ struct sk_buff *tipc_bearer_get_names(void)
327 return NULL; 279 return NULL;
328 280
329 read_lock_bh(&tipc_net_lock); 281 read_lock_bh(&tipc_net_lock);
330 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { 282 for (i = 0; i < media_count; i++) {
331 for (j = 0; j < MAX_BEARERS; j++) { 283 for (j = 0; j < MAX_BEARERS; j++) {
332 b_ptr = &tipc_bearers[j]; 284 b_ptr = &tipc_bearers[j];
333 if (b_ptr->active && (b_ptr->media == m_ptr)) { 285 if (b_ptr->active && (b_ptr->media == media_list[i])) {
334 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 286 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME,
335 b_ptr->name, 287 b_ptr->name,
336 strlen(b_ptr->name) + 1); 288 strlen(b_ptr->name) + 1);
@@ -366,7 +318,7 @@ void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
366static int bearer_push(struct tipc_bearer *b_ptr) 318static int bearer_push(struct tipc_bearer *b_ptr)
367{ 319{
368 u32 res = 0; 320 u32 res = 0;
369 struct link *ln, *tln; 321 struct tipc_link *ln, *tln;
370 322
371 if (b_ptr->blocked) 323 if (b_ptr->blocked)
372 return 0; 324 return 0;
@@ -412,7 +364,8 @@ void tipc_continue(struct tipc_bearer *b_ptr)
412 * bearer.lock is busy 364 * bearer.lock is busy
413 */ 365 */
414 366
415static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr, struct link *l_ptr) 367static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr,
368 struct tipc_link *l_ptr)
416{ 369{
417 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links); 370 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);
418} 371}
@@ -425,7 +378,7 @@ static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr, struct link
425 * bearer.lock is free 378 * bearer.lock is free
426 */ 379 */
427 380
428void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr) 381void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct tipc_link *l_ptr)
429{ 382{
430 spin_lock_bh(&b_ptr->lock); 383 spin_lock_bh(&b_ptr->lock);
431 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 384 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
@@ -438,7 +391,8 @@ void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr)
438 * and if there is, try to resolve it before returning. 391 * and if there is, try to resolve it before returning.
439 * 'tipc_net_lock' is read_locked when this function is called 392 * 'tipc_net_lock' is read_locked when this function is called
440 */ 393 */
441int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr) 394int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr,
395 struct tipc_link *l_ptr)
442{ 396{
443 int res = 1; 397 int res = 1;
444 398
@@ -457,7 +411,7 @@ int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr
457 * tipc_bearer_congested - determines if bearer is currently congested 411 * tipc_bearer_congested - determines if bearer is currently congested
458 */ 412 */
459 413
460int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr) 414int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct tipc_link *l_ptr)
461{ 415{
462 if (unlikely(b_ptr->blocked)) 416 if (unlikely(b_ptr->blocked))
463 return 1; 417 return 1;
@@ -473,8 +427,8 @@ int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr)
473int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) 427int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
474{ 428{
475 struct tipc_bearer *b_ptr; 429 struct tipc_bearer *b_ptr;
476 struct media *m_ptr; 430 struct tipc_media *m_ptr;
477 struct bearer_name b_name; 431 struct tipc_bearer_names b_names;
478 char addr_string[16]; 432 char addr_string[16];
479 u32 bearer_id; 433 u32 bearer_id;
480 u32 with_this_prio; 434 u32 with_this_prio;
@@ -486,7 +440,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
486 name); 440 name);
487 return -ENOPROTOOPT; 441 return -ENOPROTOOPT;
488 } 442 }
489 if (!bearer_name_validate(name, &b_name)) { 443 if (!bearer_name_validate(name, &b_names)) {
490 warn("Bearer <%s> rejected, illegal name\n", name); 444 warn("Bearer <%s> rejected, illegal name\n", name);
491 return -EINVAL; 445 return -EINVAL;
492 } 446 }
@@ -511,10 +465,10 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
511 465
512 write_lock_bh(&tipc_net_lock); 466 write_lock_bh(&tipc_net_lock);
513 467
514 m_ptr = media_find(b_name.media_name); 468 m_ptr = tipc_media_find(b_names.media_name);
515 if (!m_ptr) { 469 if (!m_ptr) {
516 warn("Bearer <%s> rejected, media <%s> not registered\n", name, 470 warn("Bearer <%s> rejected, media <%s> not registered\n", name,
517 b_name.media_name); 471 b_names.media_name);
518 goto exit; 472 goto exit;
519 } 473 }
520 474
@@ -561,6 +515,8 @@ restart:
561 515
562 b_ptr->identity = bearer_id; 516 b_ptr->identity = bearer_id;
563 b_ptr->media = m_ptr; 517 b_ptr->media = m_ptr;
518 b_ptr->tolerance = m_ptr->tolerance;
519 b_ptr->window = m_ptr->window;
564 b_ptr->net_plane = bearer_id + 'A'; 520 b_ptr->net_plane = bearer_id + 'A';
565 b_ptr->active = 1; 521 b_ptr->active = 1;
566 b_ptr->priority = priority; 522 b_ptr->priority = priority;
@@ -590,11 +546,11 @@ exit:
590int tipc_block_bearer(const char *name) 546int tipc_block_bearer(const char *name)
591{ 547{
592 struct tipc_bearer *b_ptr = NULL; 548 struct tipc_bearer *b_ptr = NULL;
593 struct link *l_ptr; 549 struct tipc_link *l_ptr;
594 struct link *temp_l_ptr; 550 struct tipc_link *temp_l_ptr;
595 551
596 read_lock_bh(&tipc_net_lock); 552 read_lock_bh(&tipc_net_lock);
597 b_ptr = bearer_find(name); 553 b_ptr = tipc_bearer_find(name);
598 if (!b_ptr) { 554 if (!b_ptr) {
599 warn("Attempt to block unknown bearer <%s>\n", name); 555 warn("Attempt to block unknown bearer <%s>\n", name);
600 read_unlock_bh(&tipc_net_lock); 556 read_unlock_bh(&tipc_net_lock);
@@ -625,8 +581,8 @@ int tipc_block_bearer(const char *name)
625 581
626static void bearer_disable(struct tipc_bearer *b_ptr) 582static void bearer_disable(struct tipc_bearer *b_ptr)
627{ 583{
628 struct link *l_ptr; 584 struct tipc_link *l_ptr;
629 struct link *temp_l_ptr; 585 struct tipc_link *temp_l_ptr;
630 586
631 info("Disabling bearer <%s>\n", b_ptr->name); 587 info("Disabling bearer <%s>\n", b_ptr->name);
632 spin_lock_bh(&b_ptr->lock); 588 spin_lock_bh(&b_ptr->lock);
@@ -648,7 +604,7 @@ int tipc_disable_bearer(const char *name)
648 int res; 604 int res;
649 605
650 write_lock_bh(&tipc_net_lock); 606 write_lock_bh(&tipc_net_lock);
651 b_ptr = bearer_find(name); 607 b_ptr = tipc_bearer_find(name);
652 if (b_ptr == NULL) { 608 if (b_ptr == NULL) {
653 warn("Attempt to disable unknown bearer <%s>\n", name); 609 warn("Attempt to disable unknown bearer <%s>\n", name);
654 res = -EINVAL; 610 res = -EINVAL;