ovn-northd: Allow lport 'addresses' to store multiple ips in each set
[cascardo/ovs.git] / lib / packets.h
index 4283f59..bf12937 100644 (file)
@@ -163,6 +163,14 @@ pkt_metadata_init(struct pkt_metadata *md, odp_port_t port)
     md->in_port.odp_port = port;
 }
 
+/* This function prefetches the cachelines touched by pkt_metadata_init()
+ * For performance reasons the two functions should be kept in sync. */
+static inline void
+pkt_metadata_prefetch_init(struct pkt_metadata *md)
+{
+    ovs_prefetch_range(md, offsetof(struct pkt_metadata, tunnel.ip_src));
+}
+
 bool dpid_from_string(const char *s, uint64_t *dpidp);
 
 #define ETH_ADDR_LEN           6
@@ -330,6 +338,7 @@ ovs_be32 set_mpls_lse_values(uint8_t ttl, uint8_t tc, uint8_t bos,
 #define ETH_ADDR_ARGS(EA) ETH_ADDR_BYTES_ARGS((EA).ea)
 #define ETH_ADDR_BYTES_ARGS(EAB) \
          (EAB)[0], (EAB)[1], (EAB)[2], (EAB)[3], (EAB)[4], (EAB)[5]
+#define ETH_ADDR_STRLEN 17
 
 /* Example:
  *
@@ -580,8 +589,16 @@ ip_is_local_multicast(ovs_be32 ip)
 }
 int ip_count_cidr_bits(ovs_be32 netmask);
 void ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *);
+bool ip_parse(const char *s, ovs_be32 *ip);
 char *ip_parse_masked(const char *s, ovs_be32 *ip, ovs_be32 *mask)
     OVS_WARN_UNUSED_RESULT;
+char *ip_parse_cidr(const char *s, ovs_be32 *ip, unsigned int *plen)
+    OVS_WARN_UNUSED_RESULT;
+char *ip_parse_masked_len(const char *s, int *n, ovs_be32 *ip, ovs_be32 *mask)
+    OVS_WARN_UNUSED_RESULT;
+char *ip_parse_cidr_len(const char *s, int *n, ovs_be32 *ip,
+                        unsigned int *plen)
+    OVS_WARN_UNUSED_RESULT;
 
 #define IP_VER(ip_ihl_ver) ((ip_ihl_ver) >> 4)
 #define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15)
@@ -733,14 +750,27 @@ struct tcp_header {
 BUILD_ASSERT_DECL(TCP_HEADER_LEN == sizeof(struct tcp_header));
 
 /* Connection states */
-#define CS_NEW               0x01
-#define CS_ESTABLISHED       0x02
-#define CS_RELATED           0x04
-#define CS_REPLY_DIR         0x08
-#define CS_INVALID           0x10
-#define CS_TRACKED           0x20
-#define CS_SRC_NAT           0x40
-#define CS_DST_NAT           0x80
+enum {
+    CS_NEW_BIT =         0,
+    CS_ESTABLISHED_BIT = 1,
+    CS_RELATED_BIT =     2,
+    CS_REPLY_DIR_BIT =   3,
+    CS_INVALID_BIT =     4,
+    CS_TRACKED_BIT =     5,
+    CS_SRC_NAT_BIT =     6,
+    CS_DST_NAT_BIT =     7,
+};
+
+enum {
+    CS_NEW =         (1 << CS_NEW_BIT),
+    CS_ESTABLISHED = (1 << CS_ESTABLISHED_BIT),
+    CS_RELATED =     (1 << CS_RELATED_BIT),
+    CS_REPLY_DIR =   (1 << CS_REPLY_DIR_BIT),
+    CS_INVALID =     (1 << CS_INVALID_BIT),
+    CS_TRACKED =     (1 << CS_TRACKED_BIT),
+    CS_SRC_NAT =     (1 << CS_SRC_NAT_BIT),
+    CS_DST_NAT =     (1 << CS_DST_NAT_BIT),
+};
 
 /* Undefined connection state bits. */
 #define CS_SUPPORTED_MASK    (CS_NEW | CS_ESTABLISHED | CS_RELATED \
@@ -771,6 +801,8 @@ struct arp_eth_header {
 };
 BUILD_ASSERT_DECL(ARP_ETH_HEADER_LEN == sizeof(struct arp_eth_header));
 
+#define IPV6_HEADER_LEN 40
+
 /* Like struct in6_addr, but whereas that struct requires 32-bit alignment on
  * most implementations, this one only requires 16-bit alignment. */
 union ovs_16aligned_in6_addr {
@@ -811,6 +843,8 @@ struct icmp6_header {
 };
 BUILD_ASSERT_DECL(ICMP6_HEADER_LEN == sizeof(struct icmp6_header));
 
+uint32_t packet_csum_pseudoheader6(const struct ovs_16aligned_ip6_hdr *);
+
 /* Neighbor Discovery option field.
  * ND options are always a multiple of 8 bytes in size. */
 #define ND_OPT_LEN 8
@@ -916,13 +950,18 @@ static inline bool ipv6_addr_is_multicast(const struct in6_addr *ip) {
     return ip->s6_addr[0] == 0xff;
 }
 
+static inline struct in6_addr
+in6_addr_mapped_ipv4(ovs_be32 ip4)
+{
+    struct in6_addr ip6 = { .s6_addr = { [10] = 0xff, [11] = 0xff } };
+    memcpy(&ip6.s6_addr[12], &ip4, 4);
+    return ip6;
+}
+
 static inline void
-in6_addr_set_mapped_ipv4(struct in6_addr *addr, ovs_be32 ip4)
+in6_addr_set_mapped_ipv4(struct in6_addr *ip6, ovs_be32 ip4)
 {
-    union ovs_16aligned_in6_addr *taddr = (void *) addr;
-    memset(taddr->be16, 0, sizeof(taddr->be16));
-    taddr->be16[5] = OVS_BE16_MAX;
-    put_16aligned_be32(&taddr->be32[3], ip4);
+    *ip6 = in6_addr_mapped_ipv4(ip4);
 }
 
 static inline ovs_be32
@@ -936,6 +975,28 @@ in6_addr_get_mapped_ipv4(const struct in6_addr *addr)
     }
 }
 
+static inline void
+in6_addr_solicited_node(struct in6_addr *addr, const struct in6_addr *ip6)
+{
+    union ovs_16aligned_in6_addr *taddr = (void *) addr;
+    memset(taddr->be16, 0, sizeof(taddr->be16));
+    taddr->be16[0] = htons(0xff02);
+    taddr->be16[5] = htons(0x1);
+    taddr->be16[6] = htons(0xff00);
+    memcpy(&addr->s6_addr[13], &ip6->s6_addr[13], 3);
+}
+
+static inline void
+ipv6_multicast_to_ethernet(struct eth_addr *eth, const struct in6_addr *ip6)
+{
+    eth->ea[0] = 0x33;
+    eth->ea[1] = 0x33;
+    eth->ea[2] = ip6->s6_addr[12];
+    eth->ea[3] = ip6->s6_addr[13];
+    eth->ea[4] = ip6->s6_addr[14];
+    eth->ea[5] = ip6->s6_addr[15];
+}
+
 static inline bool dl_type_is_ip_any(ovs_be16 dl_type)
 {
     return dl_type == htons(ETH_TYPE_IP)
@@ -979,8 +1040,17 @@ struct in6_addr ipv6_addr_bitand(const struct in6_addr *src,
 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);
+
+bool ipv6_parse(const char *s, struct in6_addr *ip);
 char *ipv6_parse_masked(const char *s, struct in6_addr *ipv6,
                         struct in6_addr *mask);
+char *ipv6_parse_cidr(const char *s, struct in6_addr *ip, unsigned int *plen)
+    OVS_WARN_UNUSED_RESULT;
+char *ipv6_parse_masked_len(const char *s, int *n, struct in6_addr *ipv6,
+                            struct in6_addr *mask);
+char *ipv6_parse_cidr_len(const char *s, int *n, struct in6_addr *ip,
+                          unsigned int *plen)
+    OVS_WARN_UNUSED_RESULT;
 
 void *eth_compose(struct dp_packet *, const struct eth_addr eth_dst,
                   const struct eth_addr eth_src, uint16_t eth_type,
@@ -1006,6 +1076,8 @@ void compose_arp(struct dp_packet *, uint16_t arp_op,
                  const struct eth_addr arp_sha,
                  const struct eth_addr arp_tha, bool broadcast,
                  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 *);
 uint32_t packet_csum_pseudoheader(const struct ip_header *);
 
 #endif /* packets.h */