LCOV - code coverage report
Current view: top level - net/ipv4 - raw.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 50 559 8.9 %
Date: 2021-04-22 12:43:58 Functions: 9 40 22.5 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * INET         An implementation of the TCP/IP protocol suite for the LINUX
       4             :  *              operating system.  INET is implemented using the  BSD Socket
       5             :  *              interface as the means of communication with the user level.
       6             :  *
       7             :  *              RAW - implementation of IP "raw" sockets.
       8             :  *
       9             :  * Authors:     Ross Biro
      10             :  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
      11             :  *
      12             :  * Fixes:
      13             :  *              Alan Cox        :       verify_area() fixed up
      14             :  *              Alan Cox        :       ICMP error handling
      15             :  *              Alan Cox        :       EMSGSIZE if you send too big a packet
      16             :  *              Alan Cox        :       Now uses generic datagrams and shared
      17             :  *                                      skbuff library. No more peek crashes,
      18             :  *                                      no more backlogs
      19             :  *              Alan Cox        :       Checks sk->broadcast.
      20             :  *              Alan Cox        :       Uses skb_free_datagram/skb_copy_datagram
      21             :  *              Alan Cox        :       Raw passes ip options too
      22             :  *              Alan Cox        :       Setsocketopt added
      23             :  *              Alan Cox        :       Fixed error return for broadcasts
      24             :  *              Alan Cox        :       Removed wake_up calls
      25             :  *              Alan Cox        :       Use ttl/tos
      26             :  *              Alan Cox        :       Cleaned up old debugging
      27             :  *              Alan Cox        :       Use new kernel side addresses
      28             :  *      Arnt Gulbrandsen        :       Fixed MSG_DONTROUTE in raw sockets.
      29             :  *              Alan Cox        :       BSD style RAW socket demultiplexing.
      30             :  *              Alan Cox        :       Beginnings of mrouted support.
      31             :  *              Alan Cox        :       Added IP_HDRINCL option.
      32             :  *              Alan Cox        :       Skip broadcast check if BSDism set.
      33             :  *              David S. Miller :       New socket lookup architecture.
      34             :  */
      35             : 
      36             : #include <linux/types.h>
      37             : #include <linux/atomic.h>
      38             : #include <asm/byteorder.h>
      39             : #include <asm/current.h>
      40             : #include <linux/uaccess.h>
      41             : #include <asm/ioctls.h>
      42             : #include <linux/stddef.h>
      43             : #include <linux/slab.h>
      44             : #include <linux/errno.h>
      45             : #include <linux/kernel.h>
      46             : #include <linux/export.h>
      47             : #include <linux/spinlock.h>
      48             : #include <linux/sockios.h>
      49             : #include <linux/socket.h>
      50             : #include <linux/in.h>
      51             : #include <linux/mroute.h>
      52             : #include <linux/netdevice.h>
      53             : #include <linux/in_route.h>
      54             : #include <linux/route.h>
      55             : #include <linux/skbuff.h>
      56             : #include <linux/igmp.h>
      57             : #include <net/net_namespace.h>
      58             : #include <net/dst.h>
      59             : #include <net/sock.h>
      60             : #include <linux/ip.h>
      61             : #include <linux/net.h>
      62             : #include <net/ip.h>
      63             : #include <net/icmp.h>
      64             : #include <net/udp.h>
      65             : #include <net/raw.h>
      66             : #include <net/snmp.h>
      67             : #include <net/tcp_states.h>
      68             : #include <net/inet_common.h>
      69             : #include <net/checksum.h>
      70             : #include <net/xfrm.h>
      71             : #include <linux/rtnetlink.h>
      72             : #include <linux/proc_fs.h>
      73             : #include <linux/seq_file.h>
      74             : #include <linux/netfilter.h>
      75             : #include <linux/netfilter_ipv4.h>
      76             : #include <linux/compat.h>
      77             : #include <linux/uio.h>
      78             : 
      79             : struct raw_frag_vec {
      80             :         struct msghdr *msg;
      81             :         union {
      82             :                 struct icmphdr icmph;
      83             :                 char c[1];
      84             :         } hdr;
      85             :         int hlen;
      86             : };
      87             : 
      88             : struct raw_hashinfo raw_v4_hashinfo = {
      89             :         .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock),
      90             : };
      91             : EXPORT_SYMBOL_GPL(raw_v4_hashinfo);
      92             : 
      93           8 : int raw_hash_sk(struct sock *sk)
      94             : {
      95           8 :         struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
      96           8 :         struct hlist_head *head;
      97             : 
      98           8 :         head = &h->ht[inet_sk(sk)->inet_num & (RAW_HTABLE_SIZE - 1)];
      99             : 
     100           8 :         write_lock_bh(&h->lock);
     101           8 :         sk_add_node(sk, head);
     102           8 :         sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
     103           8 :         write_unlock_bh(&h->lock);
     104             : 
     105           8 :         return 0;
     106             : }
     107             : EXPORT_SYMBOL_GPL(raw_hash_sk);
     108             : 
     109           8 : void raw_unhash_sk(struct sock *sk)
     110             : {
     111           8 :         struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
     112             : 
     113           8 :         write_lock_bh(&h->lock);
     114           8 :         if (sk_del_node_init(sk))
     115           8 :                 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
     116           8 :         write_unlock_bh(&h->lock);
     117           8 : }
     118             : EXPORT_SYMBOL_GPL(raw_unhash_sk);
     119             : 
     120           0 : struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
     121             :                              unsigned short num, __be32 raddr, __be32 laddr,
     122             :                              int dif, int sdif)
     123             : {
     124           0 :         sk_for_each_from(sk) {
     125           0 :                 struct inet_sock *inet = inet_sk(sk);
     126             : 
     127           0 :                 if (net_eq(sock_net(sk), net) && inet->inet_num == num       &&
     128           0 :                     !(inet->inet_daddr && inet->inet_daddr != raddr)      &&
     129           0 :                     !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
     130           0 :                     raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
     131           0 :                         goto found; /* gotcha */
     132             :         }
     133             :         sk = NULL;
     134           0 : found:
     135           0 :         return sk;
     136             : }
     137             : EXPORT_SYMBOL_GPL(__raw_v4_lookup);
     138             : 
     139             : /*
     140             :  *      0 - deliver
     141             :  *      1 - block
     142             :  */
     143           0 : static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
     144             : {
     145           0 :         struct icmphdr _hdr;
     146           0 :         const struct icmphdr *hdr;
     147             : 
     148           0 :         hdr = skb_header_pointer(skb, skb_transport_offset(skb),
     149             :                                  sizeof(_hdr), &_hdr);
     150           0 :         if (!hdr)
     151             :                 return 1;
     152             : 
     153           0 :         if (hdr->type < 32) {
     154           0 :                 __u32 data = raw_sk(sk)->filter.data;
     155             : 
     156           0 :                 return ((1U << hdr->type) & data) != 0;
     157             :         }
     158             : 
     159             :         /* Do not block unknown ICMP types */
     160             :         return 0;
     161             : }
     162             : 
     163             : /* IP input processing comes here for RAW socket delivery.
     164             :  * Caller owns SKB, so we must make clones.
     165             :  *
     166             :  * RFC 1122: SHOULD pass TOS value up to the transport layer.
     167             :  * -> It does. And not only TOS, but all IP header.
     168             :  */
     169           0 : static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
     170             : {
     171           0 :         int sdif = inet_sdif(skb);
     172           0 :         int dif = inet_iif(skb);
     173           0 :         struct sock *sk;
     174           0 :         struct hlist_head *head;
     175           0 :         int delivered = 0;
     176           0 :         struct net *net;
     177             : 
     178           0 :         read_lock(&raw_v4_hashinfo.lock);
     179           0 :         head = &raw_v4_hashinfo.ht[hash];
     180           0 :         if (hlist_empty(head))
     181           0 :                 goto out;
     182             : 
     183           0 :         net = dev_net(skb->dev);
     184           0 :         sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
     185             :                              iph->saddr, iph->daddr, dif, sdif);
     186             : 
     187           0 :         while (sk) {
     188           0 :                 delivered = 1;
     189           0 :                 if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) &&
     190           0 :                     ip_mc_sf_allow(sk, iph->daddr, iph->saddr,
     191           0 :                                    skb->dev->ifindex, sdif)) {
     192           0 :                         struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
     193             : 
     194             :                         /* Not releasing hash table! */
     195           0 :                         if (clone)
     196           0 :                                 raw_rcv(sk, clone);
     197             :                 }
     198           0 :                 sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
     199             :                                      iph->saddr, iph->daddr,
     200             :                                      dif, sdif);
     201             :         }
     202           0 : out:
     203           0 :         read_unlock(&raw_v4_hashinfo.lock);
     204           0 :         return delivered;
     205             : }
     206             : 
     207         454 : int raw_local_deliver(struct sk_buff *skb, int protocol)
     208             : {
     209         454 :         int hash;
     210         454 :         struct sock *raw_sk;
     211             : 
     212         454 :         hash = protocol & (RAW_HTABLE_SIZE - 1);
     213         454 :         raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
     214             : 
     215             :         /* If there maybe a raw socket we must check - if not we
     216             :          * don't care less
     217             :          */
     218           0 :         if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
     219           0 :                 raw_sk = NULL;
     220             : 
     221         454 :         return raw_sk != NULL;
     222             : 
     223             : }
     224             : 
     225           0 : static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
     226             : {
     227           0 :         struct inet_sock *inet = inet_sk(sk);
     228           0 :         const int type = icmp_hdr(skb)->type;
     229           0 :         const int code = icmp_hdr(skb)->code;
     230           0 :         int err = 0;
     231           0 :         int harderr = 0;
     232             : 
     233           0 :         if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
     234           0 :                 ipv4_sk_update_pmtu(skb, sk, info);
     235           0 :         else if (type == ICMP_REDIRECT) {
     236           0 :                 ipv4_sk_redirect(skb, sk);
     237           0 :                 return;
     238             :         }
     239             : 
     240             :         /* Report error on raw socket, if:
     241             :            1. User requested ip_recverr.
     242             :            2. Socket is connected (otherwise the error indication
     243             :               is useless without ip_recverr and error is hard.
     244             :          */
     245           0 :         if (!inet->recverr && sk->sk_state != TCP_ESTABLISHED)
     246             :                 return;
     247             : 
     248           0 :         switch (type) {
     249             :         default:
     250             :         case ICMP_TIME_EXCEEDED:
     251             :                 err = EHOSTUNREACH;
     252             :                 break;
     253             :         case ICMP_SOURCE_QUENCH:
     254             :                 return;
     255           0 :         case ICMP_PARAMETERPROB:
     256           0 :                 err = EPROTO;
     257           0 :                 harderr = 1;
     258           0 :                 break;
     259           0 :         case ICMP_DEST_UNREACH:
     260           0 :                 err = EHOSTUNREACH;
     261           0 :                 if (code > NR_ICMP_UNREACH)
     262             :                         break;
     263           0 :                 if (code == ICMP_FRAG_NEEDED) {
     264           0 :                         harderr = inet->pmtudisc != IP_PMTUDISC_DONT;
     265           0 :                         err = EMSGSIZE;
     266             :                 } else {
     267           0 :                         err = icmp_err_convert[code].errno;
     268           0 :                         harderr = icmp_err_convert[code].fatal;
     269             :                 }
     270             :         }
     271             : 
     272           0 :         if (inet->recverr) {
     273           0 :                 const struct iphdr *iph = (const struct iphdr *)skb->data;
     274           0 :                 u8 *payload = skb->data + (iph->ihl << 2);
     275             : 
     276           0 :                 if (inet->hdrincl)
     277           0 :                         payload = skb->data;
     278           0 :                 ip_icmp_error(sk, skb, err, 0, info, payload);
     279             :         }
     280             : 
     281           0 :         if (inet->recverr || harderr) {
     282           0 :                 sk->sk_err = err;
     283           0 :                 sk->sk_error_report(sk);
     284             :         }
     285             : }
     286             : 
     287          14 : void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
     288             : {
     289          14 :         int hash;
     290          14 :         struct sock *raw_sk;
     291          14 :         const struct iphdr *iph;
     292          14 :         struct net *net;
     293             : 
     294          14 :         hash = protocol & (RAW_HTABLE_SIZE - 1);
     295             : 
     296          14 :         read_lock(&raw_v4_hashinfo.lock);
     297          14 :         raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
     298           0 :         if (raw_sk) {
     299           0 :                 int dif = skb->dev->ifindex;
     300           0 :                 int sdif = inet_sdif(skb);
     301             : 
     302           0 :                 iph = (const struct iphdr *)skb->data;
     303           0 :                 net = dev_net(skb->dev);
     304             : 
     305           0 :                 while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
     306             :                                                 iph->daddr, iph->saddr,
     307             :                                                 dif, sdif)) != NULL) {
     308           0 :                         raw_err(raw_sk, skb, info);
     309           0 :                         raw_sk = sk_next(raw_sk);
     310           0 :                         iph = (const struct iphdr *)skb->data;
     311             :                 }
     312             :         }
     313          14 :         read_unlock(&raw_v4_hashinfo.lock);
     314          14 : }
     315             : 
     316           0 : static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb)
     317             : {
     318             :         /* Charge it to the socket. */
     319             : 
     320           0 :         ipv4_pktinfo_prepare(sk, skb);
     321           0 :         if (sock_queue_rcv_skb(sk, skb) < 0) {
     322           0 :                 kfree_skb(skb);
     323           0 :                 return NET_RX_DROP;
     324             :         }
     325             : 
     326             :         return NET_RX_SUCCESS;
     327             : }
     328             : 
     329           0 : int raw_rcv(struct sock *sk, struct sk_buff *skb)
     330             : {
     331           0 :         if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
     332             :                 atomic_inc(&sk->sk_drops);
     333             :                 kfree_skb(skb);
     334             :                 return NET_RX_DROP;
     335             :         }
     336           0 :         nf_reset_ct(skb);
     337             : 
     338           0 :         skb_push(skb, skb->data - skb_network_header(skb));
     339             : 
     340           0 :         raw_rcv_skb(sk, skb);
     341           0 :         return 0;
     342             : }
     343             : 
     344           0 : static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
     345             :                            struct msghdr *msg, size_t length,
     346             :                            struct rtable **rtp, unsigned int flags,
     347             :                            const struct sockcm_cookie *sockc)
     348             : {
     349           0 :         struct inet_sock *inet = inet_sk(sk);
     350           0 :         struct net *net = sock_net(sk);
     351           0 :         struct iphdr *iph;
     352           0 :         struct sk_buff *skb;
     353           0 :         unsigned int iphlen;
     354           0 :         int err;
     355           0 :         struct rtable *rt = *rtp;
     356           0 :         int hlen, tlen;
     357             : 
     358           0 :         if (length > rt->dst.dev->mtu) {
     359           0 :                 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport,
     360             :                                rt->dst.dev->mtu);
     361           0 :                 return -EMSGSIZE;
     362             :         }
     363           0 :         if (length < sizeof(struct iphdr))
     364             :                 return -EINVAL;
     365             : 
     366           0 :         if (flags&MSG_PROBE)
     367           0 :                 goto out;
     368             : 
     369           0 :         hlen = LL_RESERVED_SPACE(rt->dst.dev);
     370           0 :         tlen = rt->dst.dev->needed_tailroom;
     371           0 :         skb = sock_alloc_send_skb(sk,
     372           0 :                                   length + hlen + tlen + 15,
     373           0 :                                   flags & MSG_DONTWAIT, &err);
     374           0 :         if (!skb)
     375           0 :                 goto error;
     376           0 :         skb_reserve(skb, hlen);
     377             : 
     378           0 :         skb->priority = sk->sk_priority;
     379           0 :         skb->mark = sockc->mark;
     380           0 :         skb->tstamp = sockc->transmit_time;
     381           0 :         skb_dst_set(skb, &rt->dst);
     382           0 :         *rtp = NULL;
     383             : 
     384           0 :         skb_reset_network_header(skb);
     385           0 :         iph = ip_hdr(skb);
     386           0 :         skb_put(skb, length);
     387             : 
     388           0 :         skb->ip_summed = CHECKSUM_NONE;
     389             : 
     390           0 :         skb_setup_tx_timestamp(skb, sockc->tsflags);
     391             : 
     392           0 :         if (flags & MSG_CONFIRM)
     393           0 :                 skb_set_dst_pending_confirm(skb, 1);
     394             : 
     395           0 :         skb->transport_header = skb->network_header;
     396           0 :         err = -EFAULT;
     397           0 :         if (memcpy_from_msg(iph, msg, length))
     398           0 :                 goto error_free;
     399             : 
     400           0 :         iphlen = iph->ihl * 4;
     401             : 
     402             :         /*
     403             :          * We don't want to modify the ip header, but we do need to
     404             :          * be sure that it won't cause problems later along the network
     405             :          * stack.  Specifically we want to make sure that iph->ihl is a
     406             :          * sane value.  If ihl points beyond the length of the buffer passed
     407             :          * in, reject the frame as invalid
     408             :          */
     409           0 :         err = -EINVAL;
     410           0 :         if (iphlen > length)
     411           0 :                 goto error_free;
     412             : 
     413           0 :         if (iphlen >= sizeof(*iph)) {
     414           0 :                 if (!iph->saddr)
     415           0 :                         iph->saddr = fl4->saddr;
     416           0 :                 iph->check   = 0;
     417           0 :                 iph->tot_len = htons(length);
     418           0 :                 if (!iph->id)
     419           0 :                         ip_select_ident(net, skb, NULL);
     420             : 
     421           0 :                 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
     422           0 :                 skb->transport_header += iphlen;
     423           0 :                 if (iph->protocol == IPPROTO_ICMP &&
     424           0 :                     length >= iphlen + sizeof(struct icmphdr))
     425           0 :                         icmp_out_count(net, ((struct icmphdr *)
     426           0 :                                 skb_transport_header(skb))->type);
     427             :         }
     428             : 
     429           0 :         err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
     430             :                       net, sk, skb, NULL, rt->dst.dev,
     431             :                       dst_output);
     432           0 :         if (err > 0)
     433           0 :                 err = net_xmit_errno(err);
     434           0 :         if (err)
     435           0 :                 goto error;
     436           0 : out:
     437             :         return 0;
     438             : 
     439           0 : error_free:
     440           0 :         kfree_skb(skb);
     441           0 : error:
     442           0 :         IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
     443           0 :         if (err == -ENOBUFS && !inet->recverr)
     444           0 :                 err = 0;
     445           0 :         return err;
     446             : }
     447             : 
     448           0 : static int raw_probe_proto_opt(struct raw_frag_vec *rfv, struct flowi4 *fl4)
     449             : {
     450           0 :         int err;
     451             : 
     452           0 :         if (fl4->flowi4_proto != IPPROTO_ICMP)
     453             :                 return 0;
     454             : 
     455             :         /* We only need the first two bytes. */
     456           0 :         rfv->hlen = 2;
     457             : 
     458           0 :         err = memcpy_from_msg(rfv->hdr.c, rfv->msg, rfv->hlen);
     459           0 :         if (err)
     460             :                 return err;
     461             : 
     462           0 :         fl4->fl4_icmp_type = rfv->hdr.icmph.type;
     463           0 :         fl4->fl4_icmp_code = rfv->hdr.icmph.code;
     464             : 
     465           0 :         return 0;
     466             : }
     467             : 
     468           0 : static int raw_getfrag(void *from, char *to, int offset, int len, int odd,
     469             :                        struct sk_buff *skb)
     470             : {
     471           0 :         struct raw_frag_vec *rfv = from;
     472             : 
     473           0 :         if (offset < rfv->hlen) {
     474           0 :                 int copy = min(rfv->hlen - offset, len);
     475             : 
     476           0 :                 if (skb->ip_summed == CHECKSUM_PARTIAL)
     477           0 :                         memcpy(to, rfv->hdr.c + offset, copy);
     478             :                 else
     479           0 :                         skb->csum = csum_block_add(
     480             :                                 skb->csum,
     481           0 :                                 csum_partial_copy_nocheck(rfv->hdr.c + offset,
     482             :                                                           to, copy),
     483             :                                 odd);
     484             : 
     485           0 :                 odd = 0;
     486           0 :                 offset += copy;
     487           0 :                 to += copy;
     488           0 :                 len -= copy;
     489             : 
     490           0 :                 if (!len)
     491             :                         return 0;
     492             :         }
     493             : 
     494           0 :         offset -= rfv->hlen;
     495             : 
     496           0 :         return ip_generic_getfrag(rfv->msg, to, offset, len, odd, skb);
     497             : }
     498             : 
     499           0 : static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
     500             : {
     501           0 :         struct inet_sock *inet = inet_sk(sk);
     502           0 :         struct net *net = sock_net(sk);
     503           0 :         struct ipcm_cookie ipc;
     504           0 :         struct rtable *rt = NULL;
     505           0 :         struct flowi4 fl4;
     506           0 :         int free = 0;
     507           0 :         __be32 daddr;
     508           0 :         __be32 saddr;
     509           0 :         u8  tos;
     510           0 :         int err;
     511           0 :         struct ip_options_data opt_copy;
     512           0 :         struct raw_frag_vec rfv;
     513           0 :         int hdrincl;
     514             : 
     515           0 :         err = -EMSGSIZE;
     516           0 :         if (len > 0xFFFF)
     517           0 :                 goto out;
     518             : 
     519             :         /* hdrincl should be READ_ONCE(inet->hdrincl)
     520             :          * but READ_ONCE() doesn't work with bit fields.
     521             :          * Doing this indirectly yields the same result.
     522             :          */
     523           0 :         hdrincl = inet->hdrincl;
     524           0 :         hdrincl = READ_ONCE(hdrincl);
     525             :         /*
     526             :          *      Check the flags.
     527             :          */
     528             : 
     529           0 :         err = -EOPNOTSUPP;
     530           0 :         if (msg->msg_flags & MSG_OOB)    /* Mirror BSD error message */
     531           0 :                 goto out;               /* compatibility */
     532             : 
     533             :         /*
     534             :          *      Get and verify the address.
     535             :          */
     536             : 
     537           0 :         if (msg->msg_namelen) {
     538           0 :                 DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
     539           0 :                 err = -EINVAL;
     540           0 :                 if (msg->msg_namelen < sizeof(*usin))
     541           0 :                         goto out;
     542           0 :                 if (usin->sin_family != AF_INET) {
     543           0 :                         pr_info_once("%s: %s forgot to set AF_INET. Fix it!\n",
     544             :                                      __func__, current->comm);
     545           0 :                         err = -EAFNOSUPPORT;
     546           0 :                         if (usin->sin_family)
     547           0 :                                 goto out;
     548             :                 }
     549           0 :                 daddr = usin->sin_addr.s_addr;
     550             :                 /* ANK: I did not forget to get protocol from port field.
     551             :                  * I just do not know, who uses this weirdness.
     552             :                  * IP_HDRINCL is much more convenient.
     553             :                  */
     554             :         } else {
     555           0 :                 err = -EDESTADDRREQ;
     556           0 :                 if (sk->sk_state != TCP_ESTABLISHED)
     557           0 :                         goto out;
     558           0 :                 daddr = inet->inet_daddr;
     559             :         }
     560             : 
     561           0 :         ipcm_init_sk(&ipc, inet);
     562             : 
     563           0 :         if (msg->msg_controllen) {
     564           0 :                 err = ip_cmsg_send(sk, msg, &ipc, false);
     565           0 :                 if (unlikely(err)) {
     566           0 :                         kfree(ipc.opt);
     567           0 :                         goto out;
     568             :                 }
     569           0 :                 if (ipc.opt)
     570           0 :                         free = 1;
     571             :         }
     572             : 
     573           0 :         saddr = ipc.addr;
     574           0 :         ipc.addr = daddr;
     575             : 
     576           0 :         if (!ipc.opt) {
     577           0 :                 struct ip_options_rcu *inet_opt;
     578             : 
     579           0 :                 rcu_read_lock();
     580           0 :                 inet_opt = rcu_dereference(inet->inet_opt);
     581           0 :                 if (inet_opt) {
     582           0 :                         memcpy(&opt_copy, inet_opt,
     583           0 :                                sizeof(*inet_opt) + inet_opt->opt.optlen);
     584           0 :                         ipc.opt = &opt_copy.opt;
     585             :                 }
     586           0 :                 rcu_read_unlock();
     587             :         }
     588             : 
     589           0 :         if (ipc.opt) {
     590           0 :                 err = -EINVAL;
     591             :                 /* Linux does not mangle headers on raw sockets,
     592             :                  * so that IP options + IP_HDRINCL is non-sense.
     593             :                  */
     594           0 :                 if (hdrincl)
     595           0 :                         goto done;
     596           0 :                 if (ipc.opt->opt.srr) {
     597           0 :                         if (!daddr)
     598           0 :                                 goto done;
     599           0 :                         daddr = ipc.opt->opt.faddr;
     600             :                 }
     601             :         }
     602           0 :         tos = get_rtconn_flags(&ipc, sk);
     603           0 :         if (msg->msg_flags & MSG_DONTROUTE)
     604           0 :                 tos |= RTO_ONLINK;
     605             : 
     606           0 :         if (ipv4_is_multicast(daddr)) {
     607           0 :                 if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
     608           0 :                         ipc.oif = inet->mc_index;
     609           0 :                 if (!saddr)
     610           0 :                         saddr = inet->mc_addr;
     611           0 :         } else if (!ipc.oif) {
     612           0 :                 ipc.oif = inet->uc_index;
     613           0 :         } else if (ipv4_is_lbcast(daddr) && inet->uc_index) {
     614             :                 /* oif is set, packet is to local broadcast
     615             :                  * and uc_index is set. oif is most likely set
     616             :                  * by sk_bound_dev_if. If uc_index != oif check if the
     617             :                  * oif is an L3 master and uc_index is an L3 slave.
     618             :                  * If so, we want to allow the send using the uc_index.
     619             :                  */
     620             :                 if (ipc.oif != inet->uc_index &&
     621           0 :                     ipc.oif == l3mdev_master_ifindex_by_index(sock_net(sk),
     622             :                                                               inet->uc_index)) {
     623             :                         ipc.oif = inet->uc_index;
     624             :                 }
     625             :         }
     626             : 
     627           0 :         flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
     628             :                            RT_SCOPE_UNIVERSE,
     629           0 :                            hdrincl ? IPPROTO_RAW : sk->sk_protocol,
     630           0 :                            inet_sk_flowi_flags(sk) |
     631           0 :                             (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
     632             :                            daddr, saddr, 0, 0, sk->sk_uid);
     633             : 
     634           0 :         if (!hdrincl) {
     635           0 :                 rfv.msg = msg;
     636           0 :                 rfv.hlen = 0;
     637             : 
     638           0 :                 err = raw_probe_proto_opt(&rfv, &fl4);
     639           0 :                 if (err)
     640           0 :                         goto done;
     641             :         }
     642             : 
     643           0 :         security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
     644           0 :         rt = ip_route_output_flow(net, &fl4, sk);
     645           0 :         if (IS_ERR(rt)) {
     646           0 :                 err = PTR_ERR(rt);
     647           0 :                 rt = NULL;
     648           0 :                 goto done;
     649             :         }
     650             : 
     651           0 :         err = -EACCES;
     652           0 :         if (rt->rt_flags & RTCF_BROADCAST && !sock_flag(sk, SOCK_BROADCAST))
     653           0 :                 goto done;
     654             : 
     655           0 :         if (msg->msg_flags & MSG_CONFIRM)
     656           0 :                 goto do_confirm;
     657           0 : back_from_confirm:
     658             : 
     659           0 :         if (hdrincl)
     660           0 :                 err = raw_send_hdrinc(sk, &fl4, msg, len,
     661             :                                       &rt, msg->msg_flags, &ipc.sockc);
     662             : 
     663             :          else {
     664           0 :                 if (!ipc.addr)
     665           0 :                         ipc.addr = fl4.daddr;
     666           0 :                 lock_sock(sk);
     667           0 :                 err = ip_append_data(sk, &fl4, raw_getfrag,
     668             :                                      &rfv, len, 0,
     669             :                                      &ipc, &rt, msg->msg_flags);
     670           0 :                 if (err)
     671           0 :                         ip_flush_pending_frames(sk);
     672           0 :                 else if (!(msg->msg_flags & MSG_MORE)) {
     673           0 :                         err = ip_push_pending_frames(sk, &fl4);
     674           0 :                         if (err == -ENOBUFS && !inet->recverr)
     675           0 :                                 err = 0;
     676             :                 }
     677           0 :                 release_sock(sk);
     678             :         }
     679           0 : done:
     680           0 :         if (free)
     681           0 :                 kfree(ipc.opt);
     682           0 :         ip_rt_put(rt);
     683             : 
     684           0 : out:
     685           0 :         if (err < 0)
     686           0 :                 return err;
     687           0 :         return len;
     688             : 
     689           0 : do_confirm:
     690           0 :         if (msg->msg_flags & MSG_PROBE)
     691           0 :                 dst_confirm_neigh(&rt->dst, &fl4.daddr);
     692           0 :         if (!(msg->msg_flags & MSG_PROBE) || len)
     693           0 :                 goto back_from_confirm;
     694           0 :         err = 0;
     695           0 :         goto done;
     696             : }
     697             : 
     698           0 : static void raw_close(struct sock *sk, long timeout)
     699             : {
     700             :         /*
     701             :          * Raw sockets may have direct kernel references. Kill them.
     702             :          */
     703           0 :         ip_ra_control(sk, 0, NULL);
     704             : 
     705           0 :         sk_common_release(sk);
     706           0 : }
     707             : 
     708           0 : static void raw_destroy(struct sock *sk)
     709             : {
     710           0 :         lock_sock(sk);
     711           0 :         ip_flush_pending_frames(sk);
     712           0 :         release_sock(sk);
     713           0 : }
     714             : 
     715             : /* This gets rid of all the nasties in af_inet. -DaveM */
     716           0 : static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
     717             : {
     718           0 :         struct inet_sock *inet = inet_sk(sk);
     719           0 :         struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
     720           0 :         u32 tb_id = RT_TABLE_LOCAL;
     721           0 :         int ret = -EINVAL;
     722           0 :         int chk_addr_ret;
     723             : 
     724           0 :         if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
     725           0 :                 goto out;
     726             : 
     727           0 :         if (sk->sk_bound_dev_if)
     728           0 :                 tb_id = l3mdev_fib_table_by_index(sock_net(sk),
     729             :                                                  sk->sk_bound_dev_if) ? : tb_id;
     730             : 
     731           0 :         chk_addr_ret = inet_addr_type_table(sock_net(sk), addr->sin_addr.s_addr,
     732             :                                             tb_id);
     733             : 
     734           0 :         ret = -EADDRNOTAVAIL;
     735           0 :         if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
     736           0 :             chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
     737           0 :                 goto out;
     738           0 :         inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
     739           0 :         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
     740           0 :                 inet->inet_saddr = 0;  /* Use device */
     741           0 :         sk_dst_reset(sk);
     742           0 :         ret = 0;
     743           0 : out:    return ret;
     744             : }
     745             : 
     746             : /*
     747             :  *      This should be easy, if there is something there
     748             :  *      we return it, otherwise we block.
     749             :  */
     750             : 
     751           0 : static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
     752             :                        int noblock, int flags, int *addr_len)
     753             : {
     754           0 :         struct inet_sock *inet = inet_sk(sk);
     755           0 :         size_t copied = 0;
     756           0 :         int err = -EOPNOTSUPP;
     757           0 :         DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
     758           0 :         struct sk_buff *skb;
     759             : 
     760           0 :         if (flags & MSG_OOB)
     761           0 :                 goto out;
     762             : 
     763           0 :         if (flags & MSG_ERRQUEUE) {
     764           0 :                 err = ip_recv_error(sk, msg, len, addr_len);
     765           0 :                 goto out;
     766             :         }
     767             : 
     768           0 :         skb = skb_recv_datagram(sk, flags, noblock, &err);
     769           0 :         if (!skb)
     770           0 :                 goto out;
     771             : 
     772           0 :         copied = skb->len;
     773           0 :         if (len < copied) {
     774           0 :                 msg->msg_flags |= MSG_TRUNC;
     775           0 :                 copied = len;
     776             :         }
     777             : 
     778           0 :         err = skb_copy_datagram_msg(skb, 0, msg, copied);
     779           0 :         if (err)
     780           0 :                 goto done;
     781             : 
     782           0 :         sock_recv_ts_and_drops(msg, sk, skb);
     783             : 
     784             :         /* Copy the address. */
     785           0 :         if (sin) {
     786           0 :                 sin->sin_family = AF_INET;
     787           0 :                 sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
     788           0 :                 sin->sin_port = 0;
     789           0 :                 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
     790           0 :                 *addr_len = sizeof(*sin);
     791             :         }
     792           0 :         if (inet->cmsg_flags)
     793           0 :                 ip_cmsg_recv(msg, skb);
     794           0 :         if (flags & MSG_TRUNC)
     795           0 :                 copied = skb->len;
     796           0 : done:
     797           0 :         skb_free_datagram(sk, skb);
     798           0 : out:
     799           0 :         if (err)
     800             :                 return err;
     801           0 :         return copied;
     802             : }
     803             : 
     804           8 : static int raw_sk_init(struct sock *sk)
     805             : {
     806           8 :         struct raw_sock *rp = raw_sk(sk);
     807             : 
     808           8 :         if (inet_sk(sk)->inet_num == IPPROTO_ICMP)
     809           4 :                 memset(&rp->filter, 0, sizeof(rp->filter));
     810           8 :         return 0;
     811             : }
     812             : 
     813           0 : static int raw_seticmpfilter(struct sock *sk, sockptr_t optval, int optlen)
     814             : {
     815           0 :         if (optlen > sizeof(struct icmp_filter))
     816           0 :                 optlen = sizeof(struct icmp_filter);
     817           0 :         if (copy_from_sockptr(&raw_sk(sk)->filter, optval, optlen))
     818           0 :                 return -EFAULT;
     819             :         return 0;
     820             : }
     821             : 
     822           0 : static int raw_geticmpfilter(struct sock *sk, char __user *optval, int __user *optlen)
     823             : {
     824           0 :         int len, ret = -EFAULT;
     825             : 
     826           0 :         if (get_user(len, optlen))
     827           0 :                 goto out;
     828           0 :         ret = -EINVAL;
     829           0 :         if (len < 0)
     830           0 :                 goto out;
     831           0 :         if (len > sizeof(struct icmp_filter))
     832           0 :                 len = sizeof(struct icmp_filter);
     833           0 :         ret = -EFAULT;
     834           0 :         if (put_user(len, optlen) ||
     835           0 :             copy_to_user(optval, &raw_sk(sk)->filter, len))
     836           0 :                 goto out;
     837             :         ret = 0;
     838           0 : out:    return ret;
     839             : }
     840             : 
     841           0 : static int do_raw_setsockopt(struct sock *sk, int level, int optname,
     842             :                              sockptr_t optval, unsigned int optlen)
     843             : {
     844           0 :         if (optname == ICMP_FILTER) {
     845           0 :                 if (inet_sk(sk)->inet_num != IPPROTO_ICMP)
     846             :                         return -EOPNOTSUPP;
     847             :                 else
     848           0 :                         return raw_seticmpfilter(sk, optval, optlen);
     849             :         }
     850             :         return -ENOPROTOOPT;
     851             : }
     852             : 
     853           0 : static int raw_setsockopt(struct sock *sk, int level, int optname,
     854             :                           sockptr_t optval, unsigned int optlen)
     855             : {
     856           0 :         if (level != SOL_RAW)
     857           0 :                 return ip_setsockopt(sk, level, optname, optval, optlen);
     858           0 :         return do_raw_setsockopt(sk, level, optname, optval, optlen);
     859             : }
     860             : 
     861           0 : static int do_raw_getsockopt(struct sock *sk, int level, int optname,
     862             :                           char __user *optval, int __user *optlen)
     863             : {
     864           0 :         if (optname == ICMP_FILTER) {
     865           0 :                 if (inet_sk(sk)->inet_num != IPPROTO_ICMP)
     866             :                         return -EOPNOTSUPP;
     867             :                 else
     868           0 :                         return raw_geticmpfilter(sk, optval, optlen);
     869             :         }
     870             :         return -ENOPROTOOPT;
     871             : }
     872             : 
     873           0 : static int raw_getsockopt(struct sock *sk, int level, int optname,
     874             :                           char __user *optval, int __user *optlen)
     875             : {
     876           0 :         if (level != SOL_RAW)
     877           0 :                 return ip_getsockopt(sk, level, optname, optval, optlen);
     878           0 :         return do_raw_getsockopt(sk, level, optname, optval, optlen);
     879             : }
     880             : 
     881           0 : static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
     882             : {
     883           0 :         switch (cmd) {
     884             :         case SIOCOUTQ: {
     885           0 :                 int amount = sk_wmem_alloc_get(sk);
     886             : 
     887           0 :                 return put_user(amount, (int __user *)arg);
     888             :         }
     889           0 :         case SIOCINQ: {
     890           0 :                 struct sk_buff *skb;
     891           0 :                 int amount = 0;
     892             : 
     893           0 :                 spin_lock_bh(&sk->sk_receive_queue.lock);
     894           0 :                 skb = skb_peek(&sk->sk_receive_queue);
     895           0 :                 if (skb)
     896           0 :                         amount = skb->len;
     897           0 :                 spin_unlock_bh(&sk->sk_receive_queue.lock);
     898           0 :                 return put_user(amount, (int __user *)arg);
     899             :         }
     900             : 
     901             :         default:
     902             : #ifdef CONFIG_IP_MROUTE
     903             :                 return ipmr_ioctl(sk, cmd, (void __user *)arg);
     904             : #else
     905             :                 return -ENOIOCTLCMD;
     906             : #endif
     907             :         }
     908             : }
     909             : 
     910             : #ifdef CONFIG_COMPAT
     911           0 : static int compat_raw_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
     912             : {
     913           0 :         switch (cmd) {
     914             :         case SIOCOUTQ:
     915             :         case SIOCINQ:
     916             :                 return -ENOIOCTLCMD;
     917             :         default:
     918             : #ifdef CONFIG_IP_MROUTE
     919             :                 return ipmr_compat_ioctl(sk, cmd, compat_ptr(arg));
     920             : #else
     921             :                 return -ENOIOCTLCMD;
     922             : #endif
     923             :         }
     924             : }
     925             : #endif
     926             : 
     927           0 : int raw_abort(struct sock *sk, int err)
     928             : {
     929           0 :         lock_sock(sk);
     930             : 
     931           0 :         sk->sk_err = err;
     932           0 :         sk->sk_error_report(sk);
     933           0 :         __udp_disconnect(sk, 0);
     934             : 
     935           0 :         release_sock(sk);
     936             : 
     937           0 :         return 0;
     938             : }
     939             : EXPORT_SYMBOL_GPL(raw_abort);
     940             : 
     941             : struct proto raw_prot = {
     942             :         .name              = "RAW",
     943             :         .owner             = THIS_MODULE,
     944             :         .close             = raw_close,
     945             :         .destroy           = raw_destroy,
     946             :         .connect           = ip4_datagram_connect,
     947             :         .disconnect        = __udp_disconnect,
     948             :         .ioctl             = raw_ioctl,
     949             :         .init              = raw_sk_init,
     950             :         .setsockopt        = raw_setsockopt,
     951             :         .getsockopt        = raw_getsockopt,
     952             :         .sendmsg           = raw_sendmsg,
     953             :         .recvmsg           = raw_recvmsg,
     954             :         .bind              = raw_bind,
     955             :         .backlog_rcv       = raw_rcv_skb,
     956             :         .release_cb        = ip4_datagram_release_cb,
     957             :         .hash              = raw_hash_sk,
     958             :         .unhash            = raw_unhash_sk,
     959             :         .obj_size          = sizeof(struct raw_sock),
     960             :         .useroffset        = offsetof(struct raw_sock, filter),
     961             :         .usersize          = sizeof_field(struct raw_sock, filter),
     962             :         .h.raw_hash        = &raw_v4_hashinfo,
     963             : #ifdef CONFIG_COMPAT
     964             :         .compat_ioctl      = compat_raw_ioctl,
     965             : #endif
     966             :         .diag_destroy      = raw_abort,
     967             : };
     968             : 
     969             : #ifdef CONFIG_PROC_FS
     970           0 : static struct sock *raw_get_first(struct seq_file *seq)
     971             : {
     972           0 :         struct sock *sk;
     973           0 :         struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
     974           0 :         struct raw_iter_state *state = raw_seq_private(seq);
     975             : 
     976           0 :         for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
     977           0 :                         ++state->bucket) {
     978           0 :                 sk_for_each(sk, &h->ht[state->bucket])
     979           0 :                         if (sock_net(sk) == seq_file_net(seq))
     980           0 :                                 goto found;
     981             :         }
     982             :         sk = NULL;
     983           0 : found:
     984           0 :         return sk;
     985             : }
     986             : 
     987           0 : static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
     988             : {
     989           0 :         struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
     990           0 :         struct raw_iter_state *state = raw_seq_private(seq);
     991             : 
     992           0 :         do {
     993           0 :                 sk = sk_next(sk);
     994           0 : try_again:
     995           0 :                 ;
     996           0 :         } while (sk && sock_net(sk) != seq_file_net(seq));
     997             : 
     998           0 :         if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
     999           0 :                 sk = sk_head(&h->ht[state->bucket]);
    1000           0 :                 goto try_again;
    1001             :         }
    1002           0 :         return sk;
    1003             : }
    1004             : 
    1005           0 : static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
    1006             : {
    1007           0 :         struct sock *sk = raw_get_first(seq);
    1008             : 
    1009           0 :         if (sk)
    1010           0 :                 while (pos && (sk = raw_get_next(seq, sk)) != NULL)
    1011           0 :                         --pos;
    1012           0 :         return pos ? NULL : sk;
    1013             : }
    1014             : 
    1015           0 : void *raw_seq_start(struct seq_file *seq, loff_t *pos)
    1016             :         __acquires(&h->lock)
    1017             : {
    1018           0 :         struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
    1019             : 
    1020           0 :         read_lock(&h->lock);
    1021           0 :         return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
    1022             : }
    1023             : EXPORT_SYMBOL_GPL(raw_seq_start);
    1024             : 
    1025           0 : void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
    1026             : {
    1027           0 :         struct sock *sk;
    1028             : 
    1029           0 :         if (v == SEQ_START_TOKEN)
    1030           0 :                 sk = raw_get_first(seq);
    1031             :         else
    1032           0 :                 sk = raw_get_next(seq, v);
    1033           0 :         ++*pos;
    1034           0 :         return sk;
    1035             : }
    1036             : EXPORT_SYMBOL_GPL(raw_seq_next);
    1037             : 
    1038           0 : void raw_seq_stop(struct seq_file *seq, void *v)
    1039             :         __releases(&h->lock)
    1040             : {
    1041           0 :         struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
    1042             : 
    1043           0 :         read_unlock(&h->lock);
    1044           0 : }
    1045             : EXPORT_SYMBOL_GPL(raw_seq_stop);
    1046             : 
    1047           0 : static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
    1048             : {
    1049           0 :         struct inet_sock *inet = inet_sk(sp);
    1050           0 :         __be32 dest = inet->inet_daddr,
    1051           0 :                src = inet->inet_rcv_saddr;
    1052           0 :         __u16 destp = 0,
    1053           0 :               srcp  = inet->inet_num;
    1054             : 
    1055           0 :         seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
    1056             :                 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u\n",
    1057           0 :                 i, src, srcp, dest, destp, sp->sk_state,
    1058             :                 sk_wmem_alloc_get(sp),
    1059             :                 sk_rmem_alloc_get(sp),
    1060             :                 0, 0L, 0,
    1061             :                 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
    1062             :                 0, sock_i_ino(sp),
    1063           0 :                 refcount_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
    1064           0 : }
    1065             : 
    1066           0 : static int raw_seq_show(struct seq_file *seq, void *v)
    1067             : {
    1068           0 :         if (v == SEQ_START_TOKEN)
    1069           0 :                 seq_printf(seq, "  sl  local_address rem_address   st tx_queue "
    1070             :                                 "rx_queue tr tm->when retrnsmt   uid  timeout "
    1071             :                                 "inode ref pointer drops\n");
    1072             :         else
    1073           0 :                 raw_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
    1074           0 :         return 0;
    1075             : }
    1076             : 
    1077             : static const struct seq_operations raw_seq_ops = {
    1078             :         .start = raw_seq_start,
    1079             :         .next  = raw_seq_next,
    1080             :         .stop  = raw_seq_stop,
    1081             :         .show  = raw_seq_show,
    1082             : };
    1083             : 
    1084           1 : static __net_init int raw_init_net(struct net *net)
    1085             : {
    1086           1 :         if (!proc_create_net_data("raw", 0444, net->proc_net, &raw_seq_ops,
    1087             :                         sizeof(struct raw_iter_state), &raw_v4_hashinfo))
    1088           0 :                 return -ENOMEM;
    1089             : 
    1090             :         return 0;
    1091             : }
    1092             : 
    1093           0 : static __net_exit void raw_exit_net(struct net *net)
    1094             : {
    1095           0 :         remove_proc_entry("raw", net->proc_net);
    1096           0 : }
    1097             : 
    1098             : static __net_initdata struct pernet_operations raw_net_ops = {
    1099             :         .init = raw_init_net,
    1100             :         .exit = raw_exit_net,
    1101             : };
    1102             : 
    1103           1 : int __init raw_proc_init(void)
    1104             : {
    1105           1 :         return register_pernet_subsys(&raw_net_ops);
    1106             : }
    1107             : 
    1108           0 : void __init raw_proc_exit(void)
    1109             : {
    1110           0 :         unregister_pernet_subsys(&raw_net_ops);
    1111           0 : }
    1112             : #endif /* CONFIG_PROC_FS */
    1113             : 
    1114           2 : static void raw_sysctl_init_net(struct net *net)
    1115             : {
    1116             : #ifdef CONFIG_NET_L3_MASTER_DEV
    1117             :         net->ipv4.sysctl_raw_l3mdev_accept = 1;
    1118             : #endif
    1119           2 : }
    1120             : 
    1121           1 : static int __net_init raw_sysctl_init(struct net *net)
    1122             : {
    1123           1 :         raw_sysctl_init_net(net);
    1124           1 :         return 0;
    1125             : }
    1126             : 
    1127             : static struct pernet_operations __net_initdata raw_sysctl_ops = {
    1128             :         .init   = raw_sysctl_init,
    1129             : };
    1130             : 
    1131           1 : void __init raw_init(void)
    1132             : {
    1133           1 :         raw_sysctl_init_net(&init_net);
    1134           1 :         if (register_pernet_subsys(&raw_sysctl_ops))
    1135           0 :                 panic("RAW: failed to init sysctl parameters.\n");
    1136           1 : }

Generated by: LCOV version 1.14