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