* be uninitialized. */
};
+static inline void
+pkt_metadata_init_tnl(struct pkt_metadata *md)
+{
+ /* Zero up through the tunnel metadata options. The length and table
+ * are before this and as long as they are empty, the options won't
+ * be looked at. */
+ memset(md, 0, offsetof(struct pkt_metadata, tunnel.metadata.opts));
+}
+
static inline void
pkt_metadata_init(struct pkt_metadata *md, odp_port_t port)
{
#define IP_ECN_MASK 0x03
#define IP_DSCP_MASK 0xfc
+static inline int
+IP_ECN_is_ce(uint8_t dsfield)
+{
+ return (dsfield & IP_ECN_MASK) == IP_ECN_CE;
+}
+
#define IP_VERSION 4
#define IP_DONT_FRAGMENT 0x4000 /* Don't fragment. */
#define ND_MSG_LEN 24
struct ovs_nd_msg {
struct icmp6_header icmph;
- ovs_16aligned_be32 rco_flags;
+ ovs_16aligned_be32 rso_flags;
union ovs_16aligned_in6_addr target;
struct ovs_nd_opt options[0];
};
BUILD_ASSERT_DECL(ND_MSG_LEN == sizeof(struct ovs_nd_msg));
+#define ND_RSO_ROUTER 0x80000000
+#define ND_RSO_SOLICITED 0x40000000
+#define ND_RSO_OVERRIDE 0x20000000
+
/*
* Use the same struct for MLD and MLD2, naming members as the defined fields in
* in the corresponding version of the protocol, though they are reserved in the
taddr->be16[7] = ea.be16[2];
}
+/* Returns true if 'addr' is a link local address. Otherwise, false. */
+static inline bool
+in6_is_lla(struct in6_addr *addr)
+{
+#ifdef s6_addr32
+ return addr->s6_addr32[0] == htonl(0xfe800000) && !(addr->s6_addr32[1]);
+#else
+ return addr->s6_addr[0] == htons(0xfe80) &&
+ !(addr->s6_addr[1] | addr->s6_addr[2] | addr->s6_addr[3]);
+#endif
+}
+
static inline void
ipv6_multicast_to_ethernet(struct eth_addr *eth, const struct in6_addr *ip6)
{
const char * ipv6_string_mapped(char *addr_str, const struct in6_addr *addr);
struct in6_addr ipv6_addr_bitand(const struct in6_addr *src,
const struct in6_addr *mask);
+struct in6_addr ipv6_addr_bitxor(const struct in6_addr *a,
+ const struct in6_addr *b);
+bool ipv6_is_zero(const struct in6_addr *a);
struct in6_addr ipv6_create_mask(int mask);
int ipv6_count_cidr_bits(const struct in6_addr *netmask);
bool ipv6_is_cidr(const struct in6_addr *netmask);
ovs_be32 arp_spa, ovs_be32 arp_tpa);
void compose_nd(struct dp_packet *, const struct eth_addr eth_src,
struct in6_addr *, struct in6_addr *);
+void compose_na(struct dp_packet *,
+ const struct eth_addr eth_src, const struct eth_addr eth_dst,
+ const ovs_be32 ipv6_src[4], const ovs_be32 ipv6_dst[4],
+ ovs_be32 rso_flags);
uint32_t packet_csum_pseudoheader(const struct ip_header *);
+void IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6);
#endif /* packets.h */