aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>2013-01-13 00:02:45 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-13 20:17:14 -0500
commitdd3332bfcb2223458f553f341d3388cb84040e6a (patch)
treed48ba8b295ee3d08c4b4b4f8d924038ccec2c5eb
parent2b464f61f036f7fb9cbc34710c9b2390499e87d0 (diff)
ipv6: Store Router Alert option in IP6CB directly.
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>
-rw-r--r--include/linux/ipv6.h3
-rw-r--r--include/uapi/linux/ipv6.h2
-rw-r--r--net/ipv6/exthdrs.c3
-rw-r--r--net/ipv6/ip6_input.c5
4 files changed, 8 insertions, 5 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 304a9f46b578..e971e3742172 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -84,7 +84,7 @@ static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb)
84 84
85struct inet6_skb_parm { 85struct inet6_skb_parm {
86 int iif; 86 int iif;
87 __u16 ra; 87 __be16 ra;
88 __u16 hop; 88 __u16 hop;
89 __u16 dst0; 89 __u16 dst0;
90 __u16 srcrt; 90 __u16 srcrt;
@@ -100,6 +100,7 @@ struct inet6_skb_parm {
100#define IP6SKB_XFRM_TRANSFORMED 1 100#define IP6SKB_XFRM_TRANSFORMED 1
101#define IP6SKB_FORWARDED 2 101#define IP6SKB_FORWARDED 2
102#define IP6SKB_REROUTED 4 102#define IP6SKB_REROUTED 4
103#define IP6SKB_ROUTERALERT 8
103}; 104};
104 105
105#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) 106#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 5a2991cf0251..4bda4cf5b0f5 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -63,6 +63,8 @@ struct ipv6_opt_hdr {
63#define ipv6_destopt_hdr ipv6_opt_hdr 63#define ipv6_destopt_hdr ipv6_opt_hdr
64#define ipv6_hopopt_hdr ipv6_opt_hdr 64#define ipv6_hopopt_hdr ipv6_opt_hdr
65 65
66/* Router Alert option values (RFC2711) */
67#define IPV6_OPT_ROUTERALERT_MLD 0x0000 /* MLD(RFC2710) */
66 68
67/* 69/*
68 * routing header type 0 (used in cmsghdr struct) 70 * routing header type 0 (used in cmsghdr struct)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 473f628f9f20..07a7d65a7cb6 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -553,7 +553,8 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
553 const unsigned char *nh = skb_network_header(skb); 553 const unsigned char *nh = skb_network_header(skb);
554 554
555 if (nh[optoff + 1] == 2) { 555 if (nh[optoff + 1] == 2) {
556 IP6CB(skb)->ra = optoff; 556 IP6CB(skb)->flags |= IP6SKB_ROUTERALERT;
557 memcpy(&IP6CB(skb)->ra, nh + optoff + 2, sizeof(IP6CB(skb)->ra));
557 return true; 558 return true;
558 } 559 }
559 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", 560 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 2ccd35ec3628..4ac5bf30e16a 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -280,9 +280,8 @@ int ip6_mc_input(struct sk_buff *skb)
280 struct inet6_skb_parm *opt = IP6CB(skb); 280 struct inet6_skb_parm *opt = IP6CB(skb);
281 281
282 /* Check for MLD */ 282 /* Check for MLD */
283 if (unlikely(opt->ra)) { 283 if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
284 /* Check if this is a mld message */ 284 /* Check if this is a mld message */
285 u8 *ptr = skb_network_header(skb) + opt->ra;
286 u8 nexthdr = hdr->nexthdr; 285 u8 nexthdr = hdr->nexthdr;
287 __be16 frag_off; 286 __be16 frag_off;
288 int offset; 287 int offset;
@@ -290,7 +289,7 @@ int ip6_mc_input(struct sk_buff *skb)
290 /* Check if the value of Router Alert 289 /* Check if the value of Router Alert
291 * is for MLD (0x0000). 290 * is for MLD (0x0000).
292 */ 291 */
293 if ((ptr[2] | ptr[3]) == 0) { 292 if (opt->ra == htons(IPV6_OPT_ROUTERALERT_MLD)) {
294 deliver = false; 293 deliver = false;
295 294
296 if (!ipv6_ext_hdr(nexthdr)) { 295 if (!ipv6_ext_hdr(nexthdr)) {