0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <net/sock.h>
0038 #include "core.h"
0039 #include "bearer.h"
0040 #include "link.h"
0041 #include "discover.h"
0042 #include "monitor.h"
0043 #include "bcast.h"
0044 #include "netlink.h"
0045 #include "udp_media.h"
0046 #include "trace.h"
0047 #include "crypto.h"
0048
0049 #define MAX_ADDR_STR 60
0050
0051 static struct tipc_media * const media_info_array[] = {
0052 ð_media_info,
0053 #ifdef CONFIG_TIPC_MEDIA_IB
0054 &ib_media_info,
0055 #endif
0056 #ifdef CONFIG_TIPC_MEDIA_UDP
0057 &udp_media_info,
0058 #endif
0059 NULL
0060 };
0061
0062 static struct tipc_bearer *bearer_get(struct net *net, int bearer_id)
0063 {
0064 struct tipc_net *tn = tipc_net(net);
0065
0066 return rcu_dereference(tn->bearer_list[bearer_id]);
0067 }
0068
0069 static void bearer_disable(struct net *net, struct tipc_bearer *b);
0070 static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
0071 struct packet_type *pt, struct net_device *orig_dev);
0072
0073
0074
0075
0076
0077 struct tipc_media *tipc_media_find(const char *name)
0078 {
0079 u32 i;
0080
0081 for (i = 0; media_info_array[i] != NULL; i++) {
0082 if (!strcmp(media_info_array[i]->name, name))
0083 break;
0084 }
0085 return media_info_array[i];
0086 }
0087
0088
0089
0090
0091
0092 static struct tipc_media *media_find_id(u8 type)
0093 {
0094 u32 i;
0095
0096 for (i = 0; media_info_array[i] != NULL; i++) {
0097 if (media_info_array[i]->type_id == type)
0098 break;
0099 }
0100 return media_info_array[i];
0101 }
0102
0103
0104
0105
0106
0107
0108
0109 int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
0110 {
0111 char addr_str[MAX_ADDR_STR];
0112 struct tipc_media *m;
0113 int ret;
0114
0115 m = media_find_id(a->media_id);
0116
0117 if (m && !m->addr2str(a, addr_str, sizeof(addr_str)))
0118 ret = scnprintf(buf, len, "%s(%s)", m->name, addr_str);
0119 else {
0120 u32 i;
0121
0122 ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id);
0123 for (i = 0; i < sizeof(a->value); i++)
0124 ret += scnprintf(buf + ret, len - ret,
0125 "-%x", a->value[i]);
0126 }
0127 return ret;
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137 static int bearer_name_validate(const char *name,
0138 struct tipc_bearer_names *name_parts)
0139 {
0140 char name_copy[TIPC_MAX_BEARER_NAME];
0141 char *media_name;
0142 char *if_name;
0143 u32 media_len;
0144 u32 if_len;
0145
0146
0147 if (strscpy(name_copy, name, TIPC_MAX_BEARER_NAME) < 0)
0148 return 0;
0149
0150
0151 media_name = name_copy;
0152 if_name = strchr(media_name, ':');
0153 if (if_name == NULL)
0154 return 0;
0155 *(if_name++) = 0;
0156 media_len = if_name - media_name;
0157 if_len = strlen(if_name) + 1;
0158
0159
0160 if ((media_len <= 1) || (media_len > TIPC_MAX_MEDIA_NAME) ||
0161 (if_len <= 1) || (if_len > TIPC_MAX_IF_NAME))
0162 return 0;
0163
0164
0165 if (name_parts) {
0166 strcpy(name_parts->media_name, media_name);
0167 strcpy(name_parts->if_name, if_name);
0168 }
0169 return 1;
0170 }
0171
0172
0173
0174
0175
0176
0177 struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name)
0178 {
0179 struct tipc_net *tn = net_generic(net, tipc_net_id);
0180 struct tipc_bearer *b;
0181 u32 i;
0182
0183 for (i = 0; i < MAX_BEARERS; i++) {
0184 b = rtnl_dereference(tn->bearer_list[i]);
0185 if (b && (!strcmp(b->name, name)))
0186 return b;
0187 }
0188 return NULL;
0189 }
0190
0191
0192
0193
0194
0195
0196 int tipc_bearer_get_name(struct net *net, char *name, u32 bearer_id)
0197 {
0198 struct tipc_net *tn = tipc_net(net);
0199 struct tipc_bearer *b;
0200
0201 if (bearer_id >= MAX_BEARERS)
0202 return -EINVAL;
0203
0204 b = rtnl_dereference(tn->bearer_list[bearer_id]);
0205 if (!b)
0206 return -EINVAL;
0207
0208 strcpy(name, b->name);
0209 return 0;
0210 }
0211
0212 void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest)
0213 {
0214 struct tipc_net *tn = net_generic(net, tipc_net_id);
0215 struct tipc_bearer *b;
0216
0217 rcu_read_lock();
0218 b = rcu_dereference(tn->bearer_list[bearer_id]);
0219 if (b)
0220 tipc_disc_add_dest(b->disc);
0221 rcu_read_unlock();
0222 }
0223
0224 void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
0225 {
0226 struct tipc_net *tn = net_generic(net, tipc_net_id);
0227 struct tipc_bearer *b;
0228
0229 rcu_read_lock();
0230 b = rcu_dereference(tn->bearer_list[bearer_id]);
0231 if (b)
0232 tipc_disc_remove_dest(b->disc);
0233 rcu_read_unlock();
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 static int tipc_enable_bearer(struct net *net, const char *name,
0246 u32 disc_domain, u32 prio,
0247 struct nlattr *attr[],
0248 struct netlink_ext_ack *extack)
0249 {
0250 struct tipc_net *tn = tipc_net(net);
0251 struct tipc_bearer_names b_names;
0252 int with_this_prio = 1;
0253 struct tipc_bearer *b;
0254 struct tipc_media *m;
0255 struct sk_buff *skb;
0256 int bearer_id = 0;
0257 int res = -EINVAL;
0258 char *errstr = "";
0259 u32 i;
0260
0261 if (!bearer_name_validate(name, &b_names)) {
0262 NL_SET_ERR_MSG(extack, "Illegal name");
0263 return res;
0264 }
0265
0266 if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
0267 errstr = "illegal priority";
0268 NL_SET_ERR_MSG(extack, "Illegal priority");
0269 goto rejected;
0270 }
0271
0272 m = tipc_media_find(b_names.media_name);
0273 if (!m) {
0274 errstr = "media not registered";
0275 NL_SET_ERR_MSG(extack, "Media not registered");
0276 goto rejected;
0277 }
0278
0279 if (prio == TIPC_MEDIA_LINK_PRI)
0280 prio = m->priority;
0281
0282
0283 bearer_id = MAX_BEARERS;
0284 i = MAX_BEARERS;
0285 while (i-- != 0) {
0286 b = rtnl_dereference(tn->bearer_list[i]);
0287 if (!b) {
0288 bearer_id = i;
0289 continue;
0290 }
0291 if (!strcmp(name, b->name)) {
0292 errstr = "already enabled";
0293 NL_SET_ERR_MSG(extack, "Already enabled");
0294 goto rejected;
0295 }
0296
0297 if (b->priority == prio &&
0298 (++with_this_prio > 2)) {
0299 pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
0300 name, prio);
0301
0302 if (prio == TIPC_MIN_LINK_PRI) {
0303 errstr = "cannot adjust to lower";
0304 NL_SET_ERR_MSG(extack, "Cannot adjust to lower");
0305 goto rejected;
0306 }
0307
0308 pr_warn("Bearer <%s>: trying with adjusted priority\n",
0309 name);
0310 prio--;
0311 bearer_id = MAX_BEARERS;
0312 i = MAX_BEARERS;
0313 with_this_prio = 1;
0314 }
0315 }
0316
0317 if (bearer_id >= MAX_BEARERS) {
0318 errstr = "max 3 bearers permitted";
0319 NL_SET_ERR_MSG(extack, "Max 3 bearers permitted");
0320 goto rejected;
0321 }
0322
0323 b = kzalloc(sizeof(*b), GFP_ATOMIC);
0324 if (!b)
0325 return -ENOMEM;
0326
0327 strcpy(b->name, name);
0328 b->media = m;
0329 res = m->enable_media(net, b, attr);
0330 if (res) {
0331 kfree(b);
0332 errstr = "failed to enable media";
0333 NL_SET_ERR_MSG(extack, "Failed to enable media");
0334 goto rejected;
0335 }
0336
0337 b->identity = bearer_id;
0338 b->tolerance = m->tolerance;
0339 b->min_win = m->min_win;
0340 b->max_win = m->max_win;
0341 b->domain = disc_domain;
0342 b->net_plane = bearer_id + 'A';
0343 b->priority = prio;
0344 refcount_set(&b->refcnt, 1);
0345
0346 res = tipc_disc_create(net, b, &b->bcast_addr, &skb);
0347 if (res) {
0348 bearer_disable(net, b);
0349 errstr = "failed to create discoverer";
0350 NL_SET_ERR_MSG(extack, "Failed to create discoverer");
0351 goto rejected;
0352 }
0353
0354
0355 if (tipc_mon_create(net, bearer_id)) {
0356 bearer_disable(net, b);
0357 kfree_skb(skb);
0358 return -ENOMEM;
0359 }
0360
0361 test_and_set_bit_lock(0, &b->up);
0362 rcu_assign_pointer(tn->bearer_list[bearer_id], b);
0363 if (skb)
0364 tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr);
0365
0366 pr_info("Enabled bearer <%s>, priority %u\n", name, prio);
0367
0368 return res;
0369 rejected:
0370 pr_warn("Enabling of bearer <%s> rejected, %s\n", name, errstr);
0371 return res;
0372 }
0373
0374
0375
0376
0377
0378
0379 static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b)
0380 {
0381 pr_info("Resetting bearer <%s>\n", b->name);
0382 tipc_node_delete_links(net, b->identity);
0383 tipc_disc_reset(net, b);
0384 return 0;
0385 }
0386
0387 bool tipc_bearer_hold(struct tipc_bearer *b)
0388 {
0389 return (b && refcount_inc_not_zero(&b->refcnt));
0390 }
0391
0392 void tipc_bearer_put(struct tipc_bearer *b)
0393 {
0394 if (b && refcount_dec_and_test(&b->refcnt))
0395 kfree_rcu(b, rcu);
0396 }
0397
0398
0399
0400
0401
0402
0403
0404
0405 static void bearer_disable(struct net *net, struct tipc_bearer *b)
0406 {
0407 struct tipc_net *tn = tipc_net(net);
0408 int bearer_id = b->identity;
0409
0410 pr_info("Disabling bearer <%s>\n", b->name);
0411 clear_bit_unlock(0, &b->up);
0412 tipc_node_delete_links(net, bearer_id);
0413 b->media->disable_media(b);
0414 RCU_INIT_POINTER(b->media_ptr, NULL);
0415 if (b->disc)
0416 tipc_disc_delete(b->disc);
0417 RCU_INIT_POINTER(tn->bearer_list[bearer_id], NULL);
0418 tipc_bearer_put(b);
0419 tipc_mon_delete(net, bearer_id);
0420 }
0421
0422 int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
0423 struct nlattr *attr[])
0424 {
0425 char *dev_name = strchr((const char *)b->name, ':') + 1;
0426 int hwaddr_len = b->media->hwaddr_len;
0427 u8 node_id[NODE_ID_LEN] = {0,};
0428 struct net_device *dev;
0429
0430
0431 dev = dev_get_by_name(net, dev_name);
0432 if (!dev)
0433 return -ENODEV;
0434 if (tipc_mtu_bad(dev, 0)) {
0435 dev_put(dev);
0436 return -EINVAL;
0437 }
0438 if (dev == net->loopback_dev) {
0439 dev_put(dev);
0440 pr_info("Enabling <%s> not permitted\n", b->name);
0441 return -EINVAL;
0442 }
0443
0444
0445 if (!tipc_own_id(net) && hwaddr_len <= NODE_ID_LEN) {
0446 memcpy(node_id, dev->dev_addr, hwaddr_len);
0447 tipc_net_init(net, node_id, 0);
0448 }
0449 if (!tipc_own_id(net)) {
0450 dev_put(dev);
0451 pr_warn("Failed to obtain node identity\n");
0452 return -EINVAL;
0453 }
0454
0455
0456 rcu_assign_pointer(b->media_ptr, dev);
0457 b->pt.dev = dev;
0458 b->pt.type = htons(ETH_P_TIPC);
0459 b->pt.func = tipc_l2_rcv_msg;
0460 dev_add_pack(&b->pt);
0461 memset(&b->bcast_addr, 0, sizeof(b->bcast_addr));
0462 memcpy(b->bcast_addr.value, dev->broadcast, hwaddr_len);
0463 b->bcast_addr.media_id = b->media->type_id;
0464 b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
0465 b->mtu = dev->mtu;
0466 b->media->raw2addr(b, &b->addr, (const char *)dev->dev_addr);
0467 rcu_assign_pointer(dev->tipc_ptr, b);
0468 return 0;
0469 }
0470
0471
0472
0473
0474
0475
0476 void tipc_disable_l2_media(struct tipc_bearer *b)
0477 {
0478 struct net_device *dev;
0479
0480 dev = (struct net_device *)rtnl_dereference(b->media_ptr);
0481 dev_remove_pack(&b->pt);
0482 RCU_INIT_POINTER(dev->tipc_ptr, NULL);
0483 synchronize_net();
0484 dev_put(dev);
0485 }
0486
0487
0488
0489
0490
0491
0492
0493
0494 int tipc_l2_send_msg(struct net *net, struct sk_buff *skb,
0495 struct tipc_bearer *b, struct tipc_media_addr *dest)
0496 {
0497 struct net_device *dev;
0498 int delta;
0499
0500 dev = (struct net_device *)rcu_dereference(b->media_ptr);
0501 if (!dev)
0502 return 0;
0503
0504 delta = SKB_DATA_ALIGN(dev->hard_header_len - skb_headroom(skb));
0505 if ((delta > 0) && pskb_expand_head(skb, delta, 0, GFP_ATOMIC)) {
0506 kfree_skb(skb);
0507 return 0;
0508 }
0509 skb_reset_network_header(skb);
0510 skb->dev = dev;
0511 skb->protocol = htons(ETH_P_TIPC);
0512 dev_hard_header(skb, dev, ETH_P_TIPC, dest->value,
0513 dev->dev_addr, skb->len);
0514 dev_queue_xmit(skb);
0515 return 0;
0516 }
0517
0518 bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id)
0519 {
0520 bool supp = false;
0521 struct tipc_bearer *b;
0522
0523 rcu_read_lock();
0524 b = bearer_get(net, bearer_id);
0525 if (b)
0526 supp = (b->bcast_addr.broadcast == TIPC_BROADCAST_SUPPORT);
0527 rcu_read_unlock();
0528 return supp;
0529 }
0530
0531 int tipc_bearer_mtu(struct net *net, u32 bearer_id)
0532 {
0533 int mtu = 0;
0534 struct tipc_bearer *b;
0535
0536 rcu_read_lock();
0537 b = rcu_dereference(tipc_net(net)->bearer_list[bearer_id]);
0538 if (b)
0539 mtu = b->mtu;
0540 rcu_read_unlock();
0541 return mtu;
0542 }
0543
0544
0545
0546 void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
0547 struct sk_buff *skb,
0548 struct tipc_media_addr *dest)
0549 {
0550 struct tipc_msg *hdr = buf_msg(skb);
0551 struct tipc_bearer *b;
0552
0553 rcu_read_lock();
0554 b = bearer_get(net, bearer_id);
0555 if (likely(b && (test_bit(0, &b->up) || msg_is_reset(hdr)))) {
0556 #ifdef CONFIG_TIPC_CRYPTO
0557 tipc_crypto_xmit(net, &skb, b, dest, NULL);
0558 if (skb)
0559 #endif
0560 b->media->send_msg(net, skb, b, dest);
0561 } else {
0562 kfree_skb(skb);
0563 }
0564 rcu_read_unlock();
0565 }
0566
0567
0568
0569 void tipc_bearer_xmit(struct net *net, u32 bearer_id,
0570 struct sk_buff_head *xmitq,
0571 struct tipc_media_addr *dst,
0572 struct tipc_node *__dnode)
0573 {
0574 struct tipc_bearer *b;
0575 struct sk_buff *skb, *tmp;
0576
0577 if (skb_queue_empty(xmitq))
0578 return;
0579
0580 rcu_read_lock();
0581 b = bearer_get(net, bearer_id);
0582 if (unlikely(!b))
0583 __skb_queue_purge(xmitq);
0584 skb_queue_walk_safe(xmitq, skb, tmp) {
0585 __skb_dequeue(xmitq);
0586 if (likely(test_bit(0, &b->up) || msg_is_reset(buf_msg(skb)))) {
0587 #ifdef CONFIG_TIPC_CRYPTO
0588 tipc_crypto_xmit(net, &skb, b, dst, __dnode);
0589 if (skb)
0590 #endif
0591 b->media->send_msg(net, skb, b, dst);
0592 } else {
0593 kfree_skb(skb);
0594 }
0595 }
0596 rcu_read_unlock();
0597 }
0598
0599
0600
0601 void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
0602 struct sk_buff_head *xmitq)
0603 {
0604 struct tipc_net *tn = tipc_net(net);
0605 struct tipc_media_addr *dst;
0606 int net_id = tn->net_id;
0607 struct tipc_bearer *b;
0608 struct sk_buff *skb, *tmp;
0609 struct tipc_msg *hdr;
0610
0611 rcu_read_lock();
0612 b = bearer_get(net, bearer_id);
0613 if (unlikely(!b || !test_bit(0, &b->up)))
0614 __skb_queue_purge(xmitq);
0615 skb_queue_walk_safe(xmitq, skb, tmp) {
0616 hdr = buf_msg(skb);
0617 msg_set_non_seq(hdr, 1);
0618 msg_set_mc_netid(hdr, net_id);
0619 __skb_dequeue(xmitq);
0620 dst = &b->bcast_addr;
0621 #ifdef CONFIG_TIPC_CRYPTO
0622 tipc_crypto_xmit(net, &skb, b, dst, NULL);
0623 if (skb)
0624 #endif
0625 b->media->send_msg(net, skb, b, dst);
0626 }
0627 rcu_read_unlock();
0628 }
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641 static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
0642 struct packet_type *pt, struct net_device *orig_dev)
0643 {
0644 struct tipc_bearer *b;
0645
0646 rcu_read_lock();
0647 b = rcu_dereference(dev->tipc_ptr) ?:
0648 rcu_dereference(orig_dev->tipc_ptr);
0649 if (likely(b && test_bit(0, &b->up) &&
0650 (skb->pkt_type <= PACKET_MULTICAST))) {
0651 skb_mark_not_on_list(skb);
0652 TIPC_SKB_CB(skb)->flags = 0;
0653 tipc_rcv(dev_net(b->pt.dev), skb, b);
0654 rcu_read_unlock();
0655 return NET_RX_SUCCESS;
0656 }
0657 rcu_read_unlock();
0658 kfree_skb(skb);
0659 return NET_RX_DROP;
0660 }
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671 static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
0672 void *ptr)
0673 {
0674 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
0675 struct net *net = dev_net(dev);
0676 struct tipc_bearer *b;
0677
0678 b = rtnl_dereference(dev->tipc_ptr);
0679 if (!b)
0680 return NOTIFY_DONE;
0681
0682 trace_tipc_l2_device_event(dev, b, evt);
0683 switch (evt) {
0684 case NETDEV_CHANGE:
0685 if (netif_carrier_ok(dev) && netif_oper_up(dev)) {
0686 test_and_set_bit_lock(0, &b->up);
0687 break;
0688 }
0689 fallthrough;
0690 case NETDEV_GOING_DOWN:
0691 clear_bit_unlock(0, &b->up);
0692 tipc_reset_bearer(net, b);
0693 break;
0694 case NETDEV_UP:
0695 test_and_set_bit_lock(0, &b->up);
0696 break;
0697 case NETDEV_CHANGEMTU:
0698 if (tipc_mtu_bad(dev, 0)) {
0699 bearer_disable(net, b);
0700 break;
0701 }
0702 b->mtu = dev->mtu;
0703 tipc_reset_bearer(net, b);
0704 break;
0705 case NETDEV_CHANGEADDR:
0706 b->media->raw2addr(b, &b->addr,
0707 (const char *)dev->dev_addr);
0708 tipc_reset_bearer(net, b);
0709 break;
0710 case NETDEV_UNREGISTER:
0711 case NETDEV_CHANGENAME:
0712 bearer_disable(net, b);
0713 break;
0714 }
0715 return NOTIFY_OK;
0716 }
0717
0718 static struct notifier_block notifier = {
0719 .notifier_call = tipc_l2_device_event,
0720 .priority = 0,
0721 };
0722
0723 int tipc_bearer_setup(void)
0724 {
0725 return register_netdevice_notifier(¬ifier);
0726 }
0727
0728 void tipc_bearer_cleanup(void)
0729 {
0730 unregister_netdevice_notifier(¬ifier);
0731 }
0732
0733 void tipc_bearer_stop(struct net *net)
0734 {
0735 struct tipc_net *tn = net_generic(net, tipc_net_id);
0736 struct tipc_bearer *b;
0737 u32 i;
0738
0739 for (i = 0; i < MAX_BEARERS; i++) {
0740 b = rtnl_dereference(tn->bearer_list[i]);
0741 if (b) {
0742 bearer_disable(net, b);
0743 tn->bearer_list[i] = NULL;
0744 }
0745 }
0746 }
0747
0748 void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts)
0749 {
0750 struct net_device *dev = net->loopback_dev;
0751 struct sk_buff *skb, *_skb;
0752 int exp;
0753
0754 skb_queue_walk(pkts, _skb) {
0755 skb = pskb_copy(_skb, GFP_ATOMIC);
0756 if (!skb)
0757 continue;
0758
0759 exp = SKB_DATA_ALIGN(dev->hard_header_len - skb_headroom(skb));
0760 if (exp > 0 && pskb_expand_head(skb, exp, 0, GFP_ATOMIC)) {
0761 kfree_skb(skb);
0762 continue;
0763 }
0764
0765 skb_reset_network_header(skb);
0766 dev_hard_header(skb, dev, ETH_P_TIPC, dev->dev_addr,
0767 dev->dev_addr, skb->len);
0768 skb->dev = dev;
0769 skb->pkt_type = PACKET_HOST;
0770 skb->ip_summed = CHECKSUM_UNNECESSARY;
0771 skb->protocol = eth_type_trans(skb, dev);
0772 netif_rx(skb);
0773 }
0774 }
0775
0776 static int tipc_loopback_rcv_pkt(struct sk_buff *skb, struct net_device *dev,
0777 struct packet_type *pt, struct net_device *od)
0778 {
0779 consume_skb(skb);
0780 return NET_RX_SUCCESS;
0781 }
0782
0783 int tipc_attach_loopback(struct net *net)
0784 {
0785 struct net_device *dev = net->loopback_dev;
0786 struct tipc_net *tn = tipc_net(net);
0787
0788 if (!dev)
0789 return -ENODEV;
0790
0791 netdev_hold(dev, &tn->loopback_pt.dev_tracker, GFP_KERNEL);
0792 tn->loopback_pt.dev = dev;
0793 tn->loopback_pt.type = htons(ETH_P_TIPC);
0794 tn->loopback_pt.func = tipc_loopback_rcv_pkt;
0795 dev_add_pack(&tn->loopback_pt);
0796 return 0;
0797 }
0798
0799 void tipc_detach_loopback(struct net *net)
0800 {
0801 struct tipc_net *tn = tipc_net(net);
0802
0803 dev_remove_pack(&tn->loopback_pt);
0804 netdev_put(net->loopback_dev, &tn->loopback_pt.dev_tracker);
0805 }
0806
0807
0808 static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
0809 struct tipc_bearer *bearer, int nlflags)
0810 {
0811 void *hdr;
0812 struct nlattr *attrs;
0813 struct nlattr *prop;
0814
0815 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
0816 nlflags, TIPC_NL_BEARER_GET);
0817 if (!hdr)
0818 return -EMSGSIZE;
0819
0820 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER);
0821 if (!attrs)
0822 goto msg_full;
0823
0824 if (nla_put_string(msg->skb, TIPC_NLA_BEARER_NAME, bearer->name))
0825 goto attr_msg_full;
0826
0827 prop = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER_PROP);
0828 if (!prop)
0829 goto prop_msg_full;
0830 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, bearer->priority))
0831 goto prop_msg_full;
0832 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, bearer->tolerance))
0833 goto prop_msg_full;
0834 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->max_win))
0835 goto prop_msg_full;
0836 if (bearer->media->type_id == TIPC_MEDIA_TYPE_UDP)
0837 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_MTU, bearer->mtu))
0838 goto prop_msg_full;
0839
0840 nla_nest_end(msg->skb, prop);
0841
0842 #ifdef CONFIG_TIPC_MEDIA_UDP
0843 if (bearer->media->type_id == TIPC_MEDIA_TYPE_UDP) {
0844 if (tipc_udp_nl_add_bearer_data(msg, bearer))
0845 goto attr_msg_full;
0846 }
0847 #endif
0848
0849 nla_nest_end(msg->skb, attrs);
0850 genlmsg_end(msg->skb, hdr);
0851
0852 return 0;
0853
0854 prop_msg_full:
0855 nla_nest_cancel(msg->skb, prop);
0856 attr_msg_full:
0857 nla_nest_cancel(msg->skb, attrs);
0858 msg_full:
0859 genlmsg_cancel(msg->skb, hdr);
0860
0861 return -EMSGSIZE;
0862 }
0863
0864 int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb)
0865 {
0866 int err;
0867 int i = cb->args[0];
0868 struct tipc_bearer *bearer;
0869 struct tipc_nl_msg msg;
0870 struct net *net = sock_net(skb->sk);
0871 struct tipc_net *tn = net_generic(net, tipc_net_id);
0872
0873 if (i == MAX_BEARERS)
0874 return 0;
0875
0876 msg.skb = skb;
0877 msg.portid = NETLINK_CB(cb->skb).portid;
0878 msg.seq = cb->nlh->nlmsg_seq;
0879
0880 rtnl_lock();
0881 for (i = 0; i < MAX_BEARERS; i++) {
0882 bearer = rtnl_dereference(tn->bearer_list[i]);
0883 if (!bearer)
0884 continue;
0885
0886 err = __tipc_nl_add_bearer(&msg, bearer, NLM_F_MULTI);
0887 if (err)
0888 break;
0889 }
0890 rtnl_unlock();
0891
0892 cb->args[0] = i;
0893 return skb->len;
0894 }
0895
0896 int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
0897 {
0898 int err;
0899 char *name;
0900 struct sk_buff *rep;
0901 struct tipc_bearer *bearer;
0902 struct tipc_nl_msg msg;
0903 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
0904 struct net *net = genl_info_net(info);
0905
0906 if (!info->attrs[TIPC_NLA_BEARER])
0907 return -EINVAL;
0908
0909 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_BEARER_MAX,
0910 info->attrs[TIPC_NLA_BEARER],
0911 tipc_nl_bearer_policy, info->extack);
0912 if (err)
0913 return err;
0914
0915 if (!attrs[TIPC_NLA_BEARER_NAME])
0916 return -EINVAL;
0917 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
0918
0919 rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
0920 if (!rep)
0921 return -ENOMEM;
0922
0923 msg.skb = rep;
0924 msg.portid = info->snd_portid;
0925 msg.seq = info->snd_seq;
0926
0927 rtnl_lock();
0928 bearer = tipc_bearer_find(net, name);
0929 if (!bearer) {
0930 err = -EINVAL;
0931 NL_SET_ERR_MSG(info->extack, "Bearer not found");
0932 goto err_out;
0933 }
0934
0935 err = __tipc_nl_add_bearer(&msg, bearer, 0);
0936 if (err)
0937 goto err_out;
0938 rtnl_unlock();
0939
0940 return genlmsg_reply(rep, info);
0941 err_out:
0942 rtnl_unlock();
0943 nlmsg_free(rep);
0944
0945 return err;
0946 }
0947
0948 int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
0949 {
0950 int err;
0951 char *name;
0952 struct tipc_bearer *bearer;
0953 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
0954 struct net *net = sock_net(skb->sk);
0955
0956 if (!info->attrs[TIPC_NLA_BEARER])
0957 return -EINVAL;
0958
0959 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_BEARER_MAX,
0960 info->attrs[TIPC_NLA_BEARER],
0961 tipc_nl_bearer_policy, info->extack);
0962 if (err)
0963 return err;
0964
0965 if (!attrs[TIPC_NLA_BEARER_NAME])
0966 return -EINVAL;
0967
0968 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
0969
0970 bearer = tipc_bearer_find(net, name);
0971 if (!bearer) {
0972 NL_SET_ERR_MSG(info->extack, "Bearer not found");
0973 return -EINVAL;
0974 }
0975
0976 bearer_disable(net, bearer);
0977
0978 return 0;
0979 }
0980
0981 int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
0982 {
0983 int err;
0984
0985 rtnl_lock();
0986 err = __tipc_nl_bearer_disable(skb, info);
0987 rtnl_unlock();
0988
0989 return err;
0990 }
0991
0992 int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
0993 {
0994 int err;
0995 char *bearer;
0996 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
0997 struct net *net = sock_net(skb->sk);
0998 u32 domain = 0;
0999 u32 prio;
1000
1001 prio = TIPC_MEDIA_LINK_PRI;
1002
1003 if (!info->attrs[TIPC_NLA_BEARER])
1004 return -EINVAL;
1005
1006 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_BEARER_MAX,
1007 info->attrs[TIPC_NLA_BEARER],
1008 tipc_nl_bearer_policy, info->extack);
1009 if (err)
1010 return err;
1011
1012 if (!attrs[TIPC_NLA_BEARER_NAME])
1013 return -EINVAL;
1014
1015 bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
1016
1017 if (attrs[TIPC_NLA_BEARER_DOMAIN])
1018 domain = nla_get_u32(attrs[TIPC_NLA_BEARER_DOMAIN]);
1019
1020 if (attrs[TIPC_NLA_BEARER_PROP]) {
1021 struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
1022
1023 err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP],
1024 props);
1025 if (err)
1026 return err;
1027
1028 if (props[TIPC_NLA_PROP_PRIO])
1029 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1030 }
1031
1032 return tipc_enable_bearer(net, bearer, domain, prio, attrs,
1033 info->extack);
1034 }
1035
1036 int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
1037 {
1038 int err;
1039
1040 rtnl_lock();
1041 err = __tipc_nl_bearer_enable(skb, info);
1042 rtnl_unlock();
1043
1044 return err;
1045 }
1046
1047 int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info)
1048 {
1049 int err;
1050 char *name;
1051 struct tipc_bearer *b;
1052 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
1053 struct net *net = sock_net(skb->sk);
1054
1055 if (!info->attrs[TIPC_NLA_BEARER])
1056 return -EINVAL;
1057
1058 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_BEARER_MAX,
1059 info->attrs[TIPC_NLA_BEARER],
1060 tipc_nl_bearer_policy, info->extack);
1061 if (err)
1062 return err;
1063
1064 if (!attrs[TIPC_NLA_BEARER_NAME])
1065 return -EINVAL;
1066 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
1067
1068 rtnl_lock();
1069 b = tipc_bearer_find(net, name);
1070 if (!b) {
1071 rtnl_unlock();
1072 NL_SET_ERR_MSG(info->extack, "Bearer not found");
1073 return -EINVAL;
1074 }
1075
1076 #ifdef CONFIG_TIPC_MEDIA_UDP
1077 if (attrs[TIPC_NLA_BEARER_UDP_OPTS]) {
1078 err = tipc_udp_nl_bearer_add(b,
1079 attrs[TIPC_NLA_BEARER_UDP_OPTS]);
1080 if (err) {
1081 rtnl_unlock();
1082 return err;
1083 }
1084 }
1085 #endif
1086 rtnl_unlock();
1087
1088 return 0;
1089 }
1090
1091 int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
1092 {
1093 struct tipc_bearer *b;
1094 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
1095 struct net *net = sock_net(skb->sk);
1096 char *name;
1097 int err;
1098
1099 if (!info->attrs[TIPC_NLA_BEARER])
1100 return -EINVAL;
1101
1102 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_BEARER_MAX,
1103 info->attrs[TIPC_NLA_BEARER],
1104 tipc_nl_bearer_policy, info->extack);
1105 if (err)
1106 return err;
1107
1108 if (!attrs[TIPC_NLA_BEARER_NAME])
1109 return -EINVAL;
1110 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
1111
1112 b = tipc_bearer_find(net, name);
1113 if (!b) {
1114 NL_SET_ERR_MSG(info->extack, "Bearer not found");
1115 return -EINVAL;
1116 }
1117
1118 if (attrs[TIPC_NLA_BEARER_PROP]) {
1119 struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
1120
1121 err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP],
1122 props);
1123 if (err)
1124 return err;
1125
1126 if (props[TIPC_NLA_PROP_TOL]) {
1127 b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1128 tipc_node_apply_property(net, b, TIPC_NLA_PROP_TOL);
1129 }
1130 if (props[TIPC_NLA_PROP_PRIO])
1131 b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1132 if (props[TIPC_NLA_PROP_WIN])
1133 b->max_win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
1134 if (props[TIPC_NLA_PROP_MTU]) {
1135 if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) {
1136 NL_SET_ERR_MSG(info->extack,
1137 "MTU property is unsupported");
1138 return -EINVAL;
1139 }
1140 #ifdef CONFIG_TIPC_MEDIA_UDP
1141 if (tipc_udp_mtu_bad(nla_get_u32
1142 (props[TIPC_NLA_PROP_MTU]))) {
1143 NL_SET_ERR_MSG(info->extack,
1144 "MTU value is out-of-range");
1145 return -EINVAL;
1146 }
1147 b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]);
1148 tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU);
1149 #endif
1150 }
1151 }
1152
1153 return 0;
1154 }
1155
1156 int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
1157 {
1158 int err;
1159
1160 rtnl_lock();
1161 err = __tipc_nl_bearer_set(skb, info);
1162 rtnl_unlock();
1163
1164 return err;
1165 }
1166
1167 static int __tipc_nl_add_media(struct tipc_nl_msg *msg,
1168 struct tipc_media *media, int nlflags)
1169 {
1170 void *hdr;
1171 struct nlattr *attrs;
1172 struct nlattr *prop;
1173
1174 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
1175 nlflags, TIPC_NL_MEDIA_GET);
1176 if (!hdr)
1177 return -EMSGSIZE;
1178
1179 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MEDIA);
1180 if (!attrs)
1181 goto msg_full;
1182
1183 if (nla_put_string(msg->skb, TIPC_NLA_MEDIA_NAME, media->name))
1184 goto attr_msg_full;
1185
1186 prop = nla_nest_start_noflag(msg->skb, TIPC_NLA_MEDIA_PROP);
1187 if (!prop)
1188 goto prop_msg_full;
1189 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, media->priority))
1190 goto prop_msg_full;
1191 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, media->tolerance))
1192 goto prop_msg_full;
1193 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, media->max_win))
1194 goto prop_msg_full;
1195 if (media->type_id == TIPC_MEDIA_TYPE_UDP)
1196 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_MTU, media->mtu))
1197 goto prop_msg_full;
1198
1199 nla_nest_end(msg->skb, prop);
1200 nla_nest_end(msg->skb, attrs);
1201 genlmsg_end(msg->skb, hdr);
1202
1203 return 0;
1204
1205 prop_msg_full:
1206 nla_nest_cancel(msg->skb, prop);
1207 attr_msg_full:
1208 nla_nest_cancel(msg->skb, attrs);
1209 msg_full:
1210 genlmsg_cancel(msg->skb, hdr);
1211
1212 return -EMSGSIZE;
1213 }
1214
1215 int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb)
1216 {
1217 int err;
1218 int i = cb->args[0];
1219 struct tipc_nl_msg msg;
1220
1221 if (i == MAX_MEDIA)
1222 return 0;
1223
1224 msg.skb = skb;
1225 msg.portid = NETLINK_CB(cb->skb).portid;
1226 msg.seq = cb->nlh->nlmsg_seq;
1227
1228 rtnl_lock();
1229 for (; media_info_array[i] != NULL; i++) {
1230 err = __tipc_nl_add_media(&msg, media_info_array[i],
1231 NLM_F_MULTI);
1232 if (err)
1233 break;
1234 }
1235 rtnl_unlock();
1236
1237 cb->args[0] = i;
1238 return skb->len;
1239 }
1240
1241 int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info)
1242 {
1243 int err;
1244 char *name;
1245 struct tipc_nl_msg msg;
1246 struct tipc_media *media;
1247 struct sk_buff *rep;
1248 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
1249
1250 if (!info->attrs[TIPC_NLA_MEDIA])
1251 return -EINVAL;
1252
1253 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_MEDIA_MAX,
1254 info->attrs[TIPC_NLA_MEDIA],
1255 tipc_nl_media_policy, info->extack);
1256 if (err)
1257 return err;
1258
1259 if (!attrs[TIPC_NLA_MEDIA_NAME])
1260 return -EINVAL;
1261 name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
1262
1263 rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1264 if (!rep)
1265 return -ENOMEM;
1266
1267 msg.skb = rep;
1268 msg.portid = info->snd_portid;
1269 msg.seq = info->snd_seq;
1270
1271 rtnl_lock();
1272 media = tipc_media_find(name);
1273 if (!media) {
1274 NL_SET_ERR_MSG(info->extack, "Media not found");
1275 err = -EINVAL;
1276 goto err_out;
1277 }
1278
1279 err = __tipc_nl_add_media(&msg, media, 0);
1280 if (err)
1281 goto err_out;
1282 rtnl_unlock();
1283
1284 return genlmsg_reply(rep, info);
1285 err_out:
1286 rtnl_unlock();
1287 nlmsg_free(rep);
1288
1289 return err;
1290 }
1291
1292 int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
1293 {
1294 int err;
1295 char *name;
1296 struct tipc_media *m;
1297 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
1298
1299 if (!info->attrs[TIPC_NLA_MEDIA])
1300 return -EINVAL;
1301
1302 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_MEDIA_MAX,
1303 info->attrs[TIPC_NLA_MEDIA],
1304 tipc_nl_media_policy, info->extack);
1305
1306 if (!attrs[TIPC_NLA_MEDIA_NAME])
1307 return -EINVAL;
1308 name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
1309
1310 m = tipc_media_find(name);
1311 if (!m) {
1312 NL_SET_ERR_MSG(info->extack, "Media not found");
1313 return -EINVAL;
1314 }
1315 if (attrs[TIPC_NLA_MEDIA_PROP]) {
1316 struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
1317
1318 err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_MEDIA_PROP],
1319 props);
1320 if (err)
1321 return err;
1322
1323 if (props[TIPC_NLA_PROP_TOL])
1324 m->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1325 if (props[TIPC_NLA_PROP_PRIO])
1326 m->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1327 if (props[TIPC_NLA_PROP_WIN])
1328 m->max_win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
1329 if (props[TIPC_NLA_PROP_MTU]) {
1330 if (m->type_id != TIPC_MEDIA_TYPE_UDP) {
1331 NL_SET_ERR_MSG(info->extack,
1332 "MTU property is unsupported");
1333 return -EINVAL;
1334 }
1335 #ifdef CONFIG_TIPC_MEDIA_UDP
1336 if (tipc_udp_mtu_bad(nla_get_u32
1337 (props[TIPC_NLA_PROP_MTU]))) {
1338 NL_SET_ERR_MSG(info->extack,
1339 "MTU value is out-of-range");
1340 return -EINVAL;
1341 }
1342 m->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]);
1343 #endif
1344 }
1345 }
1346
1347 return 0;
1348 }
1349
1350 int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
1351 {
1352 int err;
1353
1354 rtnl_lock();
1355 err = __tipc_nl_media_set(skb, info);
1356 rtnl_unlock();
1357
1358 return err;
1359 }