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

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

Version: ~ [ linux-5.5-rc6 ] ~ [ linux-5.4.11 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.95 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.164 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.209 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.209 ] ~ [ 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 #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 __wsum get_csum_diff(struct ipv6hdr *ip6h, struct ila_params *p)
 17 {
 18         if (*(__be64 *)&ip6h->daddr == p->locator_match)
 19                 return p->csum_diff;
 20         else
 21                 return compute_csum_diff8((__be32 *)&ip6h->daddr,
 22                                           (__be32 *)&p->locator);
 23 }
 24 
 25 void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p)
 26 {
 27         __wsum diff;
 28         struct ipv6hdr *ip6h = ipv6_hdr(skb);
 29         size_t nhoff = sizeof(struct ipv6hdr);
 30 
 31         /* First update checksum */
 32         switch (ip6h->nexthdr) {
 33         case NEXTHDR_TCP:
 34                 if (likely(pskb_may_pull(skb, nhoff + sizeof(struct tcphdr)))) {
 35                         struct tcphdr *th = (struct tcphdr *)
 36                                         (skb_network_header(skb) + nhoff);
 37 
 38                         diff = get_csum_diff(ip6h, p);
 39                         inet_proto_csum_replace_by_diff(&th->check, skb,
 40                                                         diff, true);
 41                 }
 42                 break;
 43         case NEXTHDR_UDP:
 44                 if (likely(pskb_may_pull(skb, nhoff + sizeof(struct udphdr)))) {
 45                         struct udphdr *uh = (struct udphdr *)
 46                                         (skb_network_header(skb) + nhoff);
 47 
 48                         if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {
 49                                 diff = get_csum_diff(ip6h, p);
 50                                 inet_proto_csum_replace_by_diff(&uh->check, skb,
 51                                                                 diff, true);
 52                                 if (!uh->check)
 53                                         uh->check = CSUM_MANGLED_0;
 54                         }
 55                 }
 56                 break;
 57         case NEXTHDR_ICMP:
 58                 if (likely(pskb_may_pull(skb,
 59                                          nhoff + sizeof(struct icmp6hdr)))) {
 60                         struct icmp6hdr *ih = (struct icmp6hdr *)
 61                                         (skb_network_header(skb) + nhoff);
 62 
 63                         diff = get_csum_diff(ip6h, p);
 64                         inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb,
 65                                                         diff, true);
 66                 }
 67                 break;
 68         }
 69 
 70         /* Now change destination address */
 71         *(__be64 *)&ip6h->daddr = p->locator;
 72 }
 73 
 74 static int __init ila_init(void)
 75 {
 76         int ret;
 77 
 78         ret = ila_lwt_init();
 79 
 80         if (ret)
 81                 goto fail_lwt;
 82 
 83         ret = ila_xlat_init();
 84         if (ret)
 85                 goto fail_xlat;
 86 
 87         return 0;
 88 fail_xlat:
 89         ila_lwt_fini();
 90 fail_lwt:
 91         return ret;
 92 }
 93 
 94 static void __exit ila_fini(void)
 95 {
 96         ila_xlat_fini();
 97         ila_lwt_fini();
 98 }
 99 
100 module_init(ila_init);
101 module_exit(ila_fini);
102 MODULE_ALIAS_RTNL_LWT(ILA);
103 MODULE_AUTHOR("Tom Herbert <tom@herbertland.com>");
104 MODULE_LICENSE("GPL");
105 

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