X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fpackets.c;h=b95e1e010519f91677fe30c4bf622ba594f633b3;hb=6b900de4efd368be88ef3db88b1eff8f835a7cf7;hp=4f57d16661220aca49bf995bf1a29a73358ae9ff;hpb=b02475c53b3ca857c45eb5e17d12fdf233a9dac8;p=sliver-openvswitch.git diff --git a/lib/packets.c b/lib/packets.c index 4f57d1666..b95e1e010 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -27,6 +27,7 @@ #include "hmap.h" #include "dynamic-string.h" #include "ofpbuf.h" +#include "ovs-thread.h" const struct in6_addr in6addr_exact = IN6ADDR_EXACT_INIT; @@ -54,27 +55,27 @@ eth_addr_is_reserved(const uint8_t ea[ETH_ADDR_LEN]) { struct eth_addr_node { struct hmap_node hmap_node; - uint64_t ea64; + const uint64_t ea64; }; static struct eth_addr_node nodes[] = { /* STP, IEEE pause frames, and other reserved protocols. */ - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000000ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000001ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000002ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000003ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000004ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000005ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000006ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000007ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000008ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000009ULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000aULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000bULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000cULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000dULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000eULL }, - { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000fULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000000ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000001ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000002ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000003ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000004ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000005ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000006ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000007ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000008ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000009ULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000aULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000bULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000cULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000dULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000eULL }, + { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000fULL }, /* Extreme protocols. */ { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000000ULL }, /* EDP. */ @@ -100,15 +101,18 @@ eth_addr_is_reserved(const uint8_t ea[ETH_ADDR_LEN]) { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc7ULL }, }; - static struct hmap addrs = HMAP_INITIALIZER(&addrs); + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; struct eth_addr_node *node; + static struct hmap addrs; uint64_t ea64; - if (hmap_is_empty(&addrs)) { + if (ovsthread_once_start(&once)) { + hmap_init(&addrs); for (node = nodes; node < &nodes[ARRAY_SIZE(nodes)]; node++) { hmap_insert(&addrs, &node->hmap_node, hash_2words(node->ea64, node->ea64 >> 32)); } + ovsthread_once_done(&once); } ea64 = eth_addr_to_uint64(ea); @@ -246,7 +250,8 @@ set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type) if (eh->eth_type == htons(ETH_TYPE_VLAN)) { ovs_be16 *p; - p = (ovs_be16 *)((char *)(packet->l2_5 ? packet->l2_5 : packet->l3) - 2); + p = ALIGNED_CAST(ovs_be16 *, + (char *)(packet->l2_5 ? packet->l2_5 : packet->l3) - 2); *p = eth_type; } else { eh->eth_type = eth_type; @@ -259,7 +264,7 @@ static bool is_mpls(struct ofpbuf *packet) } /* Set time to live (TTL) of an MPLS label stack entry (LSE). */ -static void +void set_mpls_lse_ttl(ovs_be32 *lse, uint8_t ttl) { *lse &= ~htonl(MPLS_TTL_MASK); @@ -373,10 +378,9 @@ pop_mpls(struct ofpbuf *packet, ovs_be16 ethtype) size_t len; mh = packet->l2_5; len = (char*)packet->l2_5 - (char*)packet->l2; - /* If bottom of the stack set ethertype. */ + set_ethertype(packet, ethtype); if (mh->mpls_lse & htonl(MPLS_BOS_MASK)) { packet->l2_5 = NULL; - set_ethertype(packet, ethtype); } else { packet->l2_5 = (char*)packet->l2_5 + MPLS_HLEN; } @@ -667,7 +671,7 @@ packet_rh_present(struct ofpbuf *packet) if (remaining < sizeof *nh) { return false; } - nh = (struct ip6_hdr *)data; + nh = ALIGNED_CAST(struct ip6_hdr *, data); data += sizeof *nh; remaining -= sizeof *nh; nexthdr = nh->ip6_nxt; @@ -703,7 +707,8 @@ packet_rh_present(struct ofpbuf *packet) nexthdr = ext_hdr->ip6e_nxt; len = (ext_hdr->ip6e_len + 2) * 4; } else if (nexthdr == IPPROTO_FRAGMENT) { - const struct ip6_frag *frag_hdr = (struct ip6_frag *)data; + const struct ip6_frag *frag_hdr = ALIGNED_CAST(struct ip6_frag *, + data); nexthdr = frag_hdr->ip6f_nxt; len = sizeof *frag_hdr; @@ -887,7 +892,8 @@ packet_set_udp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst) uint8_t packet_get_tcp_flags(const struct ofpbuf *packet, const struct flow *flow) { - if (is_ip_any(flow) && flow->nw_proto == IPPROTO_TCP && packet->l7) { + if (dl_type_is_ip_any(flow->dl_type) && + flow->nw_proto == IPPROTO_TCP && packet->l7) { const struct tcp_header *tcp = packet->l4; return TCP_FLAGS(tcp->tcp_ctl); } else {