X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fpackets.h;h=39e88f1f571b35c28c5e2de5cba02388eda50ac3;hb=6f20002c1201c1fc78fc7cedb49b103d8afe9da6;hp=7ea462bcf77ae19e68e2961c5aeb7e5aad5d19b3;hpb=a0bc29a541fc7dc6e20137d5558e2094d614e6ab;p=openvswitch diff --git a/lib/packets.h b/lib/packets.h index 7ea462bc..39e88f1f 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -18,9 +18,12 @@ #define PACKETS_H 1 #include +#include +#include #include #include #include "compiler.h" +#include "openvswitch/types.h" #include "random.h" #include "util.h" @@ -33,6 +36,9 @@ bool dpid_from_string(const char *s, uint64_t *dpidp); static const uint8_t eth_addr_broadcast[ETH_ADDR_LEN] OVS_UNUSED = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +static const uint8_t eth_addr_stp[ETH_ADDR_LEN] OVS_UNUSED + = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 }; + static inline bool eth_addr_is_broadcast(const uint8_t ea[6]) { return (ea[0] & ea[1] & ea[2] & ea[3] & ea[4] & ea[5]) == 0xff; @@ -42,19 +48,19 @@ static inline bool eth_addr_is_multicast(const uint8_t ea[6]) { return ea[0] & 1; } -static inline bool eth_addr_is_local(const uint8_t ea[6]) +static inline bool eth_addr_is_local(const uint8_t ea[6]) { /* Local if it is either a locally administered address or a Nicira random * address. */ return !!(ea[0] & 2) || (ea[0] == 0x00 && ea[1] == 0x23 && ea[2] == 0x20 && !!(ea[3] & 0x80)); } -static inline bool eth_addr_is_zero(const uint8_t ea[6]) +static inline bool eth_addr_is_zero(const uint8_t ea[6]) { return !(ea[0] | ea[1] | ea[2] | ea[3] | ea[4] | ea[5]); } static inline bool eth_addr_equals(const uint8_t a[ETH_ADDR_LEN], - const uint8_t b[ETH_ADDR_LEN]) + const uint8_t b[ETH_ADDR_LEN]) { return !memcmp(a, b, ETH_ADDR_LEN); } @@ -147,6 +153,7 @@ void compose_benign_packet(struct ofpbuf *, const char *tag, #define ETH_TYPE_IP 0x0800 #define ETH_TYPE_ARP 0x0806 #define ETH_TYPE_VLAN 0x8100 +#define ETH_TYPE_CFM 0x8902 #define ETH_HEADER_LEN 14 #define ETH_PAYLOAD_MIN 46 @@ -195,6 +202,24 @@ BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); #define VLAN_PCP_MASK 0xe000 #define VLAN_PCP_SHIFT 13 +#define VLAN_CFI 0x1000 + +/* Given the vlan_tci field from an 802.1Q header, in network byte order, + * returns the VLAN ID in host byte order. */ +static inline uint16_t +vlan_tci_to_vid(uint16_t vlan_tci) +{ + return (ntohs(vlan_tci) & VLAN_VID_MASK) >> VLAN_VID_SHIFT; +} + +/* Given the vlan_tci field from an 802.1Q header, in network byte order, + * returns the priority code point (PCP) in host byte order. */ +static inline int +vlan_tci_to_pcp(uint16_t vlan_tci) +{ + return (ntohs(vlan_tci) & VLAN_PCP_MASK) >> VLAN_PCP_SHIFT; +} + #define VLAN_HEADER_LEN 4 struct vlan_header { uint16_t vlan_tci; /* Lowest 12 bits are VLAN ID. */ @@ -212,6 +237,23 @@ struct vlan_eth_header { } __attribute__((packed)); BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); +/* A 'ccm' represents a Continuity Check Message from the 802.1ag specification. + * Continuity Check Messages are broadcast periodically so that hosts can + * determine who they have connectivity to. */ +#define CCM_LEN 74 +#define CCM_MAID_LEN 48 +struct ccm { + uint8_t mdlevel_version; /* MD Level and Version */ + uint8_t opcode; + uint8_t flags; + uint8_t tlv_offset; + uint32_t seq; + uint16_t mpid; + uint8_t maid[CCM_MAID_LEN]; + uint8_t zero[16]; /* Defined by ITU-T Y.1731 should be zero */ +} __attribute__((packed)); +BUILD_ASSERT_DECL(CCM_LEN == sizeof(struct ccm)); + /* The "(void) (ip)[0]" below has no effect on the value, since it's the first * argument of a comma expression, but it makes sure that 'ip' is a pointer. * This is useful since a common mistake is to pass an integer instead of a @@ -223,6 +265,15 @@ BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); ((uint8_t *) ip)[2], \ ((uint8_t *) ip)[3] +/* Returns true if 'netmask' is a CIDR netmask, that is, if it consists of N + * high-order 1-bits and 32-N low-order 0-bits. */ +static inline bool +ip_is_cidr(ovs_be32 netmask) +{ + uint32_t x = ~ntohl(netmask); + return !(x & (x + 1)); +} + #define IP_VER(ip_ihl_ver) ((ip_ihl_ver) >> 4) #define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15) #define IP_IHL_VER(ihl, ver) (((ver) << 4) | (ihl))