packets: Add in6_is_lla() function.
[cascardo/ovs.git] / lib / packets.h
index 2896b78..8f11e2c 100644 (file)
@@ -109,6 +109,15 @@ struct pkt_metadata {
                                  * 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)
 {
@@ -575,6 +584,12 @@ char *ip_parse_cidr_len(const char *s, int *n, ovs_be32 *ip,
 #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. */
@@ -819,12 +834,16 @@ BUILD_ASSERT_DECL(ND_OPT_LEN == sizeof(struct ovs_nd_opt));
 #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
@@ -961,6 +980,18 @@ in6_generate_lla(struct eth_addr ea, struct in6_addr *lla)
     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)
 {
@@ -1012,6 +1043,9 @@ void ipv6_format_masked(const struct in6_addr *addr,
 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);
@@ -1054,6 +1088,11 @@ void compose_arp(struct dp_packet *, uint16_t arp_op,
                  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 */