X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fpackets.h;h=39e88f1f571b35c28c5e2de5cba02388eda50ac3;hb=eb9b830766044475277a590dbf8d213b77b62188;hp=eaffca939c063adeb7429d835ca0c2a699ce2037;hpb=c69ee87c10818267f991236201150b1fa51ae519;p=openvswitch diff --git a/lib/packets.h b/lib/packets.h index eaffca93..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 @@ -190,7 +197,28 @@ struct llc_snap_header { BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); #define VLAN_VID_MASK 0x0fff +#define VLAN_VID_SHIFT 0 + #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 { @@ -209,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 @@ -220,10 +265,23 @@ 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)) +/* TOS fields. */ +#define IP_ECN_MASK 0x03 +#define IP_DSCP_MASK 0xfc + #define IP_TYPE_ICMP 1 #define IP_TYPE_TCP 6 #define IP_TYPE_UDP 17