Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * net/tipc/bearer.c: TIPC bearer code
0003  *
0004  * Copyright (c) 1996-2006, 2013-2016, Ericsson AB
0005  * Copyright (c) 2004-2006, 2010-2013, Wind River Systems
0006  * All rights reserved.
0007  *
0008  * Redistribution and use in source and binary forms, with or without
0009  * modification, are permitted provided that the following conditions are met:
0010  *
0011  * 1. Redistributions of source code must retain the above copyright
0012  *    notice, this list of conditions and the following disclaimer.
0013  * 2. Redistributions in binary form must reproduce the above copyright
0014  *    notice, this list of conditions and the following disclaimer in the
0015  *    documentation and/or other materials provided with the distribution.
0016  * 3. Neither the names of the copyright holders nor the names of its
0017  *    contributors may be used to endorse or promote products derived from
0018  *    this software without specific prior written permission.
0019  *
0020  * Alternatively, this software may be distributed under the terms of the
0021  * GNU General Public License ("GPL") version 2 as published by the Free
0022  * Software Foundation.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
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     &eth_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  * tipc_media_find - locates specified media object by name
0075  * @name: name to locate
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  * media_find_id - locates specified media object by type identifier
0090  * @type: type identifier to locate
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  * tipc_media_addr_printf - record media address in print buffer
0105  * @buf: output buffer
0106  * @len: output buffer size remaining
0107  * @a: input media address
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  * bearer_name_validate - validate & (optionally) deconstruct bearer name
0132  * @name: ptr to bearer name string
0133  * @name_parts: ptr to area for bearer name components (or NULL if not needed)
0134  *
0135  * Return: 1 if bearer name is valid, otherwise 0.
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     /* copy bearer name & ensure length is OK */
0147     if (strscpy(name_copy, name, TIPC_MAX_BEARER_NAME) < 0)
0148         return 0;
0149 
0150     /* ensure all component parts of bearer name are present */
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     /* validate component parts of bearer name */
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     /* return bearer name components, if necessary */
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  * tipc_bearer_find - locates bearer object with matching bearer name
0174  * @net: the applicable net namespace
0175  * @name: bearer name to locate
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 /*     tipc_bearer_get_name - get the bearer name from its id.
0192  *     @net: network namespace
0193  *     @name: a pointer to the buffer where the name will be stored.
0194  *     @bearer_id: the id to get the name from.
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  * tipc_enable_bearer - enable bearer with the given name
0238  * @net: the applicable net namespace
0239  * @name: bearer name to enable
0240  * @disc_domain: bearer domain
0241  * @prio: bearer priority
0242  * @attr: nlattr array
0243  * @extack: netlink extended ack
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     /* Check new bearer vs existing ones and find free bearer id if any */
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     /* Create monitoring data before accepting activate messages */
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  * tipc_reset_bearer - Reset all links established over this bearer
0376  * @net: the applicable net namespace
0377  * @b: the target bearer
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  * bearer_disable - disable this bearer
0400  * @net: the applicable net namespace
0401  * @b: the bearer to disable
0402  *
0403  * Note: This routine assumes caller holds RTNL lock.
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     /* Find device with specified name */
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     /* Autoconfigure own node identity if needed */
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     /* Associate TIPC bearer with L2 bearer */
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 /* tipc_disable_l2_media - detach TIPC bearer from an L2 interface
0472  * @b: the target bearer
0473  *
0474  * Mark L2 bearer as inactive so that incoming buffers are thrown away
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  * tipc_l2_send_msg - send a TIPC packet out over an L2 interface
0489  * @net: the associated network namespace
0490  * @skb: the packet to be sent
0491  * @b: the bearer through which the packet is to be sent
0492  * @dest: peer destination address
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 /* tipc_bearer_xmit_skb - sends buffer to destination over bearer
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 /* tipc_bearer_xmit() -send buffer to destination over bearer
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 /* tipc_bearer_bc_xmit() - broadcast buffers to all destinations
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  * tipc_l2_rcv_msg - handle incoming TIPC message from an interface
0632  * @skb: the received message
0633  * @dev: the net device that the packet was received on
0634  * @pt: the packet_type structure which was used to register this handler
0635  * @orig_dev: the original receive net device in case the device is a bond
0636  *
0637  * Accept only packets explicitly sent to this node, or broadcast packets;
0638  * ignores packets sent using interface multicast, and traffic sent to other
0639  * nodes (which can happen if interface is running in promiscuous mode).
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  * tipc_l2_device_event - handle device events from network device
0664  * @nb: the context of the notification
0665  * @evt: the type of event
0666  * @ptr: the net device that the event was on
0667  *
0668  * This function is called by the Ethernet driver in case of link
0669  * change event.
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(&notifier);
0726 }
0727 
0728 void tipc_bearer_cleanup(void)
0729 {
0730     unregister_netdevice_notifier(&notifier);
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 /* Caller should hold rtnl_lock to protect the bearer */
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 }