1/* net/tipc/udp_media.c: IP bearer support for TIPC 2 * 3 * Copyright (c) 2015, Ericsson AB 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the names of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * Alternatively, this software may be distributed under the terms of the 19 * GNU General Public License ("GPL") version 2 as published by the Free 20 * Software Foundation. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35#include <linux/socket.h> 36#include <linux/ip.h> 37#include <linux/udp.h> 38#include <linux/inet.h> 39#include <linux/inetdevice.h> 40#include <linux/igmp.h> 41#include <linux/kernel.h> 42#include <linux/workqueue.h> 43#include <linux/list.h> 44#include <net/sock.h> 45#include <net/ip.h> 46#include <net/udp_tunnel.h> 47#include <net/addrconf.h> 48#include <linux/tipc_netlink.h> 49#include "core.h" 50#include "bearer.h" 51#include "msg.h" 52 53/* IANA assigned UDP port */ 54#define UDP_PORT_DEFAULT 6118 55 56static const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = { 57 [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC}, 58 [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY, 59 .len = sizeof(struct sockaddr_storage)}, 60 [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY, 61 .len = sizeof(struct sockaddr_storage)}, 62}; 63 64/** 65 * struct udp_media_addr - IP/UDP addressing information 66 * 67 * This is the bearer level originating address used in neighbor discovery 68 * messages, and all fields should be in network byte order 69 */ 70struct udp_media_addr { 71 __be16 proto; 72 __be16 udp_port; 73 union { 74 struct in_addr ipv4; 75 struct in6_addr ipv6; 76 }; 77}; 78 79/** 80 * struct udp_bearer - ip/udp bearer data structure 81 * @bearer: associated generic tipc bearer 82 * @ubsock: bearer associated socket 83 * @ifindex: local address scope 84 * @work: used to schedule deferred work on a bearer 85 */ 86struct udp_bearer { 87 struct tipc_bearer __rcu *bearer; 88 struct socket *ubsock; 89 u32 ifindex; 90 struct work_struct work; 91}; 92 93/* udp_media_addr_set - convert a ip/udp address to a TIPC media address */ 94static void tipc_udp_media_addr_set(struct tipc_media_addr *addr, 95 struct udp_media_addr *ua) 96{ 97 memset(addr, 0, sizeof(struct tipc_media_addr)); 98 addr->media_id = TIPC_MEDIA_TYPE_UDP; 99 memcpy(addr->value, ua, sizeof(struct udp_media_addr)); 100 if (ntohs(ua->proto) == ETH_P_IP) { 101 if (ipv4_is_multicast(ua->ipv4.s_addr)) 102 addr->broadcast = 1; 103 } else if (ntohs(ua->proto) == ETH_P_IPV6) { 104 if (ipv6_addr_type(&ua->ipv6) & IPV6_ADDR_MULTICAST) 105 addr->broadcast = 1; 106 } else { 107 pr_err("Invalid UDP media address\n"); 108 } 109} 110 111/* tipc_udp_addr2str - convert ip/udp address to string */ 112static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size) 113{ 114 struct udp_media_addr *ua = (struct udp_media_addr *)&a->value; 115 116 if (ntohs(ua->proto) == ETH_P_IP) 117 snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->udp_port)); 118 else if (ntohs(ua->proto) == ETH_P_IPV6) 119 snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->udp_port)); 120 else 121 pr_err("Invalid UDP media address\n"); 122 return 0; 123} 124 125/* tipc_udp_msg2addr - extract an ip/udp address from a TIPC ndisc message */ 126static int tipc_udp_msg2addr(struct tipc_bearer *b, struct tipc_media_addr *a, 127 char *msg) 128{ 129 struct udp_media_addr *ua; 130 131 ua = (struct udp_media_addr *) (msg + TIPC_MEDIA_ADDR_OFFSET); 132 if (msg[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_UDP) 133 return -EINVAL; 134 tipc_udp_media_addr_set(a, ua); 135 return 0; 136} 137 138/* tipc_udp_addr2msg - write an ip/udp address to a TIPC ndisc message */ 139static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a) 140{ 141 memset(msg, 0, TIPC_MEDIA_INFO_SIZE); 142 msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_UDP; 143 memcpy(msg + TIPC_MEDIA_ADDR_OFFSET, a->value, 144 sizeof(struct udp_media_addr)); 145 return 0; 146} 147 148/* tipc_send_msg - enqueue a send request */ 149static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, 150 struct tipc_bearer *b, 151 struct tipc_media_addr *dest) 152{ 153 int ttl, err = 0; 154 struct udp_bearer *ub; 155 struct udp_media_addr *dst = (struct udp_media_addr *)&dest->value; 156 struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value; 157 struct sk_buff *clone; 158 struct rtable *rt; 159 160 clone = skb_clone(skb, GFP_ATOMIC); 161 skb_set_inner_protocol(clone, htons(ETH_P_TIPC)); 162 ub = rcu_dereference_rtnl(b->media_ptr); 163 if (!ub) { 164 err = -ENODEV; 165 goto tx_error; 166 } 167 if (dst->proto == htons(ETH_P_IP)) { 168 struct flowi4 fl = { 169 .daddr = dst->ipv4.s_addr, 170 .saddr = src->ipv4.s_addr, 171 .flowi4_mark = clone->mark, 172 .flowi4_proto = IPPROTO_UDP 173 }; 174 rt = ip_route_output_key(net, &fl); 175 if (IS_ERR(rt)) { 176 err = PTR_ERR(rt); 177 goto tx_error; 178 } 179 ttl = ip4_dst_hoplimit(&rt->dst); 180 err = udp_tunnel_xmit_skb(rt, ub->ubsock->sk, clone, 181 src->ipv4.s_addr, 182 dst->ipv4.s_addr, 0, ttl, 0, 183 src->udp_port, dst->udp_port, 184 false, true); 185 if (err < 0) { 186 ip_rt_put(rt); 187 goto tx_error; 188 } 189#if IS_ENABLED(CONFIG_IPV6) 190 } else { 191 struct dst_entry *ndst; 192 struct flowi6 fl6 = { 193 .flowi6_oif = ub->ifindex, 194 .daddr = dst->ipv6, 195 .saddr = src->ipv6, 196 .flowi6_proto = IPPROTO_UDP 197 }; 198 err = ipv6_stub->ipv6_dst_lookup(ub->ubsock->sk, &ndst, &fl6); 199 if (err) 200 goto tx_error; 201 ttl = ip6_dst_hoplimit(ndst); 202 err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, clone, 203 ndst->dev, &src->ipv6, 204 &dst->ipv6, 0, ttl, src->udp_port, 205 dst->udp_port, false); 206#endif 207 } 208 return err; 209 210tx_error: 211 kfree_skb(clone); 212 return err; 213} 214 215/* tipc_udp_recv - read data from bearer socket */ 216static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb) 217{ 218 struct udp_bearer *ub; 219 struct tipc_bearer *b; 220 int usr = msg_user(buf_msg(skb)); 221 222 if ((usr == LINK_PROTOCOL) || (usr == NAME_DISTRIBUTOR)) 223 skb_linearize(skb); 224 225 ub = rcu_dereference_sk_user_data(sk); 226 if (!ub) { 227 pr_err_ratelimited("Failed to get UDP bearer reference"); 228 kfree_skb(skb); 229 return 0; 230 } 231 232 skb_pull(skb, sizeof(struct udphdr)); 233 rcu_read_lock(); 234 b = rcu_dereference_rtnl(ub->bearer); 235 236 if (b) { 237 tipc_rcv(sock_net(sk), skb, b); 238 rcu_read_unlock(); 239 return 0; 240 } 241 rcu_read_unlock(); 242 kfree_skb(skb); 243 return 0; 244} 245 246static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote) 247{ 248 int err = 0; 249 struct ip_mreqn mreqn; 250 struct sock *sk = ub->ubsock->sk; 251 252 if (ntohs(remote->proto) == ETH_P_IP) { 253 if (!ipv4_is_multicast(remote->ipv4.s_addr)) 254 return 0; 255 mreqn.imr_multiaddr = remote->ipv4; 256 mreqn.imr_ifindex = ub->ifindex; 257 err = ip_mc_join_group(sk, &mreqn); 258#if IS_ENABLED(CONFIG_IPV6) 259 } else { 260 if (!ipv6_addr_is_multicast(&remote->ipv6)) 261 return 0; 262 err = ipv6_stub->ipv6_sock_mc_join(sk, ub->ifindex, 263 &remote->ipv6); 264#endif 265 } 266 return err; 267} 268 269/** 270 * parse_options - build local/remote addresses from configuration 271 * @attrs: netlink config data 272 * @ub: UDP bearer instance 273 * @local: local bearer IP address/port 274 * @remote: peer or multicast IP/port 275 */ 276static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub, 277 struct udp_media_addr *local, 278 struct udp_media_addr *remote) 279{ 280 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1]; 281 struct sockaddr_storage *sa_local, *sa_remote; 282 283 if (!attrs[TIPC_NLA_BEARER_UDP_OPTS]) 284 goto err; 285 if (nla_parse_nested(opts, TIPC_NLA_UDP_MAX, 286 attrs[TIPC_NLA_BEARER_UDP_OPTS], 287 tipc_nl_udp_policy)) 288 goto err; 289 if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) { 290 sa_local = nla_data(opts[TIPC_NLA_UDP_LOCAL]); 291 sa_remote = nla_data(opts[TIPC_NLA_UDP_REMOTE]); 292 } else { 293err: 294 pr_err("Invalid UDP bearer configuration"); 295 return -EINVAL; 296 } 297 if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET) { 298 struct sockaddr_in *ip4; 299 300 ip4 = (struct sockaddr_in *)sa_local; 301 local->proto = htons(ETH_P_IP); 302 local->udp_port = ip4->sin_port; 303 local->ipv4.s_addr = ip4->sin_addr.s_addr; 304 305 ip4 = (struct sockaddr_in *)sa_remote; 306 remote->proto = htons(ETH_P_IP); 307 remote->udp_port = ip4->sin_port; 308 remote->ipv4.s_addr = ip4->sin_addr.s_addr; 309 return 0; 310 311#if IS_ENABLED(CONFIG_IPV6) 312 } else if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET6) { 313 struct sockaddr_in6 *ip6; 314 315 ip6 = (struct sockaddr_in6 *)sa_local; 316 local->proto = htons(ETH_P_IPV6); 317 local->udp_port = ip6->sin6_port; 318 local->ipv6 = ip6->sin6_addr; 319 ub->ifindex = ip6->sin6_scope_id; 320 321 ip6 = (struct sockaddr_in6 *)sa_remote; 322 remote->proto = htons(ETH_P_IPV6); 323 remote->udp_port = ip6->sin6_port; 324 remote->ipv6 = ip6->sin6_addr; 325 return 0; 326#endif 327 } 328 return -EADDRNOTAVAIL; 329} 330 331/** 332 * tipc_udp_enable - callback to create a new udp bearer instance 333 * @net: network namespace 334 * @b: pointer to generic tipc_bearer 335 * @attrs: netlink bearer configuration 336 * 337 * validate the bearer parameters and initialize the udp bearer 338 * rtnl_lock should be held 339 */ 340static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, 341 struct nlattr *attrs[]) 342{ 343 int err = -EINVAL; 344 struct udp_bearer *ub; 345 struct udp_media_addr *remote; 346 struct udp_media_addr local = {0}; 347 struct udp_port_cfg udp_conf = {0}; 348 struct udp_tunnel_sock_cfg tuncfg = {NULL}; 349 350 ub = kzalloc(sizeof(*ub), GFP_ATOMIC); 351 if (!ub) 352 return -ENOMEM; 353 354 remote = (struct udp_media_addr *)&b->bcast_addr.value; 355 memset(remote, 0, sizeof(struct udp_media_addr)); 356 err = parse_options(attrs, ub, &local, remote); 357 if (err) 358 goto err; 359 360 b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP; 361 b->bcast_addr.broadcast = 1; 362 rcu_assign_pointer(b->media_ptr, ub); 363 rcu_assign_pointer(ub->bearer, b); 364 tipc_udp_media_addr_set(&b->addr, &local); 365 if (local.proto == htons(ETH_P_IP)) { 366 struct net_device *dev; 367 368 dev = __ip_dev_find(net, local.ipv4.s_addr, false); 369 if (!dev) { 370 err = -ENODEV; 371 goto err; 372 } 373 udp_conf.family = AF_INET; 374 udp_conf.local_ip.s_addr = htonl(INADDR_ANY); 375 udp_conf.use_udp_checksums = false; 376 ub->ifindex = dev->ifindex; 377 b->mtu = dev->mtu - sizeof(struct iphdr) 378 - sizeof(struct udphdr); 379#if IS_ENABLED(CONFIG_IPV6) 380 } else if (local.proto == htons(ETH_P_IPV6)) { 381 udp_conf.family = AF_INET6; 382 udp_conf.use_udp6_tx_checksums = true; 383 udp_conf.use_udp6_rx_checksums = true; 384 udp_conf.local_ip6 = in6addr_any; 385 b->mtu = 1280; 386#endif 387 } else { 388 err = -EAFNOSUPPORT; 389 goto err; 390 } 391 udp_conf.local_udp_port = local.udp_port; 392 err = udp_sock_create(net, &udp_conf, &ub->ubsock); 393 if (err) 394 goto err; 395 tuncfg.sk_user_data = ub; 396 tuncfg.encap_type = 1; 397 tuncfg.encap_rcv = tipc_udp_recv; 398 tuncfg.encap_destroy = NULL; 399 setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg); 400 401 if (enable_mcast(ub, remote)) 402 goto err; 403 return 0; 404err: 405 kfree(ub); 406 return err; 407} 408 409/* cleanup_bearer - break the socket/bearer association */ 410static void cleanup_bearer(struct work_struct *work) 411{ 412 struct udp_bearer *ub = container_of(work, struct udp_bearer, work); 413 414 if (ub->ubsock) 415 udp_tunnel_sock_release(ub->ubsock); 416 synchronize_net(); 417 kfree(ub); 418} 419 420/* tipc_udp_disable - detach bearer from socket */ 421static void tipc_udp_disable(struct tipc_bearer *b) 422{ 423 struct udp_bearer *ub; 424 425 ub = rcu_dereference_rtnl(b->media_ptr); 426 if (!ub) { 427 pr_err("UDP bearer instance not found\n"); 428 return; 429 } 430 if (ub->ubsock) 431 sock_set_flag(ub->ubsock->sk, SOCK_DEAD); 432 RCU_INIT_POINTER(b->media_ptr, NULL); 433 RCU_INIT_POINTER(ub->bearer, NULL); 434 435 /* sock_release need to be done outside of rtnl lock */ 436 INIT_WORK(&ub->work, cleanup_bearer); 437 schedule_work(&ub->work); 438} 439 440struct tipc_media udp_media_info = { 441 .send_msg = tipc_udp_send_msg, 442 .enable_media = tipc_udp_enable, 443 .disable_media = tipc_udp_disable, 444 .addr2str = tipc_udp_addr2str, 445 .addr2msg = tipc_udp_addr2msg, 446 .msg2addr = tipc_udp_msg2addr, 447 .priority = TIPC_DEF_LINK_PRI, 448 .tolerance = TIPC_DEF_LINK_TOL, 449 .window = TIPC_DEF_LINK_WIN, 450 .type_id = TIPC_MEDIA_TYPE_UDP, 451 .hwaddr_len = 0, 452 .name = "udp" 453}; 454