Skip to content

Commit

Permalink
packets: Un-inline functions needed by DDlog.
Browse files Browse the repository at this point in the history
DDlog uses these functions from Rust, but Rust can't use inline
functions (since it doesn't compile C headers but only links
against a C-compatible ABI).  Thus, move the implementations
of these functions to a .c file.

I don't think any of these functions is likely to be an
important part of a "fast path" in OVS, but if that's wrong,
then we could take another approach.

Signed-off-by: Leonid Ryzhyk <lryzhyk@vmware.com>
Co-authored-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
2 people authored and ovsrobot committed Oct 23, 2020
1 parent 04d1406 commit d8a72cc
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 86 deletions.
97 changes: 97 additions & 0 deletions lib/packets.c
Expand Up @@ -75,6 +75,29 @@ dpid_from_string(const char *s, uint64_t *dpidp)
return *dpidp != 0;
}

uint64_t
eth_addr_to_uint64(const struct eth_addr ea)
{
return (((uint64_t) ntohs(ea.be16[0]) << 32)
| ((uint64_t) ntohs(ea.be16[1]) << 16)
| ntohs(ea.be16[2]));
}

void
eth_addr_from_uint64(uint64_t x, struct eth_addr *ea)
{
ea->be16[0] = htons(x >> 32);
ea->be16[1] = htons((x & 0xFFFF0000) >> 16);
ea->be16[2] = htons(x & 0xFFFF);
}

void
eth_addr_mark_random(struct eth_addr *ea)
{
ea->ea[0] &= ~1; /* Unicast. */
ea->ea[0] |= 2; /* Private. */
}

/* Returns true if 'ea' is a reserved address, that a bridge must never
* forward, false otherwise.
*
Expand Down Expand Up @@ -524,6 +547,79 @@ eth_format_masked(const struct eth_addr eth,
}
}

void
in6_addr_solicited_node(struct in6_addr *addr, const struct in6_addr *ip6)
{
union ovs_16aligned_in6_addr *taddr =
(union ovs_16aligned_in6_addr *) 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);
}

/*
* Generates ipv6 EUI64 address from the given eth addr
* and prefix and stores it in 'lla'
*/
void
in6_generate_eui64(struct eth_addr ea, const struct in6_addr *prefix,
struct in6_addr *lla)
{
union ovs_16aligned_in6_addr *taddr =
(union ovs_16aligned_in6_addr *) lla;
union ovs_16aligned_in6_addr *prefix_taddr =
(union ovs_16aligned_in6_addr *) prefix;
taddr->be16[0] = prefix_taddr->be16[0];
taddr->be16[1] = prefix_taddr->be16[1];
taddr->be16[2] = prefix_taddr->be16[2];
taddr->be16[3] = prefix_taddr->be16[3];
taddr->be16[4] = htons(((ea.ea[0] ^ 0x02) << 8) | ea.ea[1]);
taddr->be16[5] = htons(ea.ea[2] << 8 | 0x00ff);
taddr->be16[6] = htons(0xfe << 8 | ea.ea[3]);
taddr->be16[7] = ea.be16[2];
}

/* Generates ipv6 link local address from the given eth addr
* with prefix 'fe80::/64' and stores it in 'lla'. */
void
in6_generate_lla(struct eth_addr ea, struct in6_addr *lla)
{
union ovs_16aligned_in6_addr *taddr =
(union ovs_16aligned_in6_addr *) lla;
memset(taddr->be16, 0, sizeof(taddr->be16));
taddr->be16[0] = htons(0xfe80);
taddr->be16[4] = htons(((ea.ea[0] ^ 0x02) << 8) | ea.ea[1]);
taddr->be16[5] = htons(ea.ea[2] << 8 | 0x00ff);
taddr->be16[6] = htons(0xfe << 8 | ea.ea[3]);
taddr->be16[7] = ea.be16[2];
}

/* Returns true if 'addr' is a link local address. Otherwise, false. */
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] == 0xfe && addr->s6_addr[1] == 0x80 &&
!(addr->s6_addr[2] | addr->s6_addr[3] | addr->s6_addr[4] |
addr->s6_addr[5] | addr->s6_addr[6] | addr->s6_addr[7]);
#endif
}

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];
}

/* Given the IP netmask 'netmask', returns the number of bits of the IP address
* that it specifies, that is, the number of 1-bits in 'netmask'.
*
Expand Down Expand Up @@ -957,6 +1053,7 @@ eth_compose(struct dp_packet *b, const struct eth_addr eth_dst,
void *data;
struct eth_header *eth;


dp_packet_clear(b);

/* The magic 2 here ensures that the L3 header (when it is added later)
Expand Down
97 changes: 11 additions & 86 deletions lib/packets.h
Expand Up @@ -281,25 +281,15 @@ static inline bool eth_addr_equal_except(const struct eth_addr a,
|| ((a.be16[2] ^ b.be16[2]) & mask.be16[2]));
}

static inline uint64_t eth_addr_to_uint64(const struct eth_addr ea)
{
return (((uint64_t) ntohs(ea.be16[0]) << 32)
| ((uint64_t) ntohs(ea.be16[1]) << 16)
| ntohs(ea.be16[2]));
}
uint64_t eth_addr_to_uint64(const struct eth_addr ea);

static inline uint64_t eth_addr_vlan_to_uint64(const struct eth_addr ea,
uint16_t vlan)
{
return (((uint64_t)vlan << 48) | eth_addr_to_uint64(ea));
}

static inline void eth_addr_from_uint64(uint64_t x, struct eth_addr *ea)
{
ea->be16[0] = htons(x >> 32);
ea->be16[1] = htons((x & 0xFFFF0000) >> 16);
ea->be16[2] = htons(x & 0xFFFF);
}
void eth_addr_from_uint64(uint64_t x, struct eth_addr *ea);

static inline struct eth_addr eth_addr_invert(const struct eth_addr src)
{
Expand All @@ -312,11 +302,7 @@ static inline struct eth_addr eth_addr_invert(const struct eth_addr src)
return dst;
}

static inline void eth_addr_mark_random(struct eth_addr *ea)
{
ea->ea[0] &= ~1; /* Unicast. */
ea->ea[0] |= 2; /* Private. */
}
void eth_addr_mark_random(struct eth_addr *ea);

static inline void eth_addr_random(struct eth_addr *ea)
{
Expand Down Expand Up @@ -1211,80 +1197,19 @@ 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 =
(union ovs_16aligned_in6_addr *) 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);
}
void in6_addr_solicited_node(struct in6_addr *addr,
const struct in6_addr *ip6);

/*
* Generates ipv6 EUI64 address from the given eth addr
* and prefix and stores it in 'lla'
*/
static inline void
in6_generate_eui64(struct eth_addr ea, struct in6_addr *prefix,
struct in6_addr *lla)
{
union ovs_16aligned_in6_addr *taddr =
(union ovs_16aligned_in6_addr *) lla;
union ovs_16aligned_in6_addr *prefix_taddr =
(union ovs_16aligned_in6_addr *) prefix;
taddr->be16[0] = prefix_taddr->be16[0];
taddr->be16[1] = prefix_taddr->be16[1];
taddr->be16[2] = prefix_taddr->be16[2];
taddr->be16[3] = prefix_taddr->be16[3];
taddr->be16[4] = htons(((ea.ea[0] ^ 0x02) << 8) | ea.ea[1]);
taddr->be16[5] = htons(ea.ea[2] << 8 | 0x00ff);
taddr->be16[6] = htons(0xfe << 8 | ea.ea[3]);
taddr->be16[7] = ea.be16[2];
}
void in6_generate_eui64(struct eth_addr ea, const struct in6_addr *prefix,
struct in6_addr *lla);

/*
* Generates ipv6 link local address from the given eth addr
* with prefix 'fe80::/64' and stores it in 'lla'
*/
static inline void
in6_generate_lla(struct eth_addr ea, struct in6_addr *lla)
{
union ovs_16aligned_in6_addr *taddr =
(union ovs_16aligned_in6_addr *) lla;
memset(taddr->be16, 0, sizeof(taddr->be16));
taddr->be16[0] = htons(0xfe80);
taddr->be16[4] = htons(((ea.ea[0] ^ 0x02) << 8) | ea.ea[1]);
taddr->be16[5] = htons(ea.ea[2] << 8 | 0x00ff);
taddr->be16[6] = htons(0xfe << 8 | ea.ea[3]);
taddr->be16[7] = ea.be16[2];
}
void in6_generate_lla(struct eth_addr ea, struct in6_addr *lla);

/* 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] == 0xfe && addr->s6_addr[1] == 0x80 &&
!(addr->s6_addr[2] | addr->s6_addr[3] | addr->s6_addr[4] |
addr->s6_addr[5] | addr->s6_addr[6] | addr->s6_addr[7]);
#endif
}
bool in6_is_lla(struct in6_addr *addr);

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];
}
void ipv6_multicast_to_ethernet(struct eth_addr *eth,
const struct in6_addr *ip6);

static inline bool dl_type_is_ip_any(ovs_be16 dl_type)
{
Expand Down

0 comments on commit d8a72cc

Please sign in to comment.