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

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

Version: ~ [ linux-5.5 ] ~ [ linux-5.4.15 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.98 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.167 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.211 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.211 ] ~ [ 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.81 ] ~ [ 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  * 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 {
 26         XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
 27         XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
 28         return xfrm_input(skb, nexthdr, spi, 0);
 29 }
 30 EXPORT_SYMBOL(xfrm6_rcv_spi);
 31 
 32 int xfrm6_transport_finish(struct sk_buff *skb, int async)
 33 {
 34         skb_network_header(skb)[IP6CB(skb)->nhoff] =
 35                 XFRM_MODE_SKB_CB(skb)->protocol;
 36 
 37 #ifndef CONFIG_NETFILTER
 38         if (!async)
 39                 return 1;
 40 #endif
 41 
 42         ipv6_hdr(skb)->payload_len = htons(skb->len);
 43         __skb_push(skb, skb->data - skb_network_header(skb));
 44 
 45         NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
 46                 dev_net(skb->dev), NULL, skb, skb->dev, NULL,
 47                 ip6_rcv_finish);
 48         return -1;
 49 }
 50 
 51 int xfrm6_rcv(struct sk_buff *skb)
 52 {
 53         return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
 54                              0);
 55 }
 56 EXPORT_SYMBOL(xfrm6_rcv);
 57 
 58 int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 59                      xfrm_address_t *saddr, u8 proto)
 60 {
 61         struct net *net = dev_net(skb->dev);
 62         struct xfrm_state *x = NULL;
 63         int i = 0;
 64 
 65         /* Allocate new secpath or COW existing one. */
 66         if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
 67                 struct sec_path *sp;
 68 
 69                 sp = secpath_dup(skb->sp);
 70                 if (!sp) {
 71                         XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
 72                         goto drop;
 73                 }
 74                 if (skb->sp)
 75                         secpath_put(skb->sp);
 76                 skb->sp = sp;
 77         }
 78 
 79         if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
 80                 XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
 81                 goto drop;
 82         }
 83 
 84         for (i = 0; i < 3; i++) {
 85                 xfrm_address_t *dst, *src;
 86 
 87                 switch (i) {
 88                 case 0:
 89                         dst = daddr;
 90                         src = saddr;
 91                         break;
 92                 case 1:
 93                         /* lookup state with wild-card source address */
 94                         dst = daddr;
 95                         src = (xfrm_address_t *)&in6addr_any;
 96                         break;
 97                 default:
 98                         /* lookup state with wild-card addresses */
 99                         dst = (xfrm_address_t *)&in6addr_any;
100                         src = (xfrm_address_t *)&in6addr_any;
101                         break;
102                 }
103 
104                 x = xfrm_state_lookup_byaddr(net, skb->mark, dst, src, proto, AF_INET6);
105                 if (!x)
106                         continue;
107 
108                 spin_lock(&x->lock);
109 
110                 if ((!i || (x->props.flags & XFRM_STATE_WILDRECV)) &&
111                     likely(x->km.state == XFRM_STATE_VALID) &&
112                     !xfrm_state_check_expire(x)) {
113                         spin_unlock(&x->lock);
114                         if (x->type->input(x, skb) > 0) {
115                                 /* found a valid state */
116                                 break;
117                         }
118                 } else
119                         spin_unlock(&x->lock);
120 
121                 xfrm_state_put(x);
122                 x = NULL;
123         }
124 
125         if (!x) {
126                 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
127                 xfrm_audit_state_notfound_simple(skb, AF_INET6);
128                 goto drop;
129         }
130 
131         skb->sp->xvec[skb->sp->len++] = x;
132 
133         spin_lock(&x->lock);
134 
135         x->curlft.bytes += skb->len;
136         x->curlft.packets++;
137 
138         spin_unlock(&x->lock);
139 
140         return 1;
141 
142 drop:
143         return -1;
144 }
145 EXPORT_SYMBOL(xfrm6_input_addr);
146 

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