cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bearer.c (33207B)


      1/*
      2 * net/tipc/bearer.c: TIPC bearer code
      3 *
      4 * Copyright (c) 1996-2006, 2013-2016, Ericsson AB
      5 * Copyright (c) 2004-2006, 2010-2013, Wind River Systems
      6 * All rights reserved.
      7 *
      8 * Redistribution and use in source and binary forms, with or without
      9 * modification, are permitted provided that the following conditions are met:
     10 *
     11 * 1. Redistributions of source code must retain the above copyright
     12 *    notice, this list of conditions and the following disclaimer.
     13 * 2. Redistributions in binary form must reproduce the above copyright
     14 *    notice, this list of conditions and the following disclaimer in the
     15 *    documentation and/or other materials provided with the distribution.
     16 * 3. Neither the names of the copyright holders nor the names of its
     17 *    contributors may be used to endorse or promote products derived from
     18 *    this software without specific prior written permission.
     19 *
     20 * Alternatively, this software may be distributed under the terms of the
     21 * GNU General Public License ("GPL") version 2 as published by the Free
     22 * Software Foundation.
     23 *
     24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     34 * POSSIBILITY OF SUCH DAMAGE.
     35 */
     36
     37#include <net/sock.h>
     38#include "core.h"
     39#include "bearer.h"
     40#include "link.h"
     41#include "discover.h"
     42#include "monitor.h"
     43#include "bcast.h"
     44#include "netlink.h"
     45#include "udp_media.h"
     46#include "trace.h"
     47#include "crypto.h"
     48
     49#define MAX_ADDR_STR 60
     50
     51static struct tipc_media * const media_info_array[] = {
     52	&eth_media_info,
     53#ifdef CONFIG_TIPC_MEDIA_IB
     54	&ib_media_info,
     55#endif
     56#ifdef CONFIG_TIPC_MEDIA_UDP
     57	&udp_media_info,
     58#endif
     59	NULL
     60};
     61
     62static struct tipc_bearer *bearer_get(struct net *net, int bearer_id)
     63{
     64	struct tipc_net *tn = tipc_net(net);
     65
     66	return rcu_dereference(tn->bearer_list[bearer_id]);
     67}
     68
     69static void bearer_disable(struct net *net, struct tipc_bearer *b);
     70static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
     71			   struct packet_type *pt, struct net_device *orig_dev);
     72
     73/**
     74 * tipc_media_find - locates specified media object by name
     75 * @name: name to locate
     76 */
     77struct tipc_media *tipc_media_find(const char *name)
     78{
     79	u32 i;
     80
     81	for (i = 0; media_info_array[i] != NULL; i++) {
     82		if (!strcmp(media_info_array[i]->name, name))
     83			break;
     84	}
     85	return media_info_array[i];
     86}
     87
     88/**
     89 * media_find_id - locates specified media object by type identifier
     90 * @type: type identifier to locate
     91 */
     92static struct tipc_media *media_find_id(u8 type)
     93{
     94	u32 i;
     95
     96	for (i = 0; media_info_array[i] != NULL; i++) {
     97		if (media_info_array[i]->type_id == type)
     98			break;
     99	}
    100	return media_info_array[i];
    101}
    102
    103/**
    104 * tipc_media_addr_printf - record media address in print buffer
    105 * @buf: output buffer
    106 * @len: output buffer size remaining
    107 * @a: input media address
    108 */
    109int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
    110{
    111	char addr_str[MAX_ADDR_STR];
    112	struct tipc_media *m;
    113	int ret;
    114
    115	m = media_find_id(a->media_id);
    116
    117	if (m && !m->addr2str(a, addr_str, sizeof(addr_str)))
    118		ret = scnprintf(buf, len, "%s(%s)", m->name, addr_str);
    119	else {
    120		u32 i;
    121
    122		ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id);
    123		for (i = 0; i < sizeof(a->value); i++)
    124			ret += scnprintf(buf + ret, len - ret,
    125					    "-%x", a->value[i]);
    126	}
    127	return ret;
    128}
    129
    130/**
    131 * bearer_name_validate - validate & (optionally) deconstruct bearer name
    132 * @name: ptr to bearer name string
    133 * @name_parts: ptr to area for bearer name components (or NULL if not needed)
    134 *
    135 * Return: 1 if bearer name is valid, otherwise 0.
    136 */
    137static int bearer_name_validate(const char *name,
    138				struct tipc_bearer_names *name_parts)
    139{
    140	char name_copy[TIPC_MAX_BEARER_NAME];
    141	char *media_name;
    142	char *if_name;
    143	u32 media_len;
    144	u32 if_len;
    145
    146	/* copy bearer name & ensure length is OK */
    147	if (strscpy(name_copy, name, TIPC_MAX_BEARER_NAME) < 0)
    148		return 0;
    149
    150	/* ensure all component parts of bearer name are present */
    151	media_name = name_copy;
    152	if_name = strchr(media_name, ':');
    153	if (if_name == NULL)
    154		return 0;
    155	*(if_name++) = 0;
    156	media_len = if_name - media_name;
    157	if_len = strlen(if_name) + 1;
    158
    159	/* validate component parts of bearer name */
    160	if ((media_len <= 1) || (media_len > TIPC_MAX_MEDIA_NAME) ||
    161	    (if_len <= 1) || (if_len > TIPC_MAX_IF_NAME))
    162		return 0;
    163
    164	/* return bearer name components, if necessary */
    165	if (name_parts) {
    166		strcpy(name_parts->media_name, media_name);
    167		strcpy(name_parts->if_name, if_name);
    168	}
    169	return 1;
    170}
    171
    172/**
    173 * tipc_bearer_find - locates bearer object with matching bearer name
    174 * @net: the applicable net namespace
    175 * @name: bearer name to locate
    176 */
    177struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name)
    178{
    179	struct tipc_net *tn = net_generic(net, tipc_net_id);
    180	struct tipc_bearer *b;
    181	u32 i;
    182
    183	for (i = 0; i < MAX_BEARERS; i++) {
    184		b = rtnl_dereference(tn->bearer_list[i]);
    185		if (b && (!strcmp(b->name, name)))
    186			return b;
    187	}
    188	return NULL;
    189}
    190
    191/*     tipc_bearer_get_name - get the bearer name from its id.
    192 *     @net: network namespace
    193 *     @name: a pointer to the buffer where the name will be stored.
    194 *     @bearer_id: the id to get the name from.
    195 */
    196int tipc_bearer_get_name(struct net *net, char *name, u32 bearer_id)
    197{
    198	struct tipc_net *tn = tipc_net(net);
    199	struct tipc_bearer *b;
    200
    201	if (bearer_id >= MAX_BEARERS)
    202		return -EINVAL;
    203
    204	b = rtnl_dereference(tn->bearer_list[bearer_id]);
    205	if (!b)
    206		return -EINVAL;
    207
    208	strcpy(name, b->name);
    209	return 0;
    210}
    211
    212void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest)
    213{
    214	struct tipc_net *tn = net_generic(net, tipc_net_id);
    215	struct tipc_bearer *b;
    216
    217	rcu_read_lock();
    218	b = rcu_dereference(tn->bearer_list[bearer_id]);
    219	if (b)
    220		tipc_disc_add_dest(b->disc);
    221	rcu_read_unlock();
    222}
    223
    224void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
    225{
    226	struct tipc_net *tn = net_generic(net, tipc_net_id);
    227	struct tipc_bearer *b;
    228
    229	rcu_read_lock();
    230	b = rcu_dereference(tn->bearer_list[bearer_id]);
    231	if (b)
    232		tipc_disc_remove_dest(b->disc);
    233	rcu_read_unlock();
    234}
    235
    236/**
    237 * tipc_enable_bearer - enable bearer with the given name
    238 * @net: the applicable net namespace
    239 * @name: bearer name to enable
    240 * @disc_domain: bearer domain
    241 * @prio: bearer priority
    242 * @attr: nlattr array
    243 * @extack: netlink extended ack
    244 */
    245static int tipc_enable_bearer(struct net *net, const char *name,
    246			      u32 disc_domain, u32 prio,
    247			      struct nlattr *attr[],
    248			      struct netlink_ext_ack *extack)
    249{
    250	struct tipc_net *tn = tipc_net(net);
    251	struct tipc_bearer_names b_names;
    252	int with_this_prio = 1;
    253	struct tipc_bearer *b;
    254	struct tipc_media *m;
    255	struct sk_buff *skb;
    256	int bearer_id = 0;
    257	int res = -EINVAL;
    258	char *errstr = "";
    259	u32 i;
    260
    261	if (!bearer_name_validate(name, &b_names)) {
    262		NL_SET_ERR_MSG(extack, "Illegal name");
    263		return res;
    264	}
    265
    266	if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
    267		errstr = "illegal priority";
    268		NL_SET_ERR_MSG(extack, "Illegal priority");
    269		goto rejected;
    270	}
    271
    272	m = tipc_media_find(b_names.media_name);
    273	if (!m) {
    274		errstr = "media not registered";
    275		NL_SET_ERR_MSG(extack, "Media not registered");
    276		goto rejected;
    277	}
    278
    279	if (prio == TIPC_MEDIA_LINK_PRI)
    280		prio = m->priority;
    281
    282	/* Check new bearer vs existing ones and find free bearer id if any */
    283	bearer_id = MAX_BEARERS;
    284	i = MAX_BEARERS;
    285	while (i-- != 0) {
    286		b = rtnl_dereference(tn->bearer_list[i]);
    287		if (!b) {
    288			bearer_id = i;
    289			continue;
    290		}
    291		if (!strcmp(name, b->name)) {
    292			errstr = "already enabled";
    293			NL_SET_ERR_MSG(extack, "Already enabled");
    294			goto rejected;
    295		}
    296
    297		if (b->priority == prio &&
    298		    (++with_this_prio > 2)) {
    299			pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
    300				name, prio);
    301
    302			if (prio == TIPC_MIN_LINK_PRI) {
    303				errstr = "cannot adjust to lower";
    304				NL_SET_ERR_MSG(extack, "Cannot adjust to lower");
    305				goto rejected;
    306			}
    307
    308			pr_warn("Bearer <%s>: trying with adjusted priority\n",
    309				name);
    310			prio--;
    311			bearer_id = MAX_BEARERS;
    312			i = MAX_BEARERS;
    313			with_this_prio = 1;
    314		}
    315	}
    316
    317	if (bearer_id >= MAX_BEARERS) {
    318		errstr = "max 3 bearers permitted";
    319		NL_SET_ERR_MSG(extack, "Max 3 bearers permitted");
    320		goto rejected;
    321	}
    322
    323	b = kzalloc(sizeof(*b), GFP_ATOMIC);
    324	if (!b)
    325		return -ENOMEM;
    326
    327	strcpy(b->name, name);
    328	b->media = m;
    329	res = m->enable_media(net, b, attr);
    330	if (res) {
    331		kfree(b);
    332		errstr = "failed to enable media";
    333		NL_SET_ERR_MSG(extack, "Failed to enable media");
    334		goto rejected;
    335	}
    336
    337	b->identity = bearer_id;
    338	b->tolerance = m->tolerance;
    339	b->min_win = m->min_win;
    340	b->max_win = m->max_win;
    341	b->domain = disc_domain;
    342	b->net_plane = bearer_id + 'A';
    343	b->priority = prio;
    344	refcount_set(&b->refcnt, 1);
    345
    346	res = tipc_disc_create(net, b, &b->bcast_addr, &skb);
    347	if (res) {
    348		bearer_disable(net, b);
    349		errstr = "failed to create discoverer";
    350		NL_SET_ERR_MSG(extack, "Failed to create discoverer");
    351		goto rejected;
    352	}
    353
    354	/* Create monitoring data before accepting activate messages */
    355	if (tipc_mon_create(net, bearer_id)) {
    356		bearer_disable(net, b);
    357		kfree_skb(skb);
    358		return -ENOMEM;
    359	}
    360
    361	test_and_set_bit_lock(0, &b->up);
    362	rcu_assign_pointer(tn->bearer_list[bearer_id], b);
    363	if (skb)
    364		tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr);
    365
    366	pr_info("Enabled bearer <%s>, priority %u\n", name, prio);
    367
    368	return res;
    369rejected:
    370	pr_warn("Enabling of bearer <%s> rejected, %s\n", name, errstr);
    371	return res;
    372}
    373
    374/**
    375 * tipc_reset_bearer - Reset all links established over this bearer
    376 * @net: the applicable net namespace
    377 * @b: the target bearer
    378 */
    379static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b)
    380{
    381	pr_info("Resetting bearer <%s>\n", b->name);
    382	tipc_node_delete_links(net, b->identity);
    383	tipc_disc_reset(net, b);
    384	return 0;
    385}
    386
    387bool tipc_bearer_hold(struct tipc_bearer *b)
    388{
    389	return (b && refcount_inc_not_zero(&b->refcnt));
    390}
    391
    392void tipc_bearer_put(struct tipc_bearer *b)
    393{
    394	if (b && refcount_dec_and_test(&b->refcnt))
    395		kfree_rcu(b, rcu);
    396}
    397
    398/**
    399 * bearer_disable - disable this bearer
    400 * @net: the applicable net namespace
    401 * @b: the bearer to disable
    402 *
    403 * Note: This routine assumes caller holds RTNL lock.
    404 */
    405static void bearer_disable(struct net *net, struct tipc_bearer *b)
    406{
    407	struct tipc_net *tn = tipc_net(net);
    408	int bearer_id = b->identity;
    409
    410	pr_info("Disabling bearer <%s>\n", b->name);
    411	clear_bit_unlock(0, &b->up);
    412	tipc_node_delete_links(net, bearer_id);
    413	b->media->disable_media(b);
    414	RCU_INIT_POINTER(b->media_ptr, NULL);
    415	if (b->disc)
    416		tipc_disc_delete(b->disc);
    417	RCU_INIT_POINTER(tn->bearer_list[bearer_id], NULL);
    418	tipc_bearer_put(b);
    419	tipc_mon_delete(net, bearer_id);
    420}
    421
    422int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
    423			 struct nlattr *attr[])
    424{
    425	char *dev_name = strchr((const char *)b->name, ':') + 1;
    426	int hwaddr_len = b->media->hwaddr_len;
    427	u8 node_id[NODE_ID_LEN] = {0,};
    428	struct net_device *dev;
    429
    430	/* Find device with specified name */
    431	dev = dev_get_by_name(net, dev_name);
    432	if (!dev)
    433		return -ENODEV;
    434	if (tipc_mtu_bad(dev, 0)) {
    435		dev_put(dev);
    436		return -EINVAL;
    437	}
    438	if (dev == net->loopback_dev) {
    439		dev_put(dev);
    440		pr_info("Enabling <%s> not permitted\n", b->name);
    441		return -EINVAL;
    442	}
    443
    444	/* Autoconfigure own node identity if needed */
    445	if (!tipc_own_id(net) && hwaddr_len <= NODE_ID_LEN) {
    446		memcpy(node_id, dev->dev_addr, hwaddr_len);
    447		tipc_net_init(net, node_id, 0);
    448	}
    449	if (!tipc_own_id(net)) {
    450		dev_put(dev);
    451		pr_warn("Failed to obtain node identity\n");
    452		return -EINVAL;
    453	}
    454
    455	/* Associate TIPC bearer with L2 bearer */
    456	rcu_assign_pointer(b->media_ptr, dev);
    457	b->pt.dev = dev;
    458	b->pt.type = htons(ETH_P_TIPC);
    459	b->pt.func = tipc_l2_rcv_msg;
    460	dev_add_pack(&b->pt);
    461	memset(&b->bcast_addr, 0, sizeof(b->bcast_addr));
    462	memcpy(b->bcast_addr.value, dev->broadcast, hwaddr_len);
    463	b->bcast_addr.media_id = b->media->type_id;
    464	b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
    465	b->mtu = dev->mtu;
    466	b->media->raw2addr(b, &b->addr, (const char *)dev->dev_addr);
    467	rcu_assign_pointer(dev->tipc_ptr, b);
    468	return 0;
    469}
    470
    471/* tipc_disable_l2_media - detach TIPC bearer from an L2 interface
    472 * @b: the target bearer
    473 *
    474 * Mark L2 bearer as inactive so that incoming buffers are thrown away
    475 */
    476void tipc_disable_l2_media(struct tipc_bearer *b)
    477{
    478	struct net_device *dev;
    479
    480	dev = (struct net_device *)rtnl_dereference(b->media_ptr);
    481	dev_remove_pack(&b->pt);
    482	RCU_INIT_POINTER(dev->tipc_ptr, NULL);
    483	synchronize_net();
    484	dev_put(dev);
    485}
    486
    487/**
    488 * tipc_l2_send_msg - send a TIPC packet out over an L2 interface
    489 * @net: the associated network namespace
    490 * @skb: the packet to be sent
    491 * @b: the bearer through which the packet is to be sent
    492 * @dest: peer destination address
    493 */
    494int tipc_l2_send_msg(struct net *net, struct sk_buff *skb,
    495		     struct tipc_bearer *b, struct tipc_media_addr *dest)
    496{
    497	struct net_device *dev;
    498	int delta;
    499
    500	dev = (struct net_device *)rcu_dereference(b->media_ptr);
    501	if (!dev)
    502		return 0;
    503
    504	delta = SKB_DATA_ALIGN(dev->hard_header_len - skb_headroom(skb));
    505	if ((delta > 0) && pskb_expand_head(skb, delta, 0, GFP_ATOMIC)) {
    506		kfree_skb(skb);
    507		return 0;
    508	}
    509	skb_reset_network_header(skb);
    510	skb->dev = dev;
    511	skb->protocol = htons(ETH_P_TIPC);
    512	dev_hard_header(skb, dev, ETH_P_TIPC, dest->value,
    513			dev->dev_addr, skb->len);
    514	dev_queue_xmit(skb);
    515	return 0;
    516}
    517
    518bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id)
    519{
    520	bool supp = false;
    521	struct tipc_bearer *b;
    522
    523	rcu_read_lock();
    524	b = bearer_get(net, bearer_id);
    525	if (b)
    526		supp = (b->bcast_addr.broadcast == TIPC_BROADCAST_SUPPORT);
    527	rcu_read_unlock();
    528	return supp;
    529}
    530
    531int tipc_bearer_mtu(struct net *net, u32 bearer_id)
    532{
    533	int mtu = 0;
    534	struct tipc_bearer *b;
    535
    536	rcu_read_lock();
    537	b = rcu_dereference(tipc_net(net)->bearer_list[bearer_id]);
    538	if (b)
    539		mtu = b->mtu;
    540	rcu_read_unlock();
    541	return mtu;
    542}
    543
    544/* tipc_bearer_xmit_skb - sends buffer to destination over bearer
    545 */
    546void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
    547			  struct sk_buff *skb,
    548			  struct tipc_media_addr *dest)
    549{
    550	struct tipc_msg *hdr = buf_msg(skb);
    551	struct tipc_bearer *b;
    552
    553	rcu_read_lock();
    554	b = bearer_get(net, bearer_id);
    555	if (likely(b && (test_bit(0, &b->up) || msg_is_reset(hdr)))) {
    556#ifdef CONFIG_TIPC_CRYPTO
    557		tipc_crypto_xmit(net, &skb, b, dest, NULL);
    558		if (skb)
    559#endif
    560			b->media->send_msg(net, skb, b, dest);
    561	} else {
    562		kfree_skb(skb);
    563	}
    564	rcu_read_unlock();
    565}
    566
    567/* tipc_bearer_xmit() -send buffer to destination over bearer
    568 */
    569void tipc_bearer_xmit(struct net *net, u32 bearer_id,
    570		      struct sk_buff_head *xmitq,
    571		      struct tipc_media_addr *dst,
    572		      struct tipc_node *__dnode)
    573{
    574	struct tipc_bearer *b;
    575	struct sk_buff *skb, *tmp;
    576
    577	if (skb_queue_empty(xmitq))
    578		return;
    579
    580	rcu_read_lock();
    581	b = bearer_get(net, bearer_id);
    582	if (unlikely(!b))
    583		__skb_queue_purge(xmitq);
    584	skb_queue_walk_safe(xmitq, skb, tmp) {
    585		__skb_dequeue(xmitq);
    586		if (likely(test_bit(0, &b->up) || msg_is_reset(buf_msg(skb)))) {
    587#ifdef CONFIG_TIPC_CRYPTO
    588			tipc_crypto_xmit(net, &skb, b, dst, __dnode);
    589			if (skb)
    590#endif
    591				b->media->send_msg(net, skb, b, dst);
    592		} else {
    593			kfree_skb(skb);
    594		}
    595	}
    596	rcu_read_unlock();
    597}
    598
    599/* tipc_bearer_bc_xmit() - broadcast buffers to all destinations
    600 */
    601void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
    602			 struct sk_buff_head *xmitq)
    603{
    604	struct tipc_net *tn = tipc_net(net);
    605	struct tipc_media_addr *dst;
    606	int net_id = tn->net_id;
    607	struct tipc_bearer *b;
    608	struct sk_buff *skb, *tmp;
    609	struct tipc_msg *hdr;
    610
    611	rcu_read_lock();
    612	b = bearer_get(net, bearer_id);
    613	if (unlikely(!b || !test_bit(0, &b->up)))
    614		__skb_queue_purge(xmitq);
    615	skb_queue_walk_safe(xmitq, skb, tmp) {
    616		hdr = buf_msg(skb);
    617		msg_set_non_seq(hdr, 1);
    618		msg_set_mc_netid(hdr, net_id);
    619		__skb_dequeue(xmitq);
    620		dst = &b->bcast_addr;
    621#ifdef CONFIG_TIPC_CRYPTO
    622		tipc_crypto_xmit(net, &skb, b, dst, NULL);
    623		if (skb)
    624#endif
    625			b->media->send_msg(net, skb, b, dst);
    626	}
    627	rcu_read_unlock();
    628}
    629
    630/**
    631 * tipc_l2_rcv_msg - handle incoming TIPC message from an interface
    632 * @skb: the received message
    633 * @dev: the net device that the packet was received on
    634 * @pt: the packet_type structure which was used to register this handler
    635 * @orig_dev: the original receive net device in case the device is a bond
    636 *
    637 * Accept only packets explicitly sent to this node, or broadcast packets;
    638 * ignores packets sent using interface multicast, and traffic sent to other
    639 * nodes (which can happen if interface is running in promiscuous mode).
    640 */
    641static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
    642			   struct packet_type *pt, struct net_device *orig_dev)
    643{
    644	struct tipc_bearer *b;
    645
    646	rcu_read_lock();
    647	b = rcu_dereference(dev->tipc_ptr) ?:
    648		rcu_dereference(orig_dev->tipc_ptr);
    649	if (likely(b && test_bit(0, &b->up) &&
    650		   (skb->pkt_type <= PACKET_MULTICAST))) {
    651		skb_mark_not_on_list(skb);
    652		TIPC_SKB_CB(skb)->flags = 0;
    653		tipc_rcv(dev_net(b->pt.dev), skb, b);
    654		rcu_read_unlock();
    655		return NET_RX_SUCCESS;
    656	}
    657	rcu_read_unlock();
    658	kfree_skb(skb);
    659	return NET_RX_DROP;
    660}
    661
    662/**
    663 * tipc_l2_device_event - handle device events from network device
    664 * @nb: the context of the notification
    665 * @evt: the type of event
    666 * @ptr: the net device that the event was on
    667 *
    668 * This function is called by the Ethernet driver in case of link
    669 * change event.
    670 */
    671static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
    672				void *ptr)
    673{
    674	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
    675	struct net *net = dev_net(dev);
    676	struct tipc_bearer *b;
    677
    678	b = rtnl_dereference(dev->tipc_ptr);
    679	if (!b)
    680		return NOTIFY_DONE;
    681
    682	trace_tipc_l2_device_event(dev, b, evt);
    683	switch (evt) {
    684	case NETDEV_CHANGE:
    685		if (netif_carrier_ok(dev) && netif_oper_up(dev)) {
    686			test_and_set_bit_lock(0, &b->up);
    687			break;
    688		}
    689		fallthrough;
    690	case NETDEV_GOING_DOWN:
    691		clear_bit_unlock(0, &b->up);
    692		tipc_reset_bearer(net, b);
    693		break;
    694	case NETDEV_UP:
    695		test_and_set_bit_lock(0, &b->up);
    696		break;
    697	case NETDEV_CHANGEMTU:
    698		if (tipc_mtu_bad(dev, 0)) {
    699			bearer_disable(net, b);
    700			break;
    701		}
    702		b->mtu = dev->mtu;
    703		tipc_reset_bearer(net, b);
    704		break;
    705	case NETDEV_CHANGEADDR:
    706		b->media->raw2addr(b, &b->addr,
    707				   (const char *)dev->dev_addr);
    708		tipc_reset_bearer(net, b);
    709		break;
    710	case NETDEV_UNREGISTER:
    711	case NETDEV_CHANGENAME:
    712		bearer_disable(net, b);
    713		break;
    714	}
    715	return NOTIFY_OK;
    716}
    717
    718static struct notifier_block notifier = {
    719	.notifier_call  = tipc_l2_device_event,
    720	.priority	= 0,
    721};
    722
    723int tipc_bearer_setup(void)
    724{
    725	return register_netdevice_notifier(&notifier);
    726}
    727
    728void tipc_bearer_cleanup(void)
    729{
    730	unregister_netdevice_notifier(&notifier);
    731}
    732
    733void tipc_bearer_stop(struct net *net)
    734{
    735	struct tipc_net *tn = net_generic(net, tipc_net_id);
    736	struct tipc_bearer *b;
    737	u32 i;
    738
    739	for (i = 0; i < MAX_BEARERS; i++) {
    740		b = rtnl_dereference(tn->bearer_list[i]);
    741		if (b) {
    742			bearer_disable(net, b);
    743			tn->bearer_list[i] = NULL;
    744		}
    745	}
    746}
    747
    748void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts)
    749{
    750	struct net_device *dev = net->loopback_dev;
    751	struct sk_buff *skb, *_skb;
    752	int exp;
    753
    754	skb_queue_walk(pkts, _skb) {
    755		skb = pskb_copy(_skb, GFP_ATOMIC);
    756		if (!skb)
    757			continue;
    758
    759		exp = SKB_DATA_ALIGN(dev->hard_header_len - skb_headroom(skb));
    760		if (exp > 0 && pskb_expand_head(skb, exp, 0, GFP_ATOMIC)) {
    761			kfree_skb(skb);
    762			continue;
    763		}
    764
    765		skb_reset_network_header(skb);
    766		dev_hard_header(skb, dev, ETH_P_TIPC, dev->dev_addr,
    767				dev->dev_addr, skb->len);
    768		skb->dev = dev;
    769		skb->pkt_type = PACKET_HOST;
    770		skb->ip_summed = CHECKSUM_UNNECESSARY;
    771		skb->protocol = eth_type_trans(skb, dev);
    772		netif_rx(skb);
    773	}
    774}
    775
    776static int tipc_loopback_rcv_pkt(struct sk_buff *skb, struct net_device *dev,
    777				 struct packet_type *pt, struct net_device *od)
    778{
    779	consume_skb(skb);
    780	return NET_RX_SUCCESS;
    781}
    782
    783int tipc_attach_loopback(struct net *net)
    784{
    785	struct net_device *dev = net->loopback_dev;
    786	struct tipc_net *tn = tipc_net(net);
    787
    788	if (!dev)
    789		return -ENODEV;
    790
    791	dev_hold_track(dev, &tn->loopback_pt.dev_tracker, GFP_KERNEL);
    792	tn->loopback_pt.dev = dev;
    793	tn->loopback_pt.type = htons(ETH_P_TIPC);
    794	tn->loopback_pt.func = tipc_loopback_rcv_pkt;
    795	dev_add_pack(&tn->loopback_pt);
    796	return 0;
    797}
    798
    799void tipc_detach_loopback(struct net *net)
    800{
    801	struct tipc_net *tn = tipc_net(net);
    802
    803	dev_remove_pack(&tn->loopback_pt);
    804	dev_put_track(net->loopback_dev, &tn->loopback_pt.dev_tracker);
    805}
    806
    807/* Caller should hold rtnl_lock to protect the bearer */
    808static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
    809				struct tipc_bearer *bearer, int nlflags)
    810{
    811	void *hdr;
    812	struct nlattr *attrs;
    813	struct nlattr *prop;
    814
    815	hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
    816			  nlflags, TIPC_NL_BEARER_GET);
    817	if (!hdr)
    818		return -EMSGSIZE;
    819
    820	attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER);
    821	if (!attrs)
    822		goto msg_full;
    823
    824	if (nla_put_string(msg->skb, TIPC_NLA_BEARER_NAME, bearer->name))
    825		goto attr_msg_full;
    826
    827	prop = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER_PROP);
    828	if (!prop)
    829		goto prop_msg_full;
    830	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, bearer->priority))
    831		goto prop_msg_full;
    832	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, bearer->tolerance))
    833		goto prop_msg_full;
    834	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->max_win))
    835		goto prop_msg_full;
    836	if (bearer->media->type_id == TIPC_MEDIA_TYPE_UDP)
    837		if (nla_put_u32(msg->skb, TIPC_NLA_PROP_MTU, bearer->mtu))
    838			goto prop_msg_full;
    839
    840	nla_nest_end(msg->skb, prop);
    841
    842#ifdef CONFIG_TIPC_MEDIA_UDP
    843	if (bearer->media->type_id == TIPC_MEDIA_TYPE_UDP) {
    844		if (tipc_udp_nl_add_bearer_data(msg, bearer))
    845			goto attr_msg_full;
    846	}
    847#endif
    848
    849	nla_nest_end(msg->skb, attrs);
    850	genlmsg_end(msg->skb, hdr);
    851
    852	return 0;
    853
    854prop_msg_full:
    855	nla_nest_cancel(msg->skb, prop);
    856attr_msg_full:
    857	nla_nest_cancel(msg->skb, attrs);
    858msg_full:
    859	genlmsg_cancel(msg->skb, hdr);
    860
    861	return -EMSGSIZE;
    862}
    863
    864int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb)
    865{
    866	int err;
    867	int i = cb->args[0];
    868	struct tipc_bearer *bearer;
    869	struct tipc_nl_msg msg;
    870	struct net *net = sock_net(skb->sk);
    871	struct tipc_net *tn = net_generic(net, tipc_net_id);
    872
    873	if (i == MAX_BEARERS)
    874		return 0;
    875
    876	msg.skb = skb;
    877	msg.portid = NETLINK_CB(cb->skb).portid;
    878	msg.seq = cb->nlh->nlmsg_seq;
    879
    880	rtnl_lock();
    881	for (i = 0; i < MAX_BEARERS; i++) {
    882		bearer = rtnl_dereference(tn->bearer_list[i]);
    883		if (!bearer)
    884			continue;
    885
    886		err = __tipc_nl_add_bearer(&msg, bearer, NLM_F_MULTI);
    887		if (err)
    888			break;
    889	}
    890	rtnl_unlock();
    891
    892	cb->args[0] = i;
    893	return skb->len;
    894}
    895
    896int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
    897{
    898	int err;
    899	char *name;
    900	struct sk_buff *rep;
    901	struct tipc_bearer *bearer;
    902	struct tipc_nl_msg msg;
    903	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
    904	struct net *net = genl_info_net(info);
    905
    906	if (!info->attrs[TIPC_NLA_BEARER])
    907		return -EINVAL;
    908
    909	err = nla_parse_nested_deprecated(attrs, TIPC_NLA_BEARER_MAX,
    910					  info->attrs[TIPC_NLA_BEARER],
    911					  tipc_nl_bearer_policy, info->extack);
    912	if (err)
    913		return err;
    914
    915	if (!attrs[TIPC_NLA_BEARER_NAME])
    916		return -EINVAL;
    917	name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
    918
    919	rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
    920	if (!rep)
    921		return -ENOMEM;
    922
    923	msg.skb = rep;
    924	msg.portid = info->snd_portid;
    925	msg.seq = info->snd_seq;
    926
    927	rtnl_lock();
    928	bearer = tipc_bearer_find(net, name);
    929	if (!bearer) {
    930		err = -EINVAL;
    931		NL_SET_ERR_MSG(info->extack, "Bearer not found");
    932		goto err_out;
    933	}
    934
    935	err = __tipc_nl_add_bearer(&msg, bearer, 0);
    936	if (err)
    937		goto err_out;
    938	rtnl_unlock();
    939
    940	return genlmsg_reply(rep, info);
    941err_out:
    942	rtnl_unlock();
    943	nlmsg_free(rep);
    944
    945	return err;
    946}
    947
    948int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
    949{
    950	int err;
    951	char *name;
    952	struct tipc_bearer *bearer;
    953	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
    954	struct net *net = sock_net(skb->sk);
    955
    956	if (!info->attrs[TIPC_NLA_BEARER])
    957		return -EINVAL;
    958
    959	err = nla_parse_nested_deprecated(attrs, TIPC_NLA_BEARER_MAX,
    960					  info->attrs[TIPC_NLA_BEARER],
    961					  tipc_nl_bearer_policy, info->extack);
    962	if (err)
    963		return err;
    964
    965	if (!attrs[TIPC_NLA_BEARER_NAME])
    966		return -EINVAL;
    967
    968	name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
    969
    970	bearer = tipc_bearer_find(net, name);
    971	if (!bearer) {
    972		NL_SET_ERR_MSG(info->extack, "Bearer not found");
    973		return -EINVAL;
    974	}
    975
    976	bearer_disable(net, bearer);
    977
    978	return 0;
    979}
    980
    981int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
    982{
    983	int err;
    984
    985	rtnl_lock();
    986	err = __tipc_nl_bearer_disable(skb, info);
    987	rtnl_unlock();
    988
    989	return err;
    990}
    991
    992int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
    993{
    994	int err;
    995	char *bearer;
    996	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
    997	struct net *net = sock_net(skb->sk);
    998	u32 domain = 0;
    999	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
   1036int 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
   1047int 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
   1091int __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
   1156int 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
   1167static 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
   1205prop_msg_full:
   1206	nla_nest_cancel(msg->skb, prop);
   1207attr_msg_full:
   1208	nla_nest_cancel(msg->skb, attrs);
   1209msg_full:
   1210	genlmsg_cancel(msg->skb, hdr);
   1211
   1212	return -EMSGSIZE;
   1213}
   1214
   1215int 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
   1241int 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);
   1285err_out:
   1286	rtnl_unlock();
   1287	nlmsg_free(rep);
   1288
   1289	return err;
   1290}
   1291
   1292int __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
   1350int 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}