LCOV - code coverage report
Current view: top level - net/ipv4 - netfilter.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 39 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /*
       2             :  * IPv4 specific functions of netfilter core
       3             :  *
       4             :  * Rusty Russell (C) 2000 -- This code is GPL.
       5             :  * Patrick McHardy (C) 2006-2012
       6             :  */
       7             : #include <linux/kernel.h>
       8             : #include <linux/netfilter.h>
       9             : #include <linux/netfilter_ipv4.h>
      10             : #include <linux/ip.h>
      11             : #include <linux/skbuff.h>
      12             : #include <linux/gfp.h>
      13             : #include <linux/export.h>
      14             : #include <net/route.h>
      15             : #include <net/xfrm.h>
      16             : #include <net/ip.h>
      17             : #include <net/netfilter/nf_queue.h>
      18             : 
      19             : /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
      20           0 : int ip_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb, unsigned int addr_type)
      21             : {
      22           0 :         const struct iphdr *iph = ip_hdr(skb);
      23           0 :         struct rtable *rt;
      24           0 :         struct flowi4 fl4 = {};
      25           0 :         __be32 saddr = iph->saddr;
      26           0 :         __u8 flags;
      27           0 :         struct net_device *dev = skb_dst(skb)->dev;
      28           0 :         unsigned int hh_len;
      29             : 
      30           0 :         sk = sk_to_full_sk(sk);
      31           0 :         flags = sk ? inet_sk_flowi_flags(sk) : 0;
      32             : 
      33           0 :         if (addr_type == RTN_UNSPEC)
      34           0 :                 addr_type = inet_addr_type_dev_table(net, dev, saddr);
      35           0 :         if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
      36             :                 flags |= FLOWI_FLAG_ANYSRC;
      37             :         else
      38           0 :                 saddr = 0;
      39             : 
      40             :         /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
      41             :          * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
      42             :          */
      43           0 :         fl4.daddr = iph->daddr;
      44           0 :         fl4.saddr = saddr;
      45           0 :         fl4.flowi4_tos = RT_TOS(iph->tos);
      46           0 :         fl4.flowi4_oif = sk ? sk->sk_bound_dev_if : 0;
      47           0 :         if (!fl4.flowi4_oif)
      48           0 :                 fl4.flowi4_oif = l3mdev_master_ifindex(dev);
      49           0 :         fl4.flowi4_mark = skb->mark;
      50           0 :         fl4.flowi4_flags = flags;
      51           0 :         rt = ip_route_output_key(net, &fl4);
      52           0 :         if (IS_ERR(rt))
      53           0 :                 return PTR_ERR(rt);
      54             : 
      55             :         /* Drop old route. */
      56           0 :         skb_dst_drop(skb);
      57           0 :         skb_dst_set(skb, &rt->dst);
      58             : 
      59           0 :         if (skb_dst(skb)->error)
      60           0 :                 return skb_dst(skb)->error;
      61             : 
      62             : #ifdef CONFIG_XFRM
      63             :         if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
      64             :             xfrm_decode_session(skb, flowi4_to_flowi(&fl4), AF_INET) == 0) {
      65             :                 struct dst_entry *dst = skb_dst(skb);
      66             :                 skb_dst_set(skb, NULL);
      67             :                 dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), sk, 0);
      68             :                 if (IS_ERR(dst))
      69             :                         return PTR_ERR(dst);
      70             :                 skb_dst_set(skb, dst);
      71             :         }
      72             : #endif
      73             : 
      74             :         /* Change in oif may mean change in hh_len. */
      75           0 :         hh_len = skb_dst(skb)->dev->hard_header_len;
      76           0 :         if (skb_headroom(skb) < hh_len &&
      77           0 :             pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)),
      78             :                                 0, GFP_ATOMIC))
      79           0 :                 return -ENOMEM;
      80             : 
      81             :         return 0;
      82             : }
      83             : EXPORT_SYMBOL(ip_route_me_harder);
      84             : 
      85           0 : int nf_ip_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
      86             :                 bool strict __always_unused)
      87             : {
      88           0 :         struct rtable *rt = ip_route_output_key(net, &fl->u.ip4);
      89           0 :         if (IS_ERR(rt))
      90           0 :                 return PTR_ERR(rt);
      91           0 :         *dst = &rt->dst;
      92           0 :         return 0;
      93             : }
      94             : EXPORT_SYMBOL_GPL(nf_ip_route);

Generated by: LCOV version 1.14