Back to home page

OSCL-LXR

 
 

    


0001 /* net/tipc/udp_media.c: IP bearer support for TIPC
0002  *
0003  * Copyright (c) 2015, Ericsson AB
0004  * All rights reserved.
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions are met:
0008  *
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  * 3. Neither the names of the copyright holders nor the names of its
0015  *    contributors may be used to endorse or promote products derived from
0016  *    this software without specific prior written permission.
0017  *
0018  * Alternatively, this software may be distributed under the terms of the
0019  * GNU General Public License ("GPL") version 2 as published by the Free
0020  * Software Foundation.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #include <linux/socket.h>
0036 #include <linux/ip.h>
0037 #include <linux/udp.h>
0038 #include <linux/inet.h>
0039 #include <linux/inetdevice.h>
0040 #include <linux/igmp.h>
0041 #include <linux/kernel.h>
0042 #include <linux/workqueue.h>
0043 #include <linux/list.h>
0044 #include <net/sock.h>
0045 #include <net/ip.h>
0046 #include <net/udp_tunnel.h>
0047 #include <net/ipv6_stubs.h>
0048 #include <linux/tipc_netlink.h>
0049 #include "core.h"
0050 #include "addr.h"
0051 #include "net.h"
0052 #include "bearer.h"
0053 #include "netlink.h"
0054 #include "msg.h"
0055 #include "udp_media.h"
0056 
0057 /* IANA assigned UDP port */
0058 #define UDP_PORT_DEFAULT    6118
0059 
0060 #define UDP_MIN_HEADROOM        48
0061 
0062 /**
0063  * struct udp_media_addr - IP/UDP addressing information
0064  *
0065  * This is the bearer level originating address used in neighbor discovery
0066  * messages, and all fields should be in network byte order
0067  *
0068  * @proto: Ethernet protocol in use
0069  * @port: port being used
0070  * @ipv4: IPv4 address of neighbor
0071  * @ipv6: IPv6 address of neighbor
0072  */
0073 struct udp_media_addr {
0074     __be16  proto;
0075     __be16  port;
0076     union {
0077         struct in_addr ipv4;
0078         struct in6_addr ipv6;
0079     };
0080 };
0081 
0082 /* struct udp_replicast - container for UDP remote addresses */
0083 struct udp_replicast {
0084     struct udp_media_addr addr;
0085     struct dst_cache dst_cache;
0086     struct rcu_head rcu;
0087     struct list_head list;
0088 };
0089 
0090 /**
0091  * struct udp_bearer - ip/udp bearer data structure
0092  * @bearer: associated generic tipc bearer
0093  * @ubsock: bearer associated socket
0094  * @ifindex:    local address scope
0095  * @work:   used to schedule deferred work on a bearer
0096  * @rcast:  associated udp_replicast container
0097  */
0098 struct udp_bearer {
0099     struct tipc_bearer __rcu *bearer;
0100     struct socket *ubsock;
0101     u32 ifindex;
0102     struct work_struct work;
0103     struct udp_replicast rcast;
0104 };
0105 
0106 static int tipc_udp_is_mcast_addr(struct udp_media_addr *addr)
0107 {
0108     if (ntohs(addr->proto) == ETH_P_IP)
0109         return ipv4_is_multicast(addr->ipv4.s_addr);
0110 #if IS_ENABLED(CONFIG_IPV6)
0111     else
0112         return ipv6_addr_is_multicast(&addr->ipv6);
0113 #endif
0114     return 0;
0115 }
0116 
0117 /* udp_media_addr_set - convert a ip/udp address to a TIPC media address */
0118 static void tipc_udp_media_addr_set(struct tipc_media_addr *addr,
0119                     struct udp_media_addr *ua)
0120 {
0121     memset(addr, 0, sizeof(struct tipc_media_addr));
0122     addr->media_id = TIPC_MEDIA_TYPE_UDP;
0123     memcpy(addr->value, ua, sizeof(struct udp_media_addr));
0124 
0125     if (tipc_udp_is_mcast_addr(ua))
0126         addr->broadcast = TIPC_BROADCAST_SUPPORT;
0127 }
0128 
0129 /* tipc_udp_addr2str - convert ip/udp address to string */
0130 static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size)
0131 {
0132     struct udp_media_addr *ua = (struct udp_media_addr *)&a->value;
0133 
0134     if (ntohs(ua->proto) == ETH_P_IP)
0135         snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->port));
0136     else if (ntohs(ua->proto) == ETH_P_IPV6)
0137         snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->port));
0138     else
0139         pr_err("Invalid UDP media address\n");
0140     return 0;
0141 }
0142 
0143 /* tipc_udp_msg2addr - extract an ip/udp address from a TIPC ndisc message */
0144 static int tipc_udp_msg2addr(struct tipc_bearer *b, struct tipc_media_addr *a,
0145                  char *msg)
0146 {
0147     struct udp_media_addr *ua;
0148 
0149     ua = (struct udp_media_addr *) (msg + TIPC_MEDIA_ADDR_OFFSET);
0150     if (msg[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_UDP)
0151         return -EINVAL;
0152     tipc_udp_media_addr_set(a, ua);
0153     return 0;
0154 }
0155 
0156 /* tipc_udp_addr2msg - write an ip/udp address to a TIPC ndisc message */
0157 static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a)
0158 {
0159     memset(msg, 0, TIPC_MEDIA_INFO_SIZE);
0160     msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_UDP;
0161     memcpy(msg + TIPC_MEDIA_ADDR_OFFSET, a->value,
0162            sizeof(struct udp_media_addr));
0163     return 0;
0164 }
0165 
0166 /* tipc_send_msg - enqueue a send request */
0167 static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
0168              struct udp_bearer *ub, struct udp_media_addr *src,
0169              struct udp_media_addr *dst, struct dst_cache *cache)
0170 {
0171     struct dst_entry *ndst;
0172     int ttl, err = 0;
0173 
0174     local_bh_disable();
0175     ndst = dst_cache_get(cache);
0176     if (dst->proto == htons(ETH_P_IP)) {
0177         struct rtable *rt = (struct rtable *)ndst;
0178 
0179         if (!rt) {
0180             struct flowi4 fl = {
0181                 .daddr = dst->ipv4.s_addr,
0182                 .saddr = src->ipv4.s_addr,
0183                 .flowi4_mark = skb->mark,
0184                 .flowi4_proto = IPPROTO_UDP
0185             };
0186             rt = ip_route_output_key(net, &fl);
0187             if (IS_ERR(rt)) {
0188                 err = PTR_ERR(rt);
0189                 goto tx_error;
0190             }
0191             dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
0192         }
0193 
0194         ttl = ip4_dst_hoplimit(&rt->dst);
0195         udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
0196                     dst->ipv4.s_addr, 0, ttl, 0, src->port,
0197                     dst->port, false, true);
0198 #if IS_ENABLED(CONFIG_IPV6)
0199     } else {
0200         if (!ndst) {
0201             struct flowi6 fl6 = {
0202                 .flowi6_oif = ub->ifindex,
0203                 .daddr = dst->ipv6,
0204                 .saddr = src->ipv6,
0205                 .flowi6_proto = IPPROTO_UDP
0206             };
0207             ndst = ipv6_stub->ipv6_dst_lookup_flow(net,
0208                                    ub->ubsock->sk,
0209                                    &fl6, NULL);
0210             if (IS_ERR(ndst)) {
0211                 err = PTR_ERR(ndst);
0212                 goto tx_error;
0213             }
0214             dst_cache_set_ip6(cache, ndst, &fl6.saddr);
0215         }
0216         ttl = ip6_dst_hoplimit(ndst);
0217         err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
0218                        &src->ipv6, &dst->ipv6, 0, ttl, 0,
0219                        src->port, dst->port, false);
0220 #endif
0221     }
0222     local_bh_enable();
0223     return err;
0224 
0225 tx_error:
0226     local_bh_enable();
0227     kfree_skb(skb);
0228     return err;
0229 }
0230 
0231 static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
0232                  struct tipc_bearer *b,
0233                  struct tipc_media_addr *addr)
0234 {
0235     struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
0236     struct udp_media_addr *dst = (struct udp_media_addr *)&addr->value;
0237     struct udp_replicast *rcast;
0238     struct udp_bearer *ub;
0239     int err = 0;
0240 
0241     if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
0242         err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
0243         if (err)
0244             goto out;
0245     }
0246 
0247     skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
0248     ub = rcu_dereference(b->media_ptr);
0249     if (!ub) {
0250         err = -ENODEV;
0251         goto out;
0252     }
0253 
0254     if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
0255         return tipc_udp_xmit(net, skb, ub, src, dst,
0256                      &ub->rcast.dst_cache);
0257 
0258     /* Replicast, send an skb to each configured IP address */
0259     list_for_each_entry_rcu(rcast, &ub->rcast.list, list) {
0260         struct sk_buff *_skb;
0261 
0262         _skb = pskb_copy(skb, GFP_ATOMIC);
0263         if (!_skb) {
0264             err = -ENOMEM;
0265             goto out;
0266         }
0267 
0268         err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr,
0269                     &rcast->dst_cache);
0270         if (err)
0271             goto out;
0272     }
0273     err = 0;
0274 out:
0275     kfree_skb(skb);
0276     return err;
0277 }
0278 
0279 static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
0280                    struct udp_media_addr *addr)
0281 {
0282     struct udp_replicast *rcast, *tmp;
0283     struct udp_bearer *ub;
0284 
0285     ub = rcu_dereference_rtnl(b->media_ptr);
0286     if (!ub) {
0287         pr_err_ratelimited("UDP bearer instance not found\n");
0288         return false;
0289     }
0290 
0291     list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
0292         if (!memcmp(&rcast->addr, addr, sizeof(struct udp_media_addr)))
0293             return true;
0294     }
0295 
0296     return false;
0297 }
0298 
0299 static int tipc_udp_rcast_add(struct tipc_bearer *b,
0300                   struct udp_media_addr *addr)
0301 {
0302     struct udp_replicast *rcast;
0303     struct udp_bearer *ub;
0304 
0305     ub = rcu_dereference_rtnl(b->media_ptr);
0306     if (!ub)
0307         return -ENODEV;
0308 
0309     rcast = kmalloc(sizeof(*rcast), GFP_ATOMIC);
0310     if (!rcast)
0311         return -ENOMEM;
0312 
0313     if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
0314         kfree(rcast);
0315         return -ENOMEM;
0316     }
0317 
0318     memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
0319 
0320     if (ntohs(addr->proto) == ETH_P_IP)
0321         pr_info("New replicast peer: %pI4\n", &rcast->addr.ipv4);
0322 #if IS_ENABLED(CONFIG_IPV6)
0323     else if (ntohs(addr->proto) == ETH_P_IPV6)
0324         pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6);
0325 #endif
0326     b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
0327     list_add_rcu(&rcast->list, &ub->rcast.list);
0328     return 0;
0329 }
0330 
0331 static int tipc_udp_rcast_disc(struct tipc_bearer *b, struct sk_buff *skb)
0332 {
0333     struct udp_media_addr src = {0};
0334     struct udp_media_addr *dst;
0335 
0336     dst = (struct udp_media_addr *)&b->bcast_addr.value;
0337     if (tipc_udp_is_mcast_addr(dst))
0338         return 0;
0339 
0340     src.port = udp_hdr(skb)->source;
0341 
0342     if (ip_hdr(skb)->version == 4) {
0343         struct iphdr *iphdr = ip_hdr(skb);
0344 
0345         src.proto = htons(ETH_P_IP);
0346         src.ipv4.s_addr = iphdr->saddr;
0347         if (ipv4_is_multicast(iphdr->daddr))
0348             return 0;
0349 #if IS_ENABLED(CONFIG_IPV6)
0350     } else if (ip_hdr(skb)->version == 6) {
0351         struct ipv6hdr *iphdr = ipv6_hdr(skb);
0352 
0353         src.proto = htons(ETH_P_IPV6);
0354         src.ipv6 = iphdr->saddr;
0355         if (ipv6_addr_is_multicast(&iphdr->daddr))
0356             return 0;
0357 #endif
0358     } else {
0359         return 0;
0360     }
0361 
0362     if (likely(tipc_udp_is_known_peer(b, &src)))
0363         return 0;
0364 
0365     return tipc_udp_rcast_add(b, &src);
0366 }
0367 
0368 /* tipc_udp_recv - read data from bearer socket */
0369 static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
0370 {
0371     struct udp_bearer *ub;
0372     struct tipc_bearer *b;
0373     struct tipc_msg *hdr;
0374     int err;
0375 
0376     ub = rcu_dereference_sk_user_data(sk);
0377     if (!ub) {
0378         pr_err_ratelimited("Failed to get UDP bearer reference");
0379         goto out;
0380     }
0381     skb_pull(skb, sizeof(struct udphdr));
0382     hdr = buf_msg(skb);
0383 
0384     b = rcu_dereference(ub->bearer);
0385     if (!b)
0386         goto out;
0387 
0388     if (b && test_bit(0, &b->up)) {
0389         TIPC_SKB_CB(skb)->flags = 0;
0390         tipc_rcv(sock_net(sk), skb, b);
0391         return 0;
0392     }
0393 
0394     if (unlikely(msg_user(hdr) == LINK_CONFIG)) {
0395         err = tipc_udp_rcast_disc(b, skb);
0396         if (err)
0397             goto out;
0398     }
0399 
0400 out:
0401     kfree_skb(skb);
0402     return 0;
0403 }
0404 
0405 static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote)
0406 {
0407     int err = 0;
0408     struct ip_mreqn mreqn;
0409     struct sock *sk = ub->ubsock->sk;
0410 
0411     if (ntohs(remote->proto) == ETH_P_IP) {
0412         mreqn.imr_multiaddr = remote->ipv4;
0413         mreqn.imr_ifindex = ub->ifindex;
0414         err = ip_mc_join_group(sk, &mreqn);
0415 #if IS_ENABLED(CONFIG_IPV6)
0416     } else {
0417         lock_sock(sk);
0418         err = ipv6_stub->ipv6_sock_mc_join(sk, ub->ifindex,
0419                            &remote->ipv6);
0420         release_sock(sk);
0421 #endif
0422     }
0423     return err;
0424 }
0425 
0426 static int __tipc_nl_add_udp_addr(struct sk_buff *skb,
0427                   struct udp_media_addr *addr, int nla_t)
0428 {
0429     if (ntohs(addr->proto) == ETH_P_IP) {
0430         struct sockaddr_in ip4;
0431 
0432         memset(&ip4, 0, sizeof(ip4));
0433         ip4.sin_family = AF_INET;
0434         ip4.sin_port = addr->port;
0435         ip4.sin_addr.s_addr = addr->ipv4.s_addr;
0436         if (nla_put(skb, nla_t, sizeof(ip4), &ip4))
0437             return -EMSGSIZE;
0438 
0439 #if IS_ENABLED(CONFIG_IPV6)
0440     } else if (ntohs(addr->proto) == ETH_P_IPV6) {
0441         struct sockaddr_in6 ip6;
0442 
0443         memset(&ip6, 0, sizeof(ip6));
0444         ip6.sin6_family = AF_INET6;
0445         ip6.sin6_port  = addr->port;
0446         memcpy(&ip6.sin6_addr, &addr->ipv6, sizeof(struct in6_addr));
0447         if (nla_put(skb, nla_t, sizeof(ip6), &ip6))
0448             return -EMSGSIZE;
0449 #endif
0450     }
0451 
0452     return 0;
0453 }
0454 
0455 int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb)
0456 {
0457     u32 bid = cb->args[0];
0458     u32 skip_cnt = cb->args[1];
0459     u32 portid = NETLINK_CB(cb->skb).portid;
0460     struct udp_replicast *rcast, *tmp;
0461     struct tipc_bearer *b;
0462     struct udp_bearer *ub;
0463     void *hdr;
0464     int err;
0465     int i;
0466 
0467     if (!bid && !skip_cnt) {
0468         struct nlattr **attrs = genl_dumpit_info(cb)->attrs;
0469         struct net *net = sock_net(skb->sk);
0470         struct nlattr *battrs[TIPC_NLA_BEARER_MAX + 1];
0471         char *bname;
0472 
0473         if (!attrs[TIPC_NLA_BEARER])
0474             return -EINVAL;
0475 
0476         err = nla_parse_nested_deprecated(battrs, TIPC_NLA_BEARER_MAX,
0477                           attrs[TIPC_NLA_BEARER],
0478                           tipc_nl_bearer_policy, NULL);
0479         if (err)
0480             return err;
0481 
0482         if (!battrs[TIPC_NLA_BEARER_NAME])
0483             return -EINVAL;
0484 
0485         bname = nla_data(battrs[TIPC_NLA_BEARER_NAME]);
0486 
0487         rtnl_lock();
0488         b = tipc_bearer_find(net, bname);
0489         if (!b) {
0490             rtnl_unlock();
0491             return -EINVAL;
0492         }
0493         bid = b->identity;
0494     } else {
0495         struct net *net = sock_net(skb->sk);
0496         struct tipc_net *tn = net_generic(net, tipc_net_id);
0497 
0498         rtnl_lock();
0499         b = rtnl_dereference(tn->bearer_list[bid]);
0500         if (!b) {
0501             rtnl_unlock();
0502             return -EINVAL;
0503         }
0504     }
0505 
0506     ub = rtnl_dereference(b->media_ptr);
0507     if (!ub) {
0508         rtnl_unlock();
0509         return -EINVAL;
0510     }
0511 
0512     i = 0;
0513     list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
0514         if (i < skip_cnt)
0515             goto count;
0516 
0517         hdr = genlmsg_put(skb, portid, cb->nlh->nlmsg_seq,
0518                   &tipc_genl_family, NLM_F_MULTI,
0519                   TIPC_NL_BEARER_GET);
0520         if (!hdr)
0521             goto done;
0522 
0523         err = __tipc_nl_add_udp_addr(skb, &rcast->addr,
0524                          TIPC_NLA_UDP_REMOTE);
0525         if (err) {
0526             genlmsg_cancel(skb, hdr);
0527             goto done;
0528         }
0529         genlmsg_end(skb, hdr);
0530 count:
0531         i++;
0532     }
0533 done:
0534     rtnl_unlock();
0535     cb->args[0] = bid;
0536     cb->args[1] = i;
0537 
0538     return skb->len;
0539 }
0540 
0541 int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b)
0542 {
0543     struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
0544     struct udp_media_addr *dst;
0545     struct udp_bearer *ub;
0546     struct nlattr *nest;
0547 
0548     ub = rtnl_dereference(b->media_ptr);
0549     if (!ub)
0550         return -ENODEV;
0551 
0552     nest = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER_UDP_OPTS);
0553     if (!nest)
0554         goto msg_full;
0555 
0556     if (__tipc_nl_add_udp_addr(msg->skb, src, TIPC_NLA_UDP_LOCAL))
0557         goto msg_full;
0558 
0559     dst = (struct udp_media_addr *)&b->bcast_addr.value;
0560     if (__tipc_nl_add_udp_addr(msg->skb, dst, TIPC_NLA_UDP_REMOTE))
0561         goto msg_full;
0562 
0563     if (!list_empty(&ub->rcast.list)) {
0564         if (nla_put_flag(msg->skb, TIPC_NLA_UDP_MULTI_REMOTEIP))
0565             goto msg_full;
0566     }
0567 
0568     nla_nest_end(msg->skb, nest);
0569     return 0;
0570 msg_full:
0571     nla_nest_cancel(msg->skb, nest);
0572     return -EMSGSIZE;
0573 }
0574 
0575 /**
0576  * tipc_parse_udp_addr - build udp media address from netlink data
0577  * @nla:    netlink attribute containing sockaddr storage aligned address
0578  * @addr:   tipc media address to fill with address, port and protocol type
0579  * @scope_id:   IPv6 scope id pointer, not NULL indicates it's required
0580  */
0581 
0582 static int tipc_parse_udp_addr(struct nlattr *nla, struct udp_media_addr *addr,
0583                    u32 *scope_id)
0584 {
0585     struct sockaddr_storage sa;
0586 
0587     nla_memcpy(&sa, nla, sizeof(sa));
0588     if (sa.ss_family == AF_INET) {
0589         struct sockaddr_in *ip4 = (struct sockaddr_in *)&sa;
0590 
0591         addr->proto = htons(ETH_P_IP);
0592         addr->port = ip4->sin_port;
0593         addr->ipv4.s_addr = ip4->sin_addr.s_addr;
0594         return 0;
0595 
0596 #if IS_ENABLED(CONFIG_IPV6)
0597     } else if (sa.ss_family == AF_INET6) {
0598         struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)&sa;
0599 
0600         addr->proto = htons(ETH_P_IPV6);
0601         addr->port = ip6->sin6_port;
0602         memcpy(&addr->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
0603 
0604         /* Scope ID is only interesting for local addresses */
0605         if (scope_id) {
0606             int atype;
0607 
0608             atype = ipv6_addr_type(&ip6->sin6_addr);
0609             if (__ipv6_addr_needs_scope_id(atype) &&
0610                 !ip6->sin6_scope_id) {
0611                 return -EINVAL;
0612             }
0613 
0614             *scope_id = ip6->sin6_scope_id ? : 0;
0615         }
0616 
0617         return 0;
0618 #endif
0619     }
0620     return -EADDRNOTAVAIL;
0621 }
0622 
0623 int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr)
0624 {
0625     int err;
0626     struct udp_media_addr addr = {0};
0627     struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
0628     struct udp_media_addr *dst;
0629 
0630     if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attr, tipc_nl_udp_policy, NULL))
0631         return -EINVAL;
0632 
0633     if (!opts[TIPC_NLA_UDP_REMOTE])
0634         return -EINVAL;
0635 
0636     err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_REMOTE], &addr, NULL);
0637     if (err)
0638         return err;
0639 
0640     dst = (struct udp_media_addr *)&b->bcast_addr.value;
0641     if (tipc_udp_is_mcast_addr(dst)) {
0642         pr_err("Can't add remote ip to TIPC UDP multicast bearer\n");
0643         return -EINVAL;
0644     }
0645 
0646     if (tipc_udp_is_known_peer(b, &addr))
0647         return 0;
0648 
0649     return tipc_udp_rcast_add(b, &addr);
0650 }
0651 
0652 /**
0653  * tipc_udp_enable - callback to create a new udp bearer instance
0654  * @net:    network namespace
0655  * @b:      pointer to generic tipc_bearer
0656  * @attrs:  netlink bearer configuration
0657  *
0658  * validate the bearer parameters and initialize the udp bearer
0659  * rtnl_lock should be held
0660  */
0661 static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
0662                struct nlattr *attrs[])
0663 {
0664     int err = -EINVAL;
0665     struct udp_bearer *ub;
0666     struct udp_media_addr remote = {0};
0667     struct udp_media_addr local = {0};
0668     struct udp_port_cfg udp_conf = {0};
0669     struct udp_tunnel_sock_cfg tuncfg = {NULL};
0670     struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
0671     u8 node_id[NODE_ID_LEN] = {0,};
0672     struct net_device *dev;
0673     int rmcast = 0;
0674 
0675     ub = kzalloc(sizeof(*ub), GFP_ATOMIC);
0676     if (!ub)
0677         return -ENOMEM;
0678 
0679     INIT_LIST_HEAD(&ub->rcast.list);
0680 
0681     if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
0682         goto err;
0683 
0684     if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attrs[TIPC_NLA_BEARER_UDP_OPTS], tipc_nl_udp_policy, NULL))
0685         goto err;
0686 
0687     if (!opts[TIPC_NLA_UDP_LOCAL] || !opts[TIPC_NLA_UDP_REMOTE]) {
0688         pr_err("Invalid UDP bearer configuration");
0689         err = -EINVAL;
0690         goto err;
0691     }
0692 
0693     err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_LOCAL], &local,
0694                   &ub->ifindex);
0695     if (err)
0696         goto err;
0697 
0698     err = tipc_parse_udp_addr(opts[TIPC_NLA_UDP_REMOTE], &remote, NULL);
0699     if (err)
0700         goto err;
0701 
0702     if (remote.proto != local.proto) {
0703         err = -EINVAL;
0704         goto err;
0705     }
0706 
0707     /* Checking remote ip address */
0708     rmcast = tipc_udp_is_mcast_addr(&remote);
0709 
0710     /* Autoconfigure own node identity if needed */
0711     if (!tipc_own_id(net)) {
0712         memcpy(node_id, local.ipv6.in6_u.u6_addr8, 16);
0713         tipc_net_init(net, node_id, 0);
0714     }
0715     if (!tipc_own_id(net)) {
0716         pr_warn("Failed to set node id, please configure manually\n");
0717         err = -EINVAL;
0718         goto err;
0719     }
0720 
0721     b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP;
0722     b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
0723     rcu_assign_pointer(b->media_ptr, ub);
0724     rcu_assign_pointer(ub->bearer, b);
0725     tipc_udp_media_addr_set(&b->addr, &local);
0726     if (local.proto == htons(ETH_P_IP)) {
0727         dev = __ip_dev_find(net, local.ipv4.s_addr, false);
0728         if (!dev) {
0729             err = -ENODEV;
0730             goto err;
0731         }
0732         udp_conf.family = AF_INET;
0733 
0734         /* Switch to use ANY to receive packets from group */
0735         if (rmcast)
0736             udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
0737         else
0738             udp_conf.local_ip.s_addr = local.ipv4.s_addr;
0739         udp_conf.use_udp_checksums = false;
0740         ub->ifindex = dev->ifindex;
0741         if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
0742                       sizeof(struct udphdr))) {
0743             err = -EINVAL;
0744             goto err;
0745         }
0746         b->mtu = b->media->mtu;
0747 #if IS_ENABLED(CONFIG_IPV6)
0748     } else if (local.proto == htons(ETH_P_IPV6)) {
0749         dev = ub->ifindex ? __dev_get_by_index(net, ub->ifindex) : NULL;
0750         dev = ipv6_dev_find(net, &local.ipv6, dev);
0751         if (!dev) {
0752             err = -ENODEV;
0753             goto err;
0754         }
0755         udp_conf.family = AF_INET6;
0756         udp_conf.use_udp6_tx_checksums = true;
0757         udp_conf.use_udp6_rx_checksums = true;
0758         if (rmcast)
0759             udp_conf.local_ip6 = in6addr_any;
0760         else
0761             udp_conf.local_ip6 = local.ipv6;
0762         ub->ifindex = dev->ifindex;
0763         b->mtu = 1280;
0764 #endif
0765     } else {
0766         err = -EAFNOSUPPORT;
0767         goto err;
0768     }
0769     udp_conf.local_udp_port = local.port;
0770     err = udp_sock_create(net, &udp_conf, &ub->ubsock);
0771     if (err)
0772         goto err;
0773     tuncfg.sk_user_data = ub;
0774     tuncfg.encap_type = 1;
0775     tuncfg.encap_rcv = tipc_udp_recv;
0776     tuncfg.encap_destroy = NULL;
0777     setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
0778 
0779     err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
0780     if (err)
0781         goto free;
0782 
0783     /*
0784      * The bcast media address port is used for all peers and the ip
0785      * is used if it's a multicast address.
0786      */
0787     memcpy(&b->bcast_addr.value, &remote, sizeof(remote));
0788     if (rmcast)
0789         err = enable_mcast(ub, &remote);
0790     else
0791         err = tipc_udp_rcast_add(b, &remote);
0792     if (err)
0793         goto free;
0794 
0795     return 0;
0796 
0797 free:
0798     dst_cache_destroy(&ub->rcast.dst_cache);
0799     udp_tunnel_sock_release(ub->ubsock);
0800 err:
0801     kfree(ub);
0802     return err;
0803 }
0804 
0805 /* cleanup_bearer - break the socket/bearer association */
0806 static void cleanup_bearer(struct work_struct *work)
0807 {
0808     struct udp_bearer *ub = container_of(work, struct udp_bearer, work);
0809     struct udp_replicast *rcast, *tmp;
0810 
0811     list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
0812         dst_cache_destroy(&rcast->dst_cache);
0813         list_del_rcu(&rcast->list);
0814         kfree_rcu(rcast, rcu);
0815     }
0816 
0817     atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
0818     dst_cache_destroy(&ub->rcast.dst_cache);
0819     udp_tunnel_sock_release(ub->ubsock);
0820     synchronize_net();
0821     kfree(ub);
0822 }
0823 
0824 /* tipc_udp_disable - detach bearer from socket */
0825 static void tipc_udp_disable(struct tipc_bearer *b)
0826 {
0827     struct udp_bearer *ub;
0828 
0829     ub = rtnl_dereference(b->media_ptr);
0830     if (!ub) {
0831         pr_err("UDP bearer instance not found\n");
0832         return;
0833     }
0834     sock_set_flag(ub->ubsock->sk, SOCK_DEAD);
0835     RCU_INIT_POINTER(ub->bearer, NULL);
0836 
0837     /* sock_release need to be done outside of rtnl lock */
0838     atomic_inc(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
0839     INIT_WORK(&ub->work, cleanup_bearer);
0840     schedule_work(&ub->work);
0841 }
0842 
0843 struct tipc_media udp_media_info = {
0844     .send_msg   = tipc_udp_send_msg,
0845     .enable_media   = tipc_udp_enable,
0846     .disable_media  = tipc_udp_disable,
0847     .addr2str   = tipc_udp_addr2str,
0848     .addr2msg   = tipc_udp_addr2msg,
0849     .msg2addr   = tipc_udp_msg2addr,
0850     .priority   = TIPC_DEF_LINK_PRI,
0851     .tolerance  = TIPC_DEF_LINK_TOL,
0852     .min_win    = TIPC_DEF_LINK_WIN,
0853     .max_win    = TIPC_DEF_LINK_WIN,
0854     .mtu        = TIPC_DEF_LINK_UDP_MTU,
0855     .type_id    = TIPC_MEDIA_TYPE_UDP,
0856     .hwaddr_len = 0,
0857     .name       = "udp"
0858 };