~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ipv4/datagram.c

Version: ~ [ linux-5.4-rc3 ] ~ [ linux-5.3.6 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.79 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.149 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.196 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.196 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.75 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      common UDP/RAW code
  3  *      Linux INET implementation
  4  *
  5  * Authors:
  6  *      Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
  7  *
  8  *      This program is free software; you can redistribute it and/or
  9  *      modify it under the terms of the GNU General Public License
 10  *      as published by the Free Software Foundation; either version
 11  *      2 of the License, or (at your option) any later version.
 12  */
 13 
 14 #include <linux/types.h>
 15 #include <linux/module.h>
 16 #include <linux/ip.h>
 17 #include <linux/in.h>
 18 #include <net/ip.h>
 19 #include <net/sock.h>
 20 #include <net/route.h>
 21 #include <net/tcp_states.h>
 22 
 23 int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 24 {
 25         struct inet_sock *inet = inet_sk(sk);
 26         struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
 27         struct flowi4 *fl4;
 28         struct rtable *rt;
 29         __be32 saddr;
 30         int oif;
 31         int err;
 32 
 33 
 34         if (addr_len < sizeof(*usin))
 35                 return -EINVAL;
 36 
 37         if (usin->sin_family != AF_INET)
 38                 return -EAFNOSUPPORT;
 39 
 40         sk_dst_reset(sk);
 41 
 42         oif = sk->sk_bound_dev_if;
 43         saddr = inet->inet_saddr;
 44         if (ipv4_is_multicast(usin->sin_addr.s_addr)) {
 45                 if (!oif)
 46                         oif = inet->mc_index;
 47                 if (!saddr)
 48                         saddr = inet->mc_addr;
 49         }
 50         fl4 = &inet->cork.fl.u.ip4;
 51         rt = ip_route_connect(fl4, usin->sin_addr.s_addr, saddr,
 52                               RT_CONN_FLAGS(sk), oif,
 53                               sk->sk_protocol,
 54                               inet->inet_sport, usin->sin_port, sk);
 55         if (IS_ERR(rt)) {
 56                 err = PTR_ERR(rt);
 57                 if (err == -ENETUNREACH)
 58                         IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
 59                 goto out;
 60         }
 61 
 62         if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) {
 63                 ip_rt_put(rt);
 64                 err = -EACCES;
 65                 goto out;
 66         }
 67         if (!inet->inet_saddr)
 68                 inet->inet_saddr = fl4->saddr;  /* Update source address */
 69         if (!inet->inet_rcv_saddr) {
 70                 inet->inet_rcv_saddr = fl4->saddr;
 71                 if (sk->sk_prot->rehash)
 72                         sk->sk_prot->rehash(sk);
 73         }
 74         inet->inet_daddr = fl4->daddr;
 75         inet->inet_dport = usin->sin_port;
 76         sk->sk_state = TCP_ESTABLISHED;
 77         sk_set_txhash(sk);
 78         inet->inet_id = jiffies;
 79 
 80         sk_dst_set(sk, &rt->dst);
 81         err = 0;
 82 out:
 83         return err;
 84 }
 85 EXPORT_SYMBOL(__ip4_datagram_connect);
 86 
 87 int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 88 {
 89         int res;
 90 
 91         lock_sock(sk);
 92         res = __ip4_datagram_connect(sk, uaddr, addr_len);
 93         release_sock(sk);
 94         return res;
 95 }
 96 EXPORT_SYMBOL(ip4_datagram_connect);
 97 
 98 /* Because UDP xmit path can manipulate sk_dst_cache without holding
 99  * socket lock, we need to use sk_dst_set() here,
100  * even if we own the socket lock.
101  */
102 void ip4_datagram_release_cb(struct sock *sk)
103 {
104         const struct inet_sock *inet = inet_sk(sk);
105         const struct ip_options_rcu *inet_opt;
106         __be32 daddr = inet->inet_daddr;
107         struct dst_entry *dst;
108         struct flowi4 fl4;
109         struct rtable *rt;
110 
111         rcu_read_lock();
112 
113         dst = __sk_dst_get(sk);
114         if (!dst || !dst->obsolete || dst->ops->check(dst, 0)) {
115                 rcu_read_unlock();
116                 return;
117         }
118         inet_opt = rcu_dereference(inet->inet_opt);
119         if (inet_opt && inet_opt->opt.srr)
120                 daddr = inet_opt->opt.faddr;
121         rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr,
122                                    inet->inet_saddr, inet->inet_dport,
123                                    inet->inet_sport, sk->sk_protocol,
124                                    RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
125 
126         dst = !IS_ERR(rt) ? &rt->dst : NULL;
127         sk_dst_set(sk, dst);
128 
129         rcu_read_unlock();
130 }
131 EXPORT_SYMBOL_GPL(ip4_datagram_release_cb);
132 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp