diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bearer.c | 29 | ||||
-rw-r--r-- | net/tipc/bearer.h | 3 | ||||
-rw-r--r-- | net/tipc/name_table.c | 103 | ||||
-rw-r--r-- | net/tipc/node.c | 33 | ||||
-rw-r--r-- | net/tipc/node.h | 3 | ||||
-rw-r--r-- | net/tipc/socket.c | 13 | ||||
-rw-r--r-- | net/tipc/udp_media.c | 4 | ||||
-rw-r--r-- | net/tipc/udp_media.h | 14 |
8 files changed, 143 insertions, 59 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index f7d47c89d658..2dfb492a7c94 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -697,6 +697,9 @@ static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, | |||
697 | goto prop_msg_full; | 697 | goto prop_msg_full; |
698 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->window)) | 698 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->window)) |
699 | goto prop_msg_full; | 699 | goto prop_msg_full; |
700 | if (bearer->media->type_id == TIPC_MEDIA_TYPE_UDP) | ||
701 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_MTU, bearer->mtu)) | ||
702 | goto prop_msg_full; | ||
700 | 703 | ||
701 | nla_nest_end(msg->skb, prop); | 704 | nla_nest_end(msg->skb, prop); |
702 | 705 | ||
@@ -979,12 +982,23 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) | |||
979 | 982 | ||
980 | if (props[TIPC_NLA_PROP_TOL]) { | 983 | if (props[TIPC_NLA_PROP_TOL]) { |
981 | b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); | 984 | b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); |
982 | tipc_node_apply_tolerance(net, b); | 985 | tipc_node_apply_property(net, b, TIPC_NLA_PROP_TOL); |
983 | } | 986 | } |
984 | if (props[TIPC_NLA_PROP_PRIO]) | 987 | if (props[TIPC_NLA_PROP_PRIO]) |
985 | b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); | 988 | b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); |
986 | if (props[TIPC_NLA_PROP_WIN]) | 989 | if (props[TIPC_NLA_PROP_WIN]) |
987 | b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); | 990 | b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); |
991 | if (props[TIPC_NLA_PROP_MTU]) { | ||
992 | if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) | ||
993 | return -EINVAL; | ||
994 | #ifdef CONFIG_TIPC_MEDIA_UDP | ||
995 | if (tipc_udp_mtu_bad(nla_get_u32 | ||
996 | (props[TIPC_NLA_PROP_MTU]))) | ||
997 | return -EINVAL; | ||
998 | b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]); | ||
999 | tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU); | ||
1000 | #endif | ||
1001 | } | ||
988 | } | 1002 | } |
989 | 1003 | ||
990 | return 0; | 1004 | return 0; |
@@ -1029,6 +1043,9 @@ static int __tipc_nl_add_media(struct tipc_nl_msg *msg, | |||
1029 | goto prop_msg_full; | 1043 | goto prop_msg_full; |
1030 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, media->window)) | 1044 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, media->window)) |
1031 | goto prop_msg_full; | 1045 | goto prop_msg_full; |
1046 | if (media->type_id == TIPC_MEDIA_TYPE_UDP) | ||
1047 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_MTU, media->mtu)) | ||
1048 | goto prop_msg_full; | ||
1032 | 1049 | ||
1033 | nla_nest_end(msg->skb, prop); | 1050 | nla_nest_end(msg->skb, prop); |
1034 | nla_nest_end(msg->skb, attrs); | 1051 | nla_nest_end(msg->skb, attrs); |
@@ -1158,6 +1175,16 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) | |||
1158 | m->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); | 1175 | m->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); |
1159 | if (props[TIPC_NLA_PROP_WIN]) | 1176 | if (props[TIPC_NLA_PROP_WIN]) |
1160 | m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); | 1177 | m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); |
1178 | if (props[TIPC_NLA_PROP_MTU]) { | ||
1179 | if (m->type_id != TIPC_MEDIA_TYPE_UDP) | ||
1180 | return -EINVAL; | ||
1181 | #ifdef CONFIG_TIPC_MEDIA_UDP | ||
1182 | if (tipc_udp_mtu_bad(nla_get_u32 | ||
1183 | (props[TIPC_NLA_PROP_MTU]))) | ||
1184 | return -EINVAL; | ||
1185 | m->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]); | ||
1186 | #endif | ||
1187 | } | ||
1161 | } | 1188 | } |
1162 | 1189 | ||
1163 | return 0; | 1190 | return 0; |
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 6efcee63a381..394290cbbb1d 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h | |||
@@ -94,6 +94,8 @@ struct tipc_bearer; | |||
94 | * @priority: default link (and bearer) priority | 94 | * @priority: default link (and bearer) priority |
95 | * @tolerance: default time (in ms) before declaring link failure | 95 | * @tolerance: default time (in ms) before declaring link failure |
96 | * @window: default window (in packets) before declaring link congestion | 96 | * @window: default window (in packets) before declaring link congestion |
97 | * @mtu: max packet size bearer can support for media type not dependent on | ||
98 | * underlying device MTU | ||
97 | * @type_id: TIPC media identifier | 99 | * @type_id: TIPC media identifier |
98 | * @hwaddr_len: TIPC media address len | 100 | * @hwaddr_len: TIPC media address len |
99 | * @name: media name | 101 | * @name: media name |
@@ -118,6 +120,7 @@ struct tipc_media { | |||
118 | u32 priority; | 120 | u32 priority; |
119 | u32 tolerance; | 121 | u32 tolerance; |
120 | u32 window; | 122 | u32 window; |
123 | u32 mtu; | ||
121 | u32 type_id; | 124 | u32 type_id; |
122 | u32 hwaddr_len; | 125 | u32 hwaddr_len; |
123 | char name[TIPC_MAX_MEDIA_NAME]; | 126 | char name[TIPC_MAX_MEDIA_NAME]; |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index dd1c4fa2eb78..bebe88cae07b 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -136,12 +136,12 @@ static struct tipc_service *tipc_service_create(u32 type, struct hlist_head *hd) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * tipc_service_find_range - find service range matching a service instance | 139 | * tipc_service_first_range - find first service range in tree matching instance |
140 | * | 140 | * |
141 | * Very time-critical, so binary search through range rb tree | 141 | * Very time-critical, so binary search through range rb tree |
142 | */ | 142 | */ |
143 | static struct service_range *tipc_service_find_range(struct tipc_service *sc, | 143 | static struct service_range *tipc_service_first_range(struct tipc_service *sc, |
144 | u32 instance) | 144 | u32 instance) |
145 | { | 145 | { |
146 | struct rb_node *n = sc->ranges.rb_node; | 146 | struct rb_node *n = sc->ranges.rb_node; |
147 | struct service_range *sr; | 147 | struct service_range *sr; |
@@ -158,6 +158,30 @@ static struct service_range *tipc_service_find_range(struct tipc_service *sc, | |||
158 | return NULL; | 158 | return NULL; |
159 | } | 159 | } |
160 | 160 | ||
161 | /* tipc_service_find_range - find service range matching publication parameters | ||
162 | */ | ||
163 | static struct service_range *tipc_service_find_range(struct tipc_service *sc, | ||
164 | u32 lower, u32 upper) | ||
165 | { | ||
166 | struct rb_node *n = sc->ranges.rb_node; | ||
167 | struct service_range *sr; | ||
168 | |||
169 | sr = tipc_service_first_range(sc, lower); | ||
170 | if (!sr) | ||
171 | return NULL; | ||
172 | |||
173 | /* Look for exact match */ | ||
174 | for (n = &sr->tree_node; n; n = rb_next(n)) { | ||
175 | sr = container_of(n, struct service_range, tree_node); | ||
176 | if (sr->upper == upper) | ||
177 | break; | ||
178 | } | ||
179 | if (!n || sr->lower != lower || sr->upper != upper) | ||
180 | return NULL; | ||
181 | |||
182 | return sr; | ||
183 | } | ||
184 | |||
161 | static struct service_range *tipc_service_create_range(struct tipc_service *sc, | 185 | static struct service_range *tipc_service_create_range(struct tipc_service *sc, |
162 | u32 lower, u32 upper) | 186 | u32 lower, u32 upper) |
163 | { | 187 | { |
@@ -238,54 +262,19 @@ err: | |||
238 | /** | 262 | /** |
239 | * tipc_service_remove_publ - remove a publication from a service | 263 | * tipc_service_remove_publ - remove a publication from a service |
240 | */ | 264 | */ |
241 | static struct publication *tipc_service_remove_publ(struct net *net, | 265 | static struct publication *tipc_service_remove_publ(struct service_range *sr, |
242 | struct tipc_service *sc, | 266 | u32 node, u32 key) |
243 | u32 lower, u32 upper, | ||
244 | u32 node, u32 key, | ||
245 | struct service_range **rng) | ||
246 | { | 267 | { |
247 | struct tipc_subscription *sub, *tmp; | ||
248 | struct service_range *sr; | ||
249 | struct publication *p; | 268 | struct publication *p; |
250 | bool found = false; | ||
251 | bool last = false; | ||
252 | struct rb_node *n; | ||
253 | |||
254 | sr = tipc_service_find_range(sc, lower); | ||
255 | if (!sr) | ||
256 | return NULL; | ||
257 | 269 | ||
258 | /* Find exact matching service range */ | ||
259 | for (n = &sr->tree_node; n; n = rb_next(n)) { | ||
260 | sr = container_of(n, struct service_range, tree_node); | ||
261 | if (sr->upper == upper) | ||
262 | break; | ||
263 | } | ||
264 | if (!n || sr->lower != lower || sr->upper != upper) | ||
265 | return NULL; | ||
266 | |||
267 | /* Find publication, if it exists */ | ||
268 | list_for_each_entry(p, &sr->all_publ, all_publ) { | 270 | list_for_each_entry(p, &sr->all_publ, all_publ) { |
269 | if (p->key != key || (node && node != p->node)) | 271 | if (p->key != key || (node && node != p->node)) |
270 | continue; | 272 | continue; |
271 | found = true; | 273 | list_del(&p->all_publ); |
272 | break; | 274 | list_del(&p->local_publ); |
275 | return p; | ||
273 | } | 276 | } |
274 | if (!found) | 277 | return NULL; |
275 | return NULL; | ||
276 | |||
277 | list_del(&p->all_publ); | ||
278 | list_del(&p->local_publ); | ||
279 | if (list_empty(&sr->all_publ)) | ||
280 | last = true; | ||
281 | |||
282 | /* Notify any waiting subscriptions */ | ||
283 | list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { | ||
284 | tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN, | ||
285 | p->port, p->node, p->scope, last); | ||
286 | } | ||
287 | *rng = sr; | ||
288 | return p; | ||
289 | } | 278 | } |
290 | 279 | ||
291 | /** | 280 | /** |
@@ -376,17 +365,31 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, | |||
376 | u32 node, u32 key) | 365 | u32 node, u32 key) |
377 | { | 366 | { |
378 | struct tipc_service *sc = tipc_service_find(net, type); | 367 | struct tipc_service *sc = tipc_service_find(net, type); |
368 | struct tipc_subscription *sub, *tmp; | ||
379 | struct service_range *sr = NULL; | 369 | struct service_range *sr = NULL; |
380 | struct publication *p = NULL; | 370 | struct publication *p = NULL; |
371 | bool last; | ||
381 | 372 | ||
382 | if (!sc) | 373 | if (!sc) |
383 | return NULL; | 374 | return NULL; |
384 | 375 | ||
385 | spin_lock_bh(&sc->lock); | 376 | spin_lock_bh(&sc->lock); |
386 | p = tipc_service_remove_publ(net, sc, lower, upper, node, key, &sr); | 377 | sr = tipc_service_find_range(sc, lower, upper); |
378 | if (!sr) | ||
379 | goto exit; | ||
380 | p = tipc_service_remove_publ(sr, node, key); | ||
381 | if (!p) | ||
382 | goto exit; | ||
383 | |||
384 | /* Notify any waiting subscriptions */ | ||
385 | last = list_empty(&sr->all_publ); | ||
386 | list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { | ||
387 | tipc_sub_report_overlap(sub, lower, upper, TIPC_WITHDRAWN, | ||
388 | p->port, node, p->scope, last); | ||
389 | } | ||
387 | 390 | ||
388 | /* Remove service range item if this was its last publication */ | 391 | /* Remove service range item if this was its last publication */ |
389 | if (sr && list_empty(&sr->all_publ)) { | 392 | if (list_empty(&sr->all_publ)) { |
390 | rb_erase(&sr->tree_node, &sc->ranges); | 393 | rb_erase(&sr->tree_node, &sc->ranges); |
391 | kfree(sr); | 394 | kfree(sr); |
392 | } | 395 | } |
@@ -396,6 +399,7 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, | |||
396 | hlist_del_init_rcu(&sc->service_list); | 399 | hlist_del_init_rcu(&sc->service_list); |
397 | kfree_rcu(sc, rcu); | 400 | kfree_rcu(sc, rcu); |
398 | } | 401 | } |
402 | exit: | ||
399 | spin_unlock_bh(&sc->lock); | 403 | spin_unlock_bh(&sc->lock); |
400 | return p; | 404 | return p; |
401 | } | 405 | } |
@@ -437,7 +441,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *dnode) | |||
437 | goto not_found; | 441 | goto not_found; |
438 | 442 | ||
439 | spin_lock_bh(&sc->lock); | 443 | spin_lock_bh(&sc->lock); |
440 | sr = tipc_service_find_range(sc, instance); | 444 | sr = tipc_service_first_range(sc, instance); |
441 | if (unlikely(!sr)) | 445 | if (unlikely(!sr)) |
442 | goto no_match; | 446 | goto no_match; |
443 | 447 | ||
@@ -484,7 +488,7 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope, | |||
484 | 488 | ||
485 | spin_lock_bh(&sc->lock); | 489 | spin_lock_bh(&sc->lock); |
486 | 490 | ||
487 | sr = tipc_service_find_range(sc, instance); | 491 | sr = tipc_service_first_range(sc, instance); |
488 | if (!sr) | 492 | if (!sr) |
489 | goto no_match; | 493 | goto no_match; |
490 | 494 | ||
@@ -756,8 +760,7 @@ static void tipc_service_delete(struct net *net, struct tipc_service *sc) | |||
756 | spin_lock_bh(&sc->lock); | 760 | spin_lock_bh(&sc->lock); |
757 | rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) { | 761 | rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) { |
758 | list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) { | 762 | list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) { |
759 | tipc_service_remove_publ(net, sc, p->lower, p->upper, | 763 | tipc_service_remove_publ(sr, p->node, p->key); |
760 | p->node, p->key, &sr); | ||
761 | kfree_rcu(p, rcu); | 764 | kfree_rcu(p, rcu); |
762 | } | 765 | } |
763 | rb_erase(&sr->tree_node, &sc->ranges); | 766 | rb_erase(&sr->tree_node, &sc->ranges); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index f29549de9245..6a44eb812baf 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -195,6 +195,27 @@ int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel) | |||
195 | return mtu; | 195 | return mtu; |
196 | } | 196 | } |
197 | 197 | ||
198 | bool tipc_node_get_id(struct net *net, u32 addr, u8 *id) | ||
199 | { | ||
200 | u8 *own_id = tipc_own_id(net); | ||
201 | struct tipc_node *n; | ||
202 | |||
203 | if (!own_id) | ||
204 | return true; | ||
205 | |||
206 | if (addr == tipc_own_addr(net)) { | ||
207 | memcpy(id, own_id, TIPC_NODEID_LEN); | ||
208 | return true; | ||
209 | } | ||
210 | n = tipc_node_find(net, addr); | ||
211 | if (!n) | ||
212 | return false; | ||
213 | |||
214 | memcpy(id, &n->peer_id, TIPC_NODEID_LEN); | ||
215 | tipc_node_put(n); | ||
216 | return true; | ||
217 | } | ||
218 | |||
198 | u16 tipc_node_get_capabilities(struct net *net, u32 addr) | 219 | u16 tipc_node_get_capabilities(struct net *net, u32 addr) |
199 | { | 220 | { |
200 | struct tipc_node *n; | 221 | struct tipc_node *n; |
@@ -1681,7 +1702,8 @@ discard: | |||
1681 | kfree_skb(skb); | 1702 | kfree_skb(skb); |
1682 | } | 1703 | } |
1683 | 1704 | ||
1684 | void tipc_node_apply_tolerance(struct net *net, struct tipc_bearer *b) | 1705 | void tipc_node_apply_property(struct net *net, struct tipc_bearer *b, |
1706 | int prop) | ||
1685 | { | 1707 | { |
1686 | struct tipc_net *tn = tipc_net(net); | 1708 | struct tipc_net *tn = tipc_net(net); |
1687 | int bearer_id = b->identity; | 1709 | int bearer_id = b->identity; |
@@ -1696,8 +1718,13 @@ void tipc_node_apply_tolerance(struct net *net, struct tipc_bearer *b) | |||
1696 | list_for_each_entry_rcu(n, &tn->node_list, list) { | 1718 | list_for_each_entry_rcu(n, &tn->node_list, list) { |
1697 | tipc_node_write_lock(n); | 1719 | tipc_node_write_lock(n); |
1698 | e = &n->links[bearer_id]; | 1720 | e = &n->links[bearer_id]; |
1699 | if (e->link) | 1721 | if (e->link) { |
1700 | tipc_link_set_tolerance(e->link, b->tolerance, &xmitq); | 1722 | if (prop == TIPC_NLA_PROP_TOL) |
1723 | tipc_link_set_tolerance(e->link, b->tolerance, | ||
1724 | &xmitq); | ||
1725 | else if (prop == TIPC_NLA_PROP_MTU) | ||
1726 | tipc_link_set_mtu(e->link, b->mtu); | ||
1727 | } | ||
1701 | tipc_node_write_unlock(n); | 1728 | tipc_node_write_unlock(n); |
1702 | tipc_bearer_xmit(net, bearer_id, &xmitq, &e->maddr); | 1729 | tipc_bearer_xmit(net, bearer_id, &xmitq, &e->maddr); |
1703 | } | 1730 | } |
diff --git a/net/tipc/node.h b/net/tipc/node.h index f24b83500df1..846c8f240872 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h | |||
@@ -60,6 +60,7 @@ enum { | |||
60 | #define INVALID_BEARER_ID -1 | 60 | #define INVALID_BEARER_ID -1 |
61 | 61 | ||
62 | void tipc_node_stop(struct net *net); | 62 | void tipc_node_stop(struct net *net); |
63 | bool tipc_node_get_id(struct net *net, u32 addr, u8 *id); | ||
63 | u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr); | 64 | u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr); |
64 | void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, | 65 | void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, |
65 | struct tipc_bearer *bearer, | 66 | struct tipc_bearer *bearer, |
@@ -67,7 +68,7 @@ void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, | |||
67 | struct tipc_media_addr *maddr, | 68 | struct tipc_media_addr *maddr, |
68 | bool *respond, bool *dupl_addr); | 69 | bool *respond, bool *dupl_addr); |
69 | void tipc_node_delete_links(struct net *net, int bearer_id); | 70 | void tipc_node_delete_links(struct net *net, int bearer_id); |
70 | void tipc_node_apply_tolerance(struct net *net, struct tipc_bearer *b); | 71 | void tipc_node_apply_property(struct net *net, struct tipc_bearer *b, int prop); |
71 | int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, | 72 | int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, |
72 | char *linkname, size_t len); | 73 | char *linkname, size_t len); |
73 | int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, | 74 | int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3bb45042e833..14a5d055717d 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2970,7 +2970,8 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt, | |||
2970 | 2970 | ||
2971 | static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 2971 | static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
2972 | { | 2972 | { |
2973 | struct sock *sk = sock->sk; | 2973 | struct net *net = sock_net(sock->sk); |
2974 | struct tipc_sioc_nodeid_req nr = {0}; | ||
2974 | struct tipc_sioc_ln_req lnr; | 2975 | struct tipc_sioc_ln_req lnr; |
2975 | void __user *argp = (void __user *)arg; | 2976 | void __user *argp = (void __user *)arg; |
2976 | 2977 | ||
@@ -2978,7 +2979,7 @@ static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
2978 | case SIOCGETLINKNAME: | 2979 | case SIOCGETLINKNAME: |
2979 | if (copy_from_user(&lnr, argp, sizeof(lnr))) | 2980 | if (copy_from_user(&lnr, argp, sizeof(lnr))) |
2980 | return -EFAULT; | 2981 | return -EFAULT; |
2981 | if (!tipc_node_get_linkname(sock_net(sk), | 2982 | if (!tipc_node_get_linkname(net, |
2982 | lnr.bearer_id & 0xffff, lnr.peer, | 2983 | lnr.bearer_id & 0xffff, lnr.peer, |
2983 | lnr.linkname, TIPC_MAX_LINK_NAME)) { | 2984 | lnr.linkname, TIPC_MAX_LINK_NAME)) { |
2984 | if (copy_to_user(argp, &lnr, sizeof(lnr))) | 2985 | if (copy_to_user(argp, &lnr, sizeof(lnr))) |
@@ -2986,6 +2987,14 @@ static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
2986 | return 0; | 2987 | return 0; |
2987 | } | 2988 | } |
2988 | return -EADDRNOTAVAIL; | 2989 | return -EADDRNOTAVAIL; |
2990 | case SIOCGETNODEID: | ||
2991 | if (copy_from_user(&nr, argp, sizeof(nr))) | ||
2992 | return -EFAULT; | ||
2993 | if (!tipc_node_get_id(net, nr.peer, nr.node_id)) | ||
2994 | return -EADDRNOTAVAIL; | ||
2995 | if (copy_to_user(argp, &nr, sizeof(nr))) | ||
2996 | return -EFAULT; | ||
2997 | return 0; | ||
2989 | default: | 2998 | default: |
2990 | return -ENOIOCTLCMD; | 2999 | return -ENOIOCTLCMD; |
2991 | } | 3000 | } |
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index e7d91f5d5cae..9783101bc4a9 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c | |||
@@ -713,8 +713,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, | |||
713 | err = -EINVAL; | 713 | err = -EINVAL; |
714 | goto err; | 714 | goto err; |
715 | } | 715 | } |
716 | b->mtu = dev->mtu - sizeof(struct iphdr) | 716 | b->mtu = b->media->mtu; |
717 | - sizeof(struct udphdr); | ||
718 | #if IS_ENABLED(CONFIG_IPV6) | 717 | #if IS_ENABLED(CONFIG_IPV6) |
719 | } else if (local.proto == htons(ETH_P_IPV6)) { | 718 | } else if (local.proto == htons(ETH_P_IPV6)) { |
720 | udp_conf.family = AF_INET6; | 719 | udp_conf.family = AF_INET6; |
@@ -803,6 +802,7 @@ struct tipc_media udp_media_info = { | |||
803 | .priority = TIPC_DEF_LINK_PRI, | 802 | .priority = TIPC_DEF_LINK_PRI, |
804 | .tolerance = TIPC_DEF_LINK_TOL, | 803 | .tolerance = TIPC_DEF_LINK_TOL, |
805 | .window = TIPC_DEF_LINK_WIN, | 804 | .window = TIPC_DEF_LINK_WIN, |
805 | .mtu = TIPC_DEF_LINK_UDP_MTU, | ||
806 | .type_id = TIPC_MEDIA_TYPE_UDP, | 806 | .type_id = TIPC_MEDIA_TYPE_UDP, |
807 | .hwaddr_len = 0, | 807 | .hwaddr_len = 0, |
808 | .name = "udp" | 808 | .name = "udp" |
diff --git a/net/tipc/udp_media.h b/net/tipc/udp_media.h index 281bbae87726..e7455cc73e16 100644 --- a/net/tipc/udp_media.h +++ b/net/tipc/udp_media.h | |||
@@ -38,9 +38,23 @@ | |||
38 | #ifndef _TIPC_UDP_MEDIA_H | 38 | #ifndef _TIPC_UDP_MEDIA_H |
39 | #define _TIPC_UDP_MEDIA_H | 39 | #define _TIPC_UDP_MEDIA_H |
40 | 40 | ||
41 | #include <linux/ip.h> | ||
42 | #include <linux/udp.h> | ||
43 | |||
41 | int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr); | 44 | int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr); |
42 | int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b); | 45 | int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b); |
43 | int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb); | 46 | int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb); |
44 | 47 | ||
48 | /* check if configured MTU is too low for tipc headers */ | ||
49 | static inline bool tipc_udp_mtu_bad(u32 mtu) | ||
50 | { | ||
51 | if (mtu >= (TIPC_MIN_BEARER_MTU + sizeof(struct iphdr) + | ||
52 | sizeof(struct udphdr))) | ||
53 | return false; | ||
54 | |||
55 | pr_warn("MTU too low for tipc bearer\n"); | ||
56 | return true; | ||
57 | } | ||
58 | |||
45 | #endif | 59 | #endif |
46 | #endif | 60 | #endif |