diff options
Diffstat (limited to 'net/tipc/bearer.c')
-rw-r--r-- | net/tipc/bearer.c | 190 |
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 | ||
44 | static struct media media_list[MAX_MEDIA]; | 44 | static struct tipc_media *media_list[MAX_MEDIA]; |
45 | static u32 media_count; | 45 | static u32 media_count; |
46 | 46 | ||
47 | struct tipc_bearer tipc_bearers[MAX_BEARERS]; | 47 | struct 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 | ||
71 | static struct media *media_find(const char *name) | 71 | struct 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 | |||
86 | static 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 | ||
89 | int tipc_register_media(u32 media_type, | 103 | int 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; |
168 | exit: | 127 | exit: |
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 | ||
177 | void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) | 138 | void 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) | |||
207 | struct sk_buff *tipc_media_get_names(void) | 160 | struct 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 | ||
234 | static int bearer_name_validate(const char *name, | 187 | static 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 | ||
282 | static struct tipc_bearer *bearer_find(const char *name) | 235 | struct 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) | |||
318 | struct sk_buff *tipc_bearer_get_names(void) | 271 | struct 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) | |||
366 | static int bearer_push(struct tipc_bearer *b_ptr) | 318 | static 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 | ||
415 | static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr, struct link *l_ptr) | 367 | static 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 | ||
428 | void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr) | 381 | void 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 | */ |
441 | int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr) | 394 | int 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 | ||
460 | int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr) | 414 | int 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) | |||
473 | int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) | 427 | int 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: | |||
590 | int tipc_block_bearer(const char *name) | 546 | int 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 | ||
626 | static void bearer_disable(struct tipc_bearer *b_ptr) | 582 | static 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; |