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

TOMOYO Linux Cross Reference
Linux/net/ipv6/ila/ila_lwt.c

Version: ~ [ linux-5.14-rc1 ] ~ [ linux-5.13.1 ] ~ [ linux-5.12.16 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.49 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.131 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.197 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.239 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.275 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.275 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <linux/errno.h>
  2 #include <linux/ip.h>
  3 #include <linux/kernel.h>
  4 #include <linux/module.h>
  5 #include <linux/skbuff.h>
  6 #include <linux/socket.h>
  7 #include <linux/types.h>
  8 #include <net/checksum.h>
  9 #include <net/ip.h>
 10 #include <net/ip6_fib.h>
 11 #include <net/lwtunnel.h>
 12 #include <net/protocol.h>
 13 #include <uapi/linux/ila.h>
 14 #include "ila.h"
 15 
 16 static inline struct ila_params *ila_params_lwtunnel(
 17         struct lwtunnel_state *lwstate)
 18 {
 19         return (struct ila_params *)lwstate->data;
 20 }
 21 
 22 static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 23 {
 24         struct dst_entry *dst = skb_dst(skb);
 25 
 26         if (skb->protocol != htons(ETH_P_IPV6))
 27                 goto drop;
 28 
 29         update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate));
 30 
 31         return dst->lwtstate->orig_output(net, sk, skb);
 32 
 33 drop:
 34         kfree_skb(skb);
 35         return -EINVAL;
 36 }
 37 
 38 static int ila_input(struct sk_buff *skb)
 39 {
 40         struct dst_entry *dst = skb_dst(skb);
 41 
 42         if (skb->protocol != htons(ETH_P_IPV6))
 43                 goto drop;
 44 
 45         update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate));
 46 
 47         return dst->lwtstate->orig_input(skb);
 48 
 49 drop:
 50         kfree_skb(skb);
 51         return -EINVAL;
 52 }
 53 
 54 static struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
 55         [ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
 56 };
 57 
 58 static int ila_build_state(struct net_device *dev, struct nlattr *nla,
 59                            unsigned int family, const void *cfg,
 60                            struct lwtunnel_state **ts)
 61 {
 62         struct ila_params *p;
 63         struct nlattr *tb[ILA_ATTR_MAX + 1];
 64         size_t encap_len = sizeof(*p);
 65         struct lwtunnel_state *newts;
 66         const struct fib6_config *cfg6 = cfg;
 67         int ret;
 68 
 69         if (family != AF_INET6)
 70                 return -EINVAL;
 71 
 72         ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla,
 73                                ila_nl_policy);
 74         if (ret < 0)
 75                 return ret;
 76 
 77         if (!tb[ILA_ATTR_LOCATOR])
 78                 return -EINVAL;
 79 
 80         newts = lwtunnel_state_alloc(encap_len);
 81         if (!newts)
 82                 return -ENOMEM;
 83 
 84         newts->len = encap_len;
 85         p = ila_params_lwtunnel(newts);
 86 
 87         p->locator = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]);
 88 
 89         if (cfg6->fc_dst_len > sizeof(__be64)) {
 90                 /* Precompute checksum difference for translation since we
 91                  * know both the old locator and the new one.
 92                  */
 93                 p->locator_match = *(__be64 *)&cfg6->fc_dst;
 94                 p->csum_diff = compute_csum_diff8(
 95                         (__be32 *)&p->locator_match, (__be32 *)&p->locator);
 96         }
 97 
 98         newts->type = LWTUNNEL_ENCAP_ILA;
 99         newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT |
100                         LWTUNNEL_STATE_INPUT_REDIRECT;
101 
102         *ts = newts;
103 
104         return 0;
105 }
106 
107 static int ila_fill_encap_info(struct sk_buff *skb,
108                                struct lwtunnel_state *lwtstate)
109 {
110         struct ila_params *p = ila_params_lwtunnel(lwtstate);
111 
112         if (nla_put_u64(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator))
113                 goto nla_put_failure;
114 
115         return 0;
116 
117 nla_put_failure:
118         return -EMSGSIZE;
119 }
120 
121 static int ila_encap_nlsize(struct lwtunnel_state *lwtstate)
122 {
123         return nla_total_size(sizeof(u64)); /* ILA_ATTR_LOCATOR */
124 }
125 
126 static int ila_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
127 {
128         struct ila_params *a_p = ila_params_lwtunnel(a);
129         struct ila_params *b_p = ila_params_lwtunnel(b);
130 
131         return (a_p->locator != b_p->locator);
132 }
133 
134 static const struct lwtunnel_encap_ops ila_encap_ops = {
135         .build_state = ila_build_state,
136         .output = ila_output,
137         .input = ila_input,
138         .fill_encap = ila_fill_encap_info,
139         .get_encap_size = ila_encap_nlsize,
140         .cmp_encap = ila_encap_cmp,
141 };
142 
143 int ila_lwt_init(void)
144 {
145         return lwtunnel_encap_add_ops(&ila_encap_ops, LWTUNNEL_ENCAP_ILA);
146 }
147 
148 void ila_lwt_fini(void)
149 {
150         lwtunnel_encap_del_ops(&ila_encap_ops, LWTUNNEL_ENCAP_ILA);
151 }
152 

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