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

TOMOYO Linux Cross Reference
Linux/net/ipv6/xfrm6_input.c

Version: ~ [ linux-6.2-rc3 ] ~ [ linux-6.1.5 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.87 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.162 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.228 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.269 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.302 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * xfrm6_input.c: based on net/ipv4/xfrm4_input.c
  3  *
  4  * Authors:
  5  *      Mitsuru KANDA @USAGI
  6  *      Kazunori MIYAZAWA @USAGI
  7  *      Kunihiro Ishiguro <kunihiro@ipinfusion.com>
  8  *      YOSHIFUJI Hideaki @USAGI
  9  *              IPv6 support
 10  */
 11 
 12 #include <linux/module.h>
 13 #include <linux/string.h>
 14 #include <linux/netfilter.h>
 15 #include <linux/netfilter_ipv6.h>
 16 #include <net/ipv6.h>
 17 #include <net/xfrm.h>
 18 
 19 int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
 20 {
 21         return xfrm6_extract_header(skb);
 22 }
 23 
 24 int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
 25                   struct ip6_tnl *t)
 26 {
 27         XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
 28         XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
 29         XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
 30         return xfrm_input(skb, nexthdr, spi, 0);
 31 }
 32 EXPORT_SYMBOL(xfrm6_rcv_spi);
 33 
 34 int xfrm6_transport_finish(struct sk_buff *skb, int async)
 35 {
 36         skb_network_header(skb)[IP6CB(skb)->nhoff] =
 37                 XFRM_MODE_SKB_CB(skb)->protocol;
 38 
 39 #ifndef CONFIG_NETFILTER
 40         if (!async)
 41                 return 1;
 42 #endif
 43 
 44         ipv6_hdr(skb)->payload_len = htons(skb->len);
 45         __skb_push(skb, skb->data - skb_network_header(skb));
 46 
 47         NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
 48                 dev_net(skb->dev), NULL, skb, skb->dev, NULL,
 49                 ip6_rcv_finish);
 50         return -1;
 51 }
 52 
 53 int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t)
 54 {
 55         return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
 56                              0, t);
 57 }
 58 EXPORT_SYMBOL(xfrm6_rcv_tnl);
 59 
 60 int xfrm6_rcv(struct sk_buff *skb)
 61 {
 62         return xfrm6_rcv_tnl(skb, NULL);
 63 }
 64 EXPORT_SYMBOL(xfrm6_rcv);
 65 int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 66                      xfrm_address_t *saddr, u8 proto)
 67 {
 68         struct net *net = dev_net(skb->dev);
 69         struct xfrm_state *x = NULL;
 70         int i = 0;
 71 
 72         /* Allocate new secpath or COW existing one. */
 73         if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
 74                 struct sec_path *sp;
 75 
 76                 sp = secpath_dup(skb->sp);
 77                 if (!sp) {
 78                         XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
 79                         goto drop;
 80                 }
 81                 if (skb->sp)
 82                         secpath_put(skb->sp);
 83                 skb->sp = sp;
 84         }
 85 
 86         if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
 87                 XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
 88                 goto drop;
 89         }
 90 
 91         for (i = 0; i < 3; i++) {
 92                 xfrm_address_t *dst, *src;
 93 
 94                 switch (i) {
 95                 case 0:
 96                         dst = daddr;
 97                         src = saddr;
 98                         break;
 99                 case 1:
100                         /* lookup state with wild-card source address */
101                         dst = daddr;
102                         src = (xfrm_address_t *)&in6addr_any;
103                         break;
104                 default:
105                         /* lookup state with wild-card addresses */
106                         dst = (xfrm_address_t *)&in6addr_any;
107                         src = (xfrm_address_t *)&in6addr_any;
108                         break;
109                 }
110 
111                 x = xfrm_state_lookup_byaddr(net, skb->mark, dst, src, proto, AF_INET6);
112                 if (!x)
113                         continue;
114 
115                 spin_lock(&x->lock);
116 
117                 if ((!i || (x->props.flags & XFRM_STATE_WILDRECV)) &&
118                     likely(x->km.state == XFRM_STATE_VALID) &&
119                     !xfrm_state_check_expire(x)) {
120                         spin_unlock(&x->lock);
121                         if (x->type->input(x, skb) > 0) {
122                                 /* found a valid state */
123                                 break;
124                         }
125                 } else
126                         spin_unlock(&x->lock);
127 
128                 xfrm_state_put(x);
129                 x = NULL;
130         }
131 
132         if (!x) {
133                 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
134                 xfrm_audit_state_notfound_simple(skb, AF_INET6);
135                 goto drop;
136         }
137 
138         skb->sp->xvec[skb->sp->len++] = x;
139 
140         spin_lock(&x->lock);
141 
142         x->curlft.bytes += skb->len;
143         x->curlft.packets++;
144 
145         spin_unlock(&x->lock);
146 
147         return 1;
148 
149 drop:
150         return -1;
151 }
152 EXPORT_SYMBOL(xfrm6_input_addr);
153 

~ [ 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