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])
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))
#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)
* 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,
found = (nexthdr == target);
if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
- if (target < 0)
+ if (target < 0 || found)
break;
return -ENOENT;
}
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;
}
__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),
}
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
*offset = start;
return nexthdr;
}
+
+#endif
#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)