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 52 /* IANA assigned UDP port */ 53 #define UDP_PORT_DEFAULT 6118 54 55 static const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = { 56 [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC}, 57 [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY, 58 .len = sizeof(struct sockaddr_storage)}, 59 [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY, 60 .len = sizeof(struct sockaddr_storage)}, 61 }; 62 63 /** 64 * struct udp_media_addr - IP/UDP addressing information 65 * 66 * This is the bearer level originating address used in neighbor discovery 67 * messages, and all fields should be in network byte order 68 */ 69 struct udp_media_addr { 70 __be16 proto; 71 __be16 udp_port; 72 union { 73 struct in_addr ipv4; 74 struct in6_addr ipv6; 75 }; 76 }; 77 78 /** 79 * struct udp_bearer - ip/udp bearer data structure 80 * @bearer: associated generic tipc bearer 81 * @ubsock: bearer associated socket 82 * @ifindex: local address scope 83 * @work: used to schedule deferred work on a bearer 84 */ 85 struct udp_bearer { 86 struct tipc_bearer __rcu *bearer; 87 struct socket *ubsock; 88 u32 ifindex; 89 struct work_struct work; 90 }; 91 92 /* udp_media_addr_set - convert a ip/udp address to a TIPC media address */ 93 static void tipc_udp_media_addr_set(struct tipc_media_addr *addr, 94 struct udp_media_addr *ua) 95 { 96 memset(addr, 0, sizeof(struct tipc_media_addr)); 97 addr->media_id = TIPC_MEDIA_TYPE_UDP; 98 memcpy(addr->value, ua, sizeof(struct udp_media_addr)); 99 if (ntohs(ua->proto) == ETH_P_IP) { 100 if (ipv4_is_multicast(ua->ipv4.s_addr)) 101 addr->broadcast = 1; 102 } else if (ntohs(ua->proto) == ETH_P_IPV6) { 103 if (ipv6_addr_type(&ua->ipv6) & IPV6_ADDR_MULTICAST) 104 addr->broadcast = 1; 105 } else { 106 pr_err("Invalid UDP media address\n"); 107 } 108 } 109 110 /* tipc_udp_addr2str - convert ip/udp address to string */ 111 static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size) 112 { 113 struct udp_media_addr *ua = (struct udp_media_addr *)&a->value; 114 115 if (ntohs(ua->proto) == ETH_P_IP) 116 snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->udp_port)); 117 else if (ntohs(ua->proto) == ETH_P_IPV6) 118 snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->udp_port)); 119 else 120 pr_err("Invalid UDP media address\n"); 121 return 0; 122 } 123 124 /* tipc_udp_msg2addr - extract an ip/udp address from a TIPC ndisc message */ 125 static int tipc_udp_msg2addr(struct tipc_bearer *b, struct tipc_media_addr *a, 126 char *msg) 127 { 128 struct udp_media_addr *ua; 129 130 ua = (struct udp_media_addr *) (msg + TIPC_MEDIA_ADDR_OFFSET); 131 if (msg[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_UDP) 132 return -EINVAL; 133 tipc_udp_media_addr_set(a, ua); 134 return 0; 135 } 136 137 /* tipc_udp_addr2msg - write an ip/udp address to a TIPC ndisc message */ 138 static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a) 139 { 140 memset(msg, 0, TIPC_MEDIA_INFO_SIZE); 141 msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_UDP; 142 memcpy(msg + TIPC_MEDIA_ADDR_OFFSET, a->value, 143 sizeof(struct udp_media_addr)); 144 return 0; 145 } 146 147 /* tipc_send_msg - enqueue a send request */ 148 static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, 149 struct tipc_bearer *b, 150 struct tipc_media_addr *dest) 151 { 152 int ttl, err = 0; 153 struct udp_bearer *ub; 154 struct udp_media_addr *dst = (struct udp_media_addr *)&dest->value; 155 struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value; 156 struct sk_buff *clone; 157 struct rtable *rt; 158 159 clone = skb_clone(skb, GFP_ATOMIC); 160 skb_set_inner_protocol(clone, htons(ETH_P_TIPC)); 161 ub = rcu_dereference_rtnl(b->media_ptr); 162 if (!ub) { 163 err = -ENODEV; 164 goto tx_error; 165 } 166 if (dst->proto == htons(ETH_P_IP)) { 167 struct flowi4 fl = { 168 .daddr = dst->ipv4.s_addr, 169 .saddr = src->ipv4.s_addr, 170 .flowi4_mark = clone->mark, 171 .flowi4_proto = IPPROTO_UDP 172 }; 173 rt = ip_route_output_key(net, &fl); 174 if (IS_ERR(rt)) { 175 err = PTR_ERR(rt); 176 goto tx_error; 177 } 178 ttl = ip4_dst_hoplimit(&rt->dst); 179 err = udp_tunnel_xmit_skb(rt, ub->ubsock->sk, clone, 180 src->ipv4.s_addr, 181 dst->ipv4.s_addr, 0, ttl, 0, 182 src->udp_port, dst->udp_port, 183 false, true); 184 if (err < 0) { 185 ip_rt_put(rt); 186 goto tx_error; 187 } 188 #if IS_ENABLED(CONFIG_IPV6) 189 } else { 190 struct dst_entry *ndst; 191 struct flowi6 fl6 = { 192 .flowi6_oif = ub->ifindex, 193 .daddr = dst->ipv6, 194 .saddr = src->ipv6, 195 .flowi6_proto = IPPROTO_UDP 196 }; 197 err = ipv6_stub->ipv6_dst_lookup(ub->ubsock->sk, &ndst, &fl6); 198 if (err) 199 goto tx_error; 200 ttl = ip6_dst_hoplimit(ndst); 201 err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, clone, 202 ndst->dev, &src->ipv6, 203 &dst->ipv6, 0, ttl, src->udp_port, 204 dst->udp_port, false); 205 #endif 206 } 207 return err; 208 209 tx_error: 210 kfree_skb(clone); 211 return err; 212 } 213 214 /* tipc_udp_recv - read data from bearer socket */ 215 static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb) 216 { 217 struct udp_bearer *ub; 218 struct tipc_bearer *b; 219 220 ub = rcu_dereference_sk_user_data(sk); 221 if (!ub) { 222 pr_err_ratelimited("Failed to get UDP bearer reference"); 223 kfree_skb(skb); 224 return 0; 225 } 226 227 skb_pull(skb, sizeof(struct udphdr)); 228 rcu_read_lock(); 229 b = rcu_dereference_rtnl(ub->bearer); 230 231 if (b) { 232 tipc_rcv(sock_net(sk), skb, b); 233 rcu_read_unlock(); 234 return 0; 235 } 236 rcu_read_unlock(); 237 kfree_skb(skb); 238 return 0; 239 } 240 241 static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote) 242 { 243 int err = 0; 244 struct ip_mreqn mreqn; 245 struct sock *sk = ub->ubsock->sk; 246 247 if (ntohs(remote->proto) == ETH_P_IP) { 248 if (!ipv4_is_multicast(remote->ipv4.s_addr)) 249 return 0; 250 mreqn.imr_multiaddr = remote->ipv4; 251 mreqn.imr_ifindex = ub->ifindex; 252 err = ip_mc_join_group(sk, &mreqn); 253 #if IS_ENABLED(CONFIG_IPV6) 254 } else { 255 if (!ipv6_addr_is_multicast(&remote->ipv6)) 256 return 0; 257 err = ipv6_stub->ipv6_sock_mc_join(sk, ub->ifindex, 258 &remote->ipv6); 259 #endif 260 } 261 return err; 262 } 263 264 /** 265 * parse_options - build local/remote addresses from configuration 266 * @attrs: netlink config data 267 * @ub: UDP bearer instance 268 * @local: local bearer IP address/port 269 * @remote: peer or multicast IP/port 270 */ 271 static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub, 272 struct udp_media_addr *local, 273 struct udp_media_addr *remote) 274 { 275 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1]; 276 struct sockaddr_storage *sa_local, *sa_remote; 277 278 if (!attrs[TIPC_NLA_BEARER_UDP_OPTS]) 279 goto err; 280 if (nla_parse_nested(opts, TIPC_NLA_UDP_MAX, 281 attrs[TIPC_NLA_BEARER_UDP_OPTS], 282 tipc_nl_udp_policy)) 283 goto err; 284 if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) { 285 sa_local = nla_data(opts[TIPC_NLA_UDP_LOCAL]); 286 sa_remote = nla_data(opts[TIPC_NLA_UDP_REMOTE]); 287 } else { 288 err: 289 pr_err("Invalid UDP bearer configuration"); 290 return -EINVAL; 291 } 292 if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET) { 293 struct sockaddr_in *ip4; 294 295 ip4 = (struct sockaddr_in *)sa_local; 296 local->proto = htons(ETH_P_IP); 297 local->udp_port = ip4->sin_port; 298 local->ipv4.s_addr = ip4->sin_addr.s_addr; 299 300 ip4 = (struct sockaddr_in *)sa_remote; 301 remote->proto = htons(ETH_P_IP); 302 remote->udp_port = ip4->sin_port; 303 remote->ipv4.s_addr = ip4->sin_addr.s_addr; 304 return 0; 305 306 #if IS_ENABLED(CONFIG_IPV6) 307 } else if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET6) { 308 struct sockaddr_in6 *ip6; 309 310 ip6 = (struct sockaddr_in6 *)sa_local; 311 local->proto = htons(ETH_P_IPV6); 312 local->udp_port = ip6->sin6_port; 313 local->ipv6 = ip6->sin6_addr; 314 ub->ifindex = ip6->sin6_scope_id; 315 316 ip6 = (struct sockaddr_in6 *)sa_remote; 317 remote->proto = htons(ETH_P_IPV6); 318 remote->udp_port = ip6->sin6_port; 319 remote->ipv6 = ip6->sin6_addr; 320 return 0; 321 #endif 322 } 323 return -EADDRNOTAVAIL; 324 } 325 326 /** 327 * tipc_udp_enable - callback to create a new udp bearer instance 328 * @net: network namespace 329 * @b: pointer to generic tipc_bearer 330 * @attrs: netlink bearer configuration 331 * 332 * validate the bearer parameters and initialize the udp bearer 333 * rtnl_lock should be held 334 */ 335 static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, 336 struct nlattr *attrs[]) 337 { 338 int err = -EINVAL; 339 struct udp_bearer *ub; 340 struct udp_media_addr *remote; 341 struct udp_media_addr local = {0}; 342 struct udp_port_cfg udp_conf = {0}; 343 struct udp_tunnel_sock_cfg tuncfg = {NULL}; 344 345 ub = kzalloc(sizeof(*ub), GFP_ATOMIC); 346 if (!ub) 347 return -ENOMEM; 348 349 remote = (struct udp_media_addr *)&b->bcast_addr.value; 350 memset(remote, 0, sizeof(struct udp_media_addr)); 351 err = parse_options(attrs, ub, &local, remote); 352 if (err) 353 goto err; 354 355 b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP; 356 b->bcast_addr.broadcast = 1; 357 rcu_assign_pointer(b->media_ptr, ub); 358 rcu_assign_pointer(ub->bearer, b); 359 tipc_udp_media_addr_set(&b->addr, &local); 360 if (local.proto == htons(ETH_P_IP)) { 361 struct net_device *dev; 362 363 dev = __ip_dev_find(net, local.ipv4.s_addr, false); 364 if (!dev) { 365 err = -ENODEV; 366 goto err; 367 } 368 udp_conf.family = AF_INET; 369 udp_conf.local_ip.s_addr = htonl(INADDR_ANY); 370 udp_conf.use_udp_checksums = false; 371 ub->ifindex = dev->ifindex; 372 b->mtu = dev->mtu - sizeof(struct iphdr) 373 - sizeof(struct udphdr); 374 #if IS_ENABLED(CONFIG_IPV6) 375 } else if (local.proto == htons(ETH_P_IPV6)) { 376 udp_conf.family = AF_INET6; 377 udp_conf.use_udp6_tx_checksums = true; 378 udp_conf.use_udp6_rx_checksums = true; 379 udp_conf.local_ip6 = in6addr_any; 380 b->mtu = 1280; 381 #endif 382 } else { 383 err = -EAFNOSUPPORT; 384 goto err; 385 } 386 udp_conf.local_udp_port = local.udp_port; 387 err = udp_sock_create(net, &udp_conf, &ub->ubsock); 388 if (err) 389 goto err; 390 tuncfg.sk_user_data = ub; 391 tuncfg.encap_type = 1; 392 tuncfg.encap_rcv = tipc_udp_recv; 393 tuncfg.encap_destroy = NULL; 394 setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg); 395 396 if (enable_mcast(ub, remote)) 397 goto err; 398 return 0; 399 err: 400 kfree(ub); 401 return err; 402 } 403 404 /* cleanup_bearer - break the socket/bearer association */ 405 static void cleanup_bearer(struct work_struct *work) 406 { 407 struct udp_bearer *ub = container_of(work, struct udp_bearer, work); 408 409 if (ub->ubsock) 410 udp_tunnel_sock_release(ub->ubsock); 411 synchronize_net(); 412 kfree(ub); 413 } 414 415 /* tipc_udp_disable - detach bearer from socket */ 416 static void tipc_udp_disable(struct tipc_bearer *b) 417 { 418 struct udp_bearer *ub; 419 420 ub = rcu_dereference_rtnl(b->media_ptr); 421 if (!ub) { 422 pr_err("UDP bearer instance not found\n"); 423 return; 424 } 425 if (ub->ubsock) 426 sock_set_flag(ub->ubsock->sk, SOCK_DEAD); 427 RCU_INIT_POINTER(b->media_ptr, NULL); 428 RCU_INIT_POINTER(ub->bearer, NULL); 429 430 /* sock_release need to be done outside of rtnl lock */ 431 INIT_WORK(&ub->work, cleanup_bearer); 432 schedule_work(&ub->work); 433 } 434 435 struct tipc_media udp_media_info = { 436 .send_msg = tipc_udp_send_msg, 437 .enable_media = tipc_udp_enable, 438 .disable_media = tipc_udp_disable, 439 .addr2str = tipc_udp_addr2str, 440 .addr2msg = tipc_udp_addr2msg, 441 .msg2addr = tipc_udp_msg2addr, 442 .priority = TIPC_DEF_LINK_PRI, 443 .tolerance = TIPC_DEF_LINK_TOL, 444 .window = TIPC_DEF_LINK_WIN, 445 .type_id = TIPC_MEDIA_TYPE_UDP, 446 .hwaddr_len = 0, 447 .name = "udp" 448 }; 449