^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) }