]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ipv6: Store Router Alert option in IP6CB directly.
authorYOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
Sun, 13 Jan 2013 05:02:45 +0000 (05:02 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 Jan 2013 01:17:14 +0000 (20:17 -0500)
Router Alert option is very small and we can store the value
itself in the skb.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/ipv6.h
include/uapi/linux/ipv6.h
net/ipv6/exthdrs.c
net/ipv6/ip6_input.c

index 304a9f46b57838bd9d079a9cc7696a6f76b404b1..e971e3742172c0c7817d1933fffa8bcf67f13492 100644 (file)
@@ -84,7 +84,7 @@ static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb)
 
 struct inet6_skb_parm {
        int                     iif;
-       __u16                   ra;
+       __be16                  ra;
        __u16                   hop;
        __u16                   dst0;
        __u16                   srcrt;
@@ -100,6 +100,7 @@ struct inet6_skb_parm {
 #define IP6SKB_XFRM_TRANSFORMED        1
 #define IP6SKB_FORWARDED       2
 #define IP6SKB_REROUTED                4
+#define IP6SKB_ROUTERALERT     8
 };
 
 #define IP6CB(skb)     ((struct inet6_skb_parm*)((skb)->cb))
index 5a2991cf0251d558c15d108d9ea88155240425e7..4bda4cf5b0f56d84651497df86bd9fa09909fa85 100644 (file)
@@ -63,6 +63,8 @@ struct ipv6_opt_hdr {
 #define ipv6_destopt_hdr ipv6_opt_hdr
 #define ipv6_hopopt_hdr  ipv6_opt_hdr
 
+/* Router Alert option values (RFC2711) */
+#define IPV6_OPT_ROUTERALERT_MLD       0x0000  /* MLD(RFC2710) */
 
 /*
  *     routing header type 0 (used in cmsghdr struct)
index 473f628f9f203d2e0c58466f32603ce50a330402..07a7d65a7cb6757bdac702b01e8284ad2402bf46 100644 (file)
@@ -553,7 +553,8 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
        const unsigned char *nh = skb_network_header(skb);
 
        if (nh[optoff + 1] == 2) {
-               IP6CB(skb)->ra = optoff;
+               IP6CB(skb)->flags |= IP6SKB_ROUTERALERT;
+               memcpy(&IP6CB(skb)->ra, nh + optoff + 2, sizeof(IP6CB(skb)->ra));
                return true;
        }
        LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
index 2ccd35ec3628138139fb5b6f8f620efe7bed1194..4ac5bf30e16adae9a2fe1e271f6e3a39adf2cbb2 100644 (file)
@@ -280,9 +280,8 @@ int ip6_mc_input(struct sk_buff *skb)
                struct inet6_skb_parm *opt = IP6CB(skb);
 
                /* Check for MLD */
-               if (unlikely(opt->ra)) {
+               if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
                        /* Check if this is a mld message */
-                       u8 *ptr = skb_network_header(skb) + opt->ra;
                        u8 nexthdr = hdr->nexthdr;
                        __be16 frag_off;
                        int offset;
@@ -290,7 +289,7 @@ int ip6_mc_input(struct sk_buff *skb)
                        /* Check if the value of Router Alert
                         * is for MLD (0x0000).
                         */
-                       if ((ptr[2] | ptr[3]) == 0) {
+                       if (opt->ra == htons(IPV6_OPT_ROUTERALERT_MLD)) {
                                deliver = false;
 
                                if (!ipv6_ext_hdr(nexthdr)) {