summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2014-10-20 16:13:04 -0700
committerPravin B Shelar <pshelar@nicira.com>2014-10-23 19:09:23 -0700
commit8abaa53cac82dad5e7f8dba9ef30d785b0a46140 (patch)
tree87a5f91e182cf71563e7421325e3611a19b9adf8
parentaf465b67a9b93f7db935924f1b51a90dea81fe12 (diff)
downloadopenvswitch-8abaa53cac82dad5e7f8dba9ef30d785b0a46140.tar.gz
datapath: Use upstream ipv6_find_hdr().
ipv6_find_hdr() already fixed in newer upstram kernel by Ansis, we can start using this API safely. This patch also backports fix (ipv6: ipv6_find_hdr restore prev functionality) to compat ipv6_find_hdr(). CC: Ansis Atteka <aatteka@nicira.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Acked-by: Andy Zhou <azhou@nicira.com>
-rw-r--r--acinclude.m41
-rw-r--r--datapath/actions.c2
-rw-r--r--datapath/linux/compat/exthdrs_core.c18
-rw-r--r--datapath/linux/compat/include/net/ipv6.h19
4 files changed, 24 insertions, 16 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index f0617df1d..3d0eef118 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -364,6 +364,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_GREP_IFELSE([$KSRC/include/net/gre.h], [gre_handle_offloads])
OVS_GREP_IFELSE([$KSRC/include/net/ip_tunnels.h], [iptunnel_xmit.*net],
[OVS_DEFINE([HAVE_IPTUNNEL_XMIT_NET])])
+ OVS_GREP_IFELSE([$KSRC/include/net/ipv6.h], [IP6_FH_F_SKIP_RH])
OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_get_be16])
OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_put_be16])
OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_put_be32])
diff --git a/datapath/actions.c b/datapath/actions.c
index 00c1fd4b7..a42ad1e10 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -482,7 +482,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *key,
if (memcmp(ipv6_key->ipv6_dst, daddr, sizeof(ipv6_key->ipv6_dst))) {
unsigned int offset = 0;
- int flags = OVS_IP6T_FH_F_SKIP_RH;
+ int flags = IP6_FH_F_SKIP_RH;
bool recalc_csum = true;
if (ipv6_ext_hdr(nh->nexthdr))
diff --git a/datapath/linux/compat/exthdrs_core.c b/datapath/linux/compat/exthdrs_core.c
index e2b4a03cb..29e4e056d 100644
--- a/datapath/linux/compat/exthdrs_core.c
+++ b/datapath/linux/compat/exthdrs_core.c
@@ -2,6 +2,7 @@
#include <linux/version.h>
#include <net/ipv6.h>
+#ifndef HAVE_IP6_FH_F_SKIP_RH
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
int rpl_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
u8 *nexthdrp, __be16 *frag_offp)
@@ -68,9 +69,9 @@ int rpl_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
* isn't NULL.
*
* if flags is not NULL and it's a fragment, then the frag flag
- * OVS_IP6T_FH_F_FRAG will be set. If it's an AH header, the
- * OVS_IP6T_FH_F_AUTH flag is set and target < 0, then this function will
- * stop at the AH header. If OVS_IP6T_FH_F_SKIP_RH flag was passed, then this
+ * IP6_FH_F_FRAG will be set. If it's an AH header, the
+ * IP6_FH_F_AUTH flag is set and target < 0, then this function will
+ * stop at the AH header. If IP6_FH_F_SKIP_RH flag was passed, then this
* function will skip all those routing headers, where segements_left was 0.
*/
int rpl_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
@@ -103,7 +104,7 @@ int rpl_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
found = (nexthdr == target);
if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
- if (target < 0)
+ if (target < 0 || found)
break;
return -ENOENT;
}
@@ -120,7 +121,7 @@ int rpl_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
if (rh == NULL)
return -EBADMSG;
- if (flags && (*flags & OVS_IP6T_FH_F_SKIP_RH) &&
+ if (flags && (*flags & IP6_FH_F_SKIP_RH) &&
rh->segments_left == 0)
found = false;
}
@@ -130,7 +131,7 @@ int rpl_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
__be16 *fp;
if (flags) /* Indicate that this is a fragment */
- *flags |= OVS_IP6T_FH_F_FRAG;
+ *flags |= IP6_FH_F_FRAG;
fp = skb_header_pointer(skb,
start+offsetof(struct frag_hdr,
frag_off),
@@ -152,8 +153,7 @@ int rpl_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
}
hdrlen = 8;
} else if (nexthdr == NEXTHDR_AUTH) {
- if (flags && (*flags & OVS_IP6T_FH_F_AUTH) &&
- (target < 0))
+ if (flags && (*flags & IP6_FH_F_AUTH) && (target < 0))
break;
hdrlen = (hp->hdrlen + 2) << 2;
} else
@@ -169,3 +169,5 @@ int rpl_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
*offset = start;
return nexthdr;
}
+
+#endif
diff --git a/datapath/linux/compat/include/net/ipv6.h b/datapath/linux/compat/include/net/ipv6.h
index eebb1fe46..1762a4d45 100644
--- a/datapath/linux/compat/include/net/ipv6.h
+++ b/datapath/linux/compat/include/net/ipv6.h
@@ -9,23 +9,28 @@
#define NEXTHDR_SCTP 132 /* Stream Control Transport Protocol */
#endif
+#ifndef HAVE_IP6_FH_F_SKIP_RH
+
+enum {
+ IP6_FH_F_FRAG = (1 << 0),
+ IP6_FH_F_AUTH = (1 << 1),
+ IP6_FH_F_SKIP_RH = (1 << 2),
+};
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
#define ipv6_skip_exthdr rpl_ipv6_skip_exthdr
extern int ipv6_skip_exthdr(const struct sk_buff *skb, int start,
u8 *nexthdrp, __be16 *frag_offp);
#endif
-enum {
- OVS_IP6T_FH_F_FRAG = (1 << 0),
- OVS_IP6T_FH_F_AUTH = (1 << 1),
- OVS_IP6T_FH_F_SKIP_RH = (1 << 2),
-};
-
/* This function is upstream, but not the version which skips routing
- * headers with 0 segments_left. We plan to propose the extended version. */
+ * headers with 0 segments_left. We fixed it when we introduced
+ * IP6_FH_F_SKIP_RH.
+ */
#define ipv6_find_hdr rpl_ipv6_find_hdr
extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
int target, unsigned short *fragoff, int *fragflg);
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
static inline u32 ipv6_addr_hash(const struct in6_addr *a)