^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* net/tipc/udp_media.c: IP bearer support for TIPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2015, Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * modification, are permitted provided that the following conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * 3. Neither the names of the copyright holders nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * contributors may be used to endorse or promote products derived from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * GNU General Public License ("GPL") version 2 as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * 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 32) * POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/inetdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/igmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <net/udp_tunnel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <net/ipv6_stubs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/tipc_netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "addr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "net.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "bearer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "msg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "udp_media.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* IANA assigned UDP port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define UDP_PORT_DEFAULT 6118
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define UDP_MIN_HEADROOM 48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * struct udp_media_addr - IP/UDP addressing information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * This is the bearer level originating address used in neighbor discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * messages, and all fields should be in network byte order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct udp_media_addr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) __be16 proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) __be16 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct in_addr ipv4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct in6_addr ipv6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* struct udp_replicast - container for UDP remote addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct udp_replicast {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct udp_media_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct dst_cache dst_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * struct udp_bearer - ip/udp bearer data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @bearer: associated generic tipc bearer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @ubsock: bearer associated socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @ifindex: local address scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @work: used to schedule deferred work on a bearer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct udp_bearer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct tipc_bearer __rcu *bearer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct socket *ubsock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct work_struct work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct udp_replicast rcast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int tipc_udp_is_mcast_addr(struct udp_media_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (ntohs(addr->proto) == ETH_P_IP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return ipv4_is_multicast(addr->ipv4.s_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return ipv6_addr_is_multicast(&addr->ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* udp_media_addr_set - convert a ip/udp address to a TIPC media address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void tipc_udp_media_addr_set(struct tipc_media_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct udp_media_addr *ua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) memset(addr, 0, sizeof(struct tipc_media_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) addr->media_id = TIPC_MEDIA_TYPE_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) memcpy(addr->value, ua, sizeof(struct udp_media_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (tipc_udp_is_mcast_addr(ua))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) addr->broadcast = TIPC_BROADCAST_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* tipc_udp_addr2str - convert ip/udp address to string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct udp_media_addr *ua = (struct udp_media_addr *)&a->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ntohs(ua->proto) == ETH_P_IP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) else if (ntohs(ua->proto) == ETH_P_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) pr_err("Invalid UDP media address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* tipc_udp_msg2addr - extract an ip/udp address from a TIPC ndisc message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int tipc_udp_msg2addr(struct tipc_bearer *b, struct tipc_media_addr *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct udp_media_addr *ua;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ua = (struct udp_media_addr *) (msg + TIPC_MEDIA_ADDR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (msg[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) tipc_udp_media_addr_set(a, ua);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* tipc_udp_addr2msg - write an ip/udp address to a TIPC ndisc message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) memset(msg, 0, TIPC_MEDIA_INFO_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) memcpy(msg + TIPC_MEDIA_ADDR_OFFSET, a->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) sizeof(struct udp_media_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* tipc_send_msg - enqueue a send request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct udp_bearer *ub, struct udp_media_addr *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct udp_media_addr *dst, struct dst_cache *cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct dst_entry *ndst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int ttl, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ndst = dst_cache_get(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (dst->proto == htons(ETH_P_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct rtable *rt = (struct rtable *)ndst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (!rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct flowi4 fl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .daddr = dst->ipv4.s_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .saddr = src->ipv4.s_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .flowi4_mark = skb->mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .flowi4_proto = IPPROTO_UDP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) rt = ip_route_output_key(net, &fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (IS_ERR(rt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) err = PTR_ERR(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto tx_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ttl = ip4_dst_hoplimit(&rt->dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dst->ipv4.s_addr, 0, ttl, 0, src->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dst->port, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!ndst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct flowi6 fl6 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .flowi6_oif = ub->ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .daddr = dst->ipv6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .saddr = src->ipv6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .flowi6_proto = IPPROTO_UDP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ndst = ipv6_stub->ipv6_dst_lookup_flow(net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ub->ubsock->sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) &fl6, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (IS_ERR(ndst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) err = PTR_ERR(ndst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto tx_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dst_cache_set_ip6(cache, ndst, &fl6.saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ttl = ip6_dst_hoplimit(ndst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) &src->ipv6, &dst->ipv6, 0, ttl, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) src->port, dst->port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) tx_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct tipc_bearer *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct tipc_media_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct udp_media_addr *dst = (struct udp_media_addr *)&addr->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct udp_replicast *rcast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ub = rcu_dereference(b->media_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!ub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return tipc_udp_xmit(net, skb, ub, src, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) &ub->rcast.dst_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Replicast, send an skb to each configured IP address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) list_for_each_entry_rcu(rcast, &ub->rcast.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct sk_buff *_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) _skb = pskb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) &rcast->dst_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct udp_media_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct udp_replicast *rcast, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ub = rcu_dereference_rtnl(b->media_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!ub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) pr_err_ratelimited("UDP bearer instance not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return false;
^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) list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!memcmp(&rcast->addr, addr, sizeof(struct udp_media_addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int tipc_udp_rcast_add(struct tipc_bearer *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct udp_media_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct udp_replicast *rcast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ub = rcu_dereference_rtnl(b->media_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!ub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) rcast = kmalloc(sizeof(*rcast), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!rcast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) kfree(rcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (ntohs(addr->proto) == ETH_P_IP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) pr_info("New replicast peer: %pI4\n", &rcast->addr.ipv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) else if (ntohs(addr->proto) == ETH_P_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) list_add_rcu(&rcast->list, &ub->rcast.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int tipc_udp_rcast_disc(struct tipc_bearer *b, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct udp_media_addr src = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct udp_media_addr *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dst = (struct udp_media_addr *)&b->bcast_addr.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (tipc_udp_is_mcast_addr(dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) src.port = udp_hdr(skb)->source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (ip_hdr(skb)->version == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct iphdr *iphdr = ip_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) src.proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) src.ipv4.s_addr = iphdr->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ipv4_is_multicast(iphdr->daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) } else if (ip_hdr(skb)->version == 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct ipv6hdr *iphdr = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) src.proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) src.ipv6 = iphdr->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (ipv6_addr_is_multicast(&iphdr->daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (likely(tipc_udp_is_known_peer(b, &src)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return tipc_udp_rcast_add(b, &src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* tipc_udp_recv - read data from bearer socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct tipc_bearer *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ub = rcu_dereference_sk_user_data(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!ub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) pr_err_ratelimited("Failed to get UDP bearer reference");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) skb_pull(skb, sizeof(struct udphdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) b = rcu_dereference(ub->bearer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (b && test_bit(0, &b->up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) TIPC_SKB_CB(skb)->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) tipc_rcv(sock_net(sk), skb, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return 0;
^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) if (unlikely(msg_user(hdr) == LINK_CONFIG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) err = tipc_udp_rcast_disc(b, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct ip_mreqn mreqn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct sock *sk = ub->ubsock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ntohs(remote->proto) == ETH_P_IP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) mreqn.imr_multiaddr = remote->ipv4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) mreqn.imr_ifindex = ub->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) err = ip_mc_join_group(sk, &mreqn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) err = ipv6_stub->ipv6_sock_mc_join(sk, ub->ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) &remote->ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static int __tipc_nl_add_udp_addr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct udp_media_addr *addr, int nla_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (ntohs(addr->proto) == ETH_P_IP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct sockaddr_in ip4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) memset(&ip4, 0, sizeof(ip4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ip4.sin_family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ip4.sin_port = addr->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ip4.sin_addr.s_addr = addr->ipv4.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (nla_put(skb, nla_t, sizeof(ip4), &ip4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) } else if (ntohs(addr->proto) == ETH_P_IPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct sockaddr_in6 ip6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) memset(&ip6, 0, sizeof(ip6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ip6.sin6_family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ip6.sin6_port = addr->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) memcpy(&ip6.sin6_addr, &addr->ipv6, sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (nla_put(skb, nla_t, sizeof(ip6), &ip6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u32 bid = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) u32 skip_cnt = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) u32 portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct udp_replicast *rcast, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct tipc_bearer *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (!bid && !skip_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct nlattr **attrs = genl_dumpit_info(cb)->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct nlattr *battrs[TIPC_NLA_BEARER_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) char *bname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (!attrs[TIPC_NLA_BEARER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) err = nla_parse_nested_deprecated(battrs, TIPC_NLA_BEARER_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) attrs[TIPC_NLA_BEARER],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) tipc_nl_bearer_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!battrs[TIPC_NLA_BEARER_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) bname = nla_data(battrs[TIPC_NLA_BEARER_NAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) b = tipc_bearer_find(net, bname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (!b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) bid = b->identity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct tipc_net *tn = net_generic(net, tipc_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) b = rtnl_dereference(tn->bearer_list[bid]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ub = rtnl_dereference(b->media_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!ub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (i < skip_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) goto count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) hdr = genlmsg_put(skb, portid, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) &tipc_genl_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) TIPC_NL_BEARER_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) err = __tipc_nl_add_udp_addr(skb, &rcast->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) TIPC_NLA_UDP_REMOTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) count:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) cb->args[0] = bid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) cb->args[1] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct udp_media_addr *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ub = rtnl_dereference(b->media_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (!ub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) nest = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER_UDP_OPTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!nest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (__tipc_nl_add_udp_addr(msg->skb, src, TIPC_NLA_UDP_LOCAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dst = (struct udp_media_addr *)&b->bcast_addr.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (__tipc_nl_add_udp_addr(msg->skb, dst, TIPC_NLA_UDP_REMOTE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!list_empty(&ub->rcast.list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (nla_put_flag(msg->skb, TIPC_NLA_UDP_MULTI_REMOTEIP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) nla_nest_end(msg->skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) nla_nest_cancel(msg->skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * tipc_parse_udp_addr - build udp media address from netlink data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * @nla: netlink attribute containing sockaddr storage aligned address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * @addr: tipc media address to fill with address, port and protocol type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * @scope_id: IPv6 scope id pointer, not NULL indicates it's required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static int tipc_parse_udp_addr(struct nlattr *nla, struct udp_media_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u32 *scope_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct sockaddr_storage sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) nla_memcpy(&sa, nla, sizeof(sa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (sa.ss_family == AF_INET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct sockaddr_in *ip4 = (struct sockaddr_in *)&sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) addr->proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) addr->port = ip4->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) addr->ipv4.s_addr = ip4->sin_addr.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) } else if (sa.ss_family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)&sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) addr->proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) addr->port = ip6->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) memcpy(&addr->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Scope ID is only interesting for local addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (scope_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) int atype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) atype = ipv6_addr_type(&ip6->sin6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (__ipv6_addr_needs_scope_id(atype) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) !ip6->sin6_scope_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) *scope_id = ip6->sin6_scope_id ? : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return -EADDRNOTAVAIL;
^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) int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct udp_media_addr addr = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct udp_media_addr *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attr, tipc_nl_udp_policy, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (!opts[TIPC_NLA_UDP_REMOTE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_REMOTE], &addr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dst = (struct udp_media_addr *)&b->bcast_addr.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (tipc_udp_is_mcast_addr(dst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) pr_err("Can't add remote ip to TIPC UDP multicast bearer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (tipc_udp_is_known_peer(b, &addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return tipc_udp_rcast_add(b, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * tipc_udp_enable - callback to create a new udp bearer instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * @net: network namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * @b: pointer to generic tipc_bearer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * @attrs: netlink bearer configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * validate the bearer parameters and initialize the udp bearer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * rtnl_lock should be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct nlattr *attrs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct udp_media_addr remote = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct udp_media_addr local = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct udp_port_cfg udp_conf = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct udp_tunnel_sock_cfg tuncfg = {NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) u8 node_id[NODE_ID_LEN] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int rmcast = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) ub = kzalloc(sizeof(*ub), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (!ub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) INIT_LIST_HEAD(&ub->rcast.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attrs[TIPC_NLA_BEARER_UDP_OPTS], tipc_nl_udp_policy, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (!opts[TIPC_NLA_UDP_LOCAL] || !opts[TIPC_NLA_UDP_REMOTE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) pr_err("Invalid UDP bearer configuration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_LOCAL], &local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) &ub->ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_REMOTE], &remote, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (remote.proto != local.proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* Checking remote ip address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) rmcast = tipc_udp_is_mcast_addr(&remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* Autoconfigure own node identity if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!tipc_own_id(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) memcpy(node_id, local.ipv6.in6_u.u6_addr8, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) tipc_net_init(net, node_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (!tipc_own_id(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) pr_warn("Failed to set node id, please configure manually\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) goto err;
^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) b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) rcu_assign_pointer(b->media_ptr, ub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) rcu_assign_pointer(ub->bearer, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) tipc_udp_media_addr_set(&b->addr, &local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (local.proto == htons(ETH_P_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dev = __ip_dev_find(net, local.ipv4.s_addr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) udp_conf.family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Switch to use ANY to receive packets from group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (rmcast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) udp_conf.local_ip.s_addr = local.ipv4.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) udp_conf.use_udp_checksums = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ub->ifindex = dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) sizeof(struct udphdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) b->mtu = b->media->mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) } else if (local.proto == htons(ETH_P_IPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) dev = ub->ifindex ? __dev_get_by_index(net, ub->ifindex) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) dev = ipv6_dev_find(net, &local.ipv6, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) udp_conf.family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) udp_conf.use_udp6_tx_checksums = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) udp_conf.use_udp6_rx_checksums = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (rmcast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) udp_conf.local_ip6 = in6addr_any;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) udp_conf.local_ip6 = local.ipv6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) ub->ifindex = dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) b->mtu = 1280;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) err = -EAFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) udp_conf.local_udp_port = local.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) err = udp_sock_create(net, &udp_conf, &ub->ubsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) tuncfg.sk_user_data = ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) tuncfg.encap_type = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) tuncfg.encap_rcv = tipc_udp_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) tuncfg.encap_destroy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * The bcast media address port is used for all peers and the ip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * is used if it's a multicast address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) memcpy(&b->bcast_addr.value, &remote, sizeof(remote));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (rmcast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) err = enable_mcast(ub, &remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) err = tipc_udp_rcast_add(b, &remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dst_cache_destroy(&ub->rcast.dst_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) udp_tunnel_sock_release(ub->ubsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) kfree(ub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /* cleanup_bearer - break the socket/bearer association */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) static void cleanup_bearer(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct udp_bearer *ub = container_of(work, struct udp_bearer, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct udp_replicast *rcast, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dst_cache_destroy(&rcast->dst_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) list_del_rcu(&rcast->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) kfree_rcu(rcast, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) dst_cache_destroy(&ub->rcast.dst_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) udp_tunnel_sock_release(ub->ubsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) kfree(ub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* tipc_udp_disable - detach bearer from socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static void tipc_udp_disable(struct tipc_bearer *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct udp_bearer *ub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ub = rtnl_dereference(b->media_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (!ub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) pr_err("UDP bearer instance not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) sock_set_flag(ub->ubsock->sk, SOCK_DEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) RCU_INIT_POINTER(ub->bearer, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* sock_release need to be done outside of rtnl lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) atomic_inc(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) INIT_WORK(&ub->work, cleanup_bearer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) schedule_work(&ub->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct tipc_media udp_media_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .send_msg = tipc_udp_send_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .enable_media = tipc_udp_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .disable_media = tipc_udp_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .addr2str = tipc_udp_addr2str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) .addr2msg = tipc_udp_addr2msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .msg2addr = tipc_udp_msg2addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .priority = TIPC_DEF_LINK_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .tolerance = TIPC_DEF_LINK_TOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .min_win = TIPC_DEF_LINK_WIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .max_win = TIPC_DEF_LINK_WIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .mtu = TIPC_DEF_LINK_UDP_MTU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .type_id = TIPC_MEDIA_TYPE_UDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .hwaddr_len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .name = "udp"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) };