Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * net/tipc/net.c: TIPC network routing code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 1995-2006, 2014, Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2005, 2010-2011, 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 "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include "net.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include "name_distr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include "subscr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include "socket.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include "node.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 "monitor.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * The TIPC locking policy is designed to ensure a very fine locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * granularity, permitting complete parallel access to individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * port and node/link instances. The code consists of four major
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * locking domains, each protected with their own disjunct set of locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * 1: The bearer level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *    RTNL lock is used to serialize the process of configuring bearer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *    on update side, and RCU lock is applied on read side to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *    bearer instance valid on both paths of message transmission and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *    reception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * 2: The node and link level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *    All node instances are saved into two tipc_node_list and node_htable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  *    lists. The two lists are protected by node_list_lock on write side,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *    and they are guarded with RCU lock on read side. Especially node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *    instance is destroyed only when TIPC module is removed, and we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *    confirm that there has no any user who is accessing the node at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *    moment. Therefore, Except for iterating the two lists within RCU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *    protection, it's no needed to hold RCU that we access node instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  *    in other places.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *    In addition, all members in node structure including link instances
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *    are protected by node spin lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * 3: The transport level of the protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *    This consists of the structures port, (and its user level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  *    representations, such as user_port and tipc_sock), reference and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  *    tipc_user (port.c, reg.c, socket.c).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *    This layer has four different locks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *     - The tipc_port spin_lock. This is protecting each port instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  *       from parallel data access and removal. Since we can not place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *       this lock in the port itself, it has been placed in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *       corresponding reference table entry, which has the same life
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *       cycle as the module. This entry is difficult to access from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *       outside the TIPC core, however, so a pointer to the lock has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *       been added in the port instance, -to be used for unlocking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *       only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *     - A read/write lock to protect the reference table itself (teg.c).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *       (Nobody is using read-only access to this, so it can just as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *       well be changed to a spin_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *     - A spin lock to protect the registry of kernel/driver users (reg.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *     - A global spin_lock (tipc_port_lock), which only task is to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *       consistency where more than one port is involved in an operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  *       i.e., whe a port is part of a linked list of ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *       There are two such lists; 'port_list', which is used for management,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *       and 'wait_list', which is used to queue ports during congestion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  *  4: The name table (name_table.c, name_distr.c, subscription.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *     - There is one big read/write-lock (tipc_nametbl_lock) protecting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  *       overall name table structure. Nothing must be added/removed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  *       this structure without holding write access to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  *     - There is one local spin_lock per sub_sequence, which can be seen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  *       as a sub-domain to the tipc_nametbl_lock domain. It is used only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  *       for translation operations, and is needed because a translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *       steps the root of the 'publication' linked list between each lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  *       This is always used within the scope of a tipc_nametbl_lock(read).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  *     - A local spin_lock protecting the queue of subscriber events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void tipc_net_finalize(struct net *net, u32 addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (tipc_own_id(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		pr_info("Cannot configure node identity twice\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	pr_info("Started in network mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (node_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		tipc_set_node_id(net, node_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if (addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		tipc_net_finalize(net, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	return 0;
^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) static void tipc_net_finalize(struct net *net, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (cmpxchg(&tn->node_addr, 0, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	tipc_set_node_addr(net, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	tipc_named_reinit(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	tipc_sk_reinit(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	tipc_mon_reinit_self(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			     TIPC_CLUSTER_SCOPE, 0, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) void tipc_net_finalize_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct tipc_net_work *fwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	fwork = container_of(work, struct tipc_net_work, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	tipc_net_finalize(fwork->net, fwork->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) void tipc_sched_net_finalize(struct net *net, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	tn->final_work.net = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	tn->final_work.addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	schedule_work(&tn->final_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) void tipc_net_stop(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (!tipc_own_id(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	tipc_bearer_stop(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	tipc_node_stop(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	pr_info("Left network mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	struct tipc_net *tn = net_generic(net, tipc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	u64 *w0 = (u64 *)&tn->node_id[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	u64 *w1 = (u64 *)&tn->node_id[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	struct nlattr *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			  NLM_F_MULTI, TIPC_NL_NET_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_NET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tn->net_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID, *w0, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID_W1, *w1, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	nla_nest_end(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	genlmsg_end(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) attr_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	nla_nest_cancel(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	genlmsg_cancel(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	int done = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	struct tipc_nl_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	msg.skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	msg.portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	msg.seq = cb->nlh->nlmsg_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	err = __tipc_nl_add_net(net, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	cb->args[0] = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	if (!info->attrs[TIPC_NLA_NET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	err = nla_parse_nested_deprecated(attrs, TIPC_NLA_NET_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 					  info->attrs[TIPC_NLA_NET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 					  tipc_nl_net_policy, info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	/* Can't change net id once TIPC has joined a network */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (tipc_own_addr(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (attrs[TIPC_NLA_NET_ID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		val = nla_get_u32(attrs[TIPC_NLA_NET_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		if (val < 1 || val > 9999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		tn->net_id = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	if (attrs[TIPC_NLA_NET_ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		if (!addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		tn->legacy_addr_format = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		tipc_net_init(net, NULL, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (attrs[TIPC_NLA_NET_NODEID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		u8 node_id[NODE_ID_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		u64 *w0 = (u64 *)&node_id[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		u64 *w1 = (u64 *)&node_id[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		if (!attrs[TIPC_NLA_NET_NODEID_W1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		*w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		*w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		tipc_net_init(net, node_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	err = __tipc_nl_net_set(skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static int __tipc_nl_addr_legacy_get(struct net *net, struct tipc_nl_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	struct nlattr *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			  0, TIPC_NL_ADDR_LEGACY_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	attrs = nla_nest_start(msg->skb, TIPC_NLA_NET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (tn->legacy_addr_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		if (nla_put_flag(msg->skb, TIPC_NLA_NET_ADDR_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	nla_nest_end(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	genlmsg_end(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) attr_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	nla_nest_cancel(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	genlmsg_cancel(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	return -EMSGSIZE;
^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) int tipc_nl_net_addr_legacy_get(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	struct tipc_nl_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	struct sk_buff *rep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (!rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	msg.skb = rep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	msg.portid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	msg.seq = info->snd_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	err = __tipc_nl_addr_legacy_get(net, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		nlmsg_free(msg.skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	return genlmsg_reply(msg.skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }