X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fpackets.h;h=e8527618383c211f2842eb97c223337f8841a7ea;hb=bbb8dee92d639331e8bd81823638267dcc895396;hp=8dd3ebff25d0dd251cd17b30d5653f1b2c03ab45;hpb=305b76debf72120672a8ba81d3356b6dccb1da9a;p=sliver-openvswitch.git diff --git a/lib/packets.h b/lib/packets.h index 8dd3ebff2..e85276183 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -140,6 +140,10 @@ void compose_rarp(struct ofpbuf *, const uint8_t eth_src[ETH_ADDR_LEN]); void eth_push_vlan(struct ofpbuf *, ovs_be16 tci); void eth_pop_vlan(struct ofpbuf *); +uint16_t eth_mpls_depth(const struct ofpbuf *packet); + +void set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type); + const char *eth_from_hex(const char *hex, struct ofpbuf **packetp); void eth_format_masked(const uint8_t eth[ETH_ADDR_LEN], const uint8_t mask[ETH_ADDR_LEN], struct ds *s); @@ -147,6 +151,17 @@ void eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN], const uint8_t mask[ETH_ADDR_LEN], uint8_t dst[ETH_ADDR_LEN]); +void set_mpls_lse(struct ofpbuf *, ovs_be32 label); +void push_mpls(struct ofpbuf *packet, ovs_be16 ethtype, ovs_be32 lse); +void pop_mpls(struct ofpbuf *, ovs_be16 ethtype); + +void set_mpls_lse_ttl(ovs_be32 *lse, uint8_t ttl); +void set_mpls_lse_tc(ovs_be32 *lse, uint8_t tc); +void set_mpls_lse_label(ovs_be32 *lse, ovs_be32 label); +void set_mpls_lse_bos(ovs_be32 *lse, uint8_t bos); +ovs_be32 set_mpls_lse_values(uint8_t ttl, uint8_t tc, uint8_t bos, + ovs_be32 label); + /* Example: * * uint8_t mac[ETH_ADDR_LEN]; @@ -186,6 +201,12 @@ void eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN], #define ETH_TYPE_MPLS 0x8847 #define ETH_TYPE_MPLS_MCAST 0x8848 +static inline bool eth_type_mpls(ovs_be16 eth_type) +{ + return eth_type == htons(ETH_TYPE_MPLS) || + eth_type == htons(ETH_TYPE_MPLS_MCAST); +} + /* Minimum value for an Ethernet type. Values below this are IEEE 802.2 frame * lengths. */ #define ETH_TYPE_MIN 0x600 @@ -196,11 +217,12 @@ void eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN], #define ETH_TOTAL_MIN (ETH_HEADER_LEN + ETH_PAYLOAD_MIN) #define ETH_TOTAL_MAX (ETH_HEADER_LEN + ETH_PAYLOAD_MAX) #define ETH_VLAN_TOTAL_MAX (ETH_HEADER_LEN + VLAN_HEADER_LEN + ETH_PAYLOAD_MAX) +OVS_PACKED( struct eth_header { uint8_t eth_dst[ETH_ADDR_LEN]; uint8_t eth_src[ETH_ADDR_LEN]; ovs_be16 eth_type; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(ETH_HEADER_LEN == sizeof(struct eth_header)); #define LLC_DSAP_SNAP 0xaa @@ -208,27 +230,30 @@ BUILD_ASSERT_DECL(ETH_HEADER_LEN == sizeof(struct eth_header)); #define LLC_CNTL_SNAP 3 #define LLC_HEADER_LEN 3 +OVS_PACKED( struct llc_header { uint8_t llc_dsap; uint8_t llc_ssap; uint8_t llc_cntl; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(LLC_HEADER_LEN == sizeof(struct llc_header)); #define SNAP_ORG_ETHERNET "\0\0" /* The compiler adds a null byte, so sizeof(SNAP_ORG_ETHERNET) == 3. */ #define SNAP_HEADER_LEN 5 +OVS_PACKED( struct snap_header { uint8_t snap_org[3]; ovs_be16 snap_type; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(SNAP_HEADER_LEN == sizeof(struct snap_header)); #define LLC_SNAP_HEADER_LEN (LLC_HEADER_LEN + SNAP_HEADER_LEN) +OVS_PACKED( struct llc_snap_header { struct llc_header llc; struct snap_header snap; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); #define VLAN_VID_MASK 0x0fff @@ -238,6 +263,7 @@ BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); #define VLAN_PCP_SHIFT 13 #define VLAN_CFI 0x1000 +#define VLAN_CFI_SHIFT 12 /* Given the vlan_tci field from an 802.1Q header, in network byte order, * returns the VLAN ID in host byte order. */ @@ -255,6 +281,14 @@ vlan_tci_to_pcp(ovs_be16 vlan_tci) return (ntohs(vlan_tci) & VLAN_PCP_MASK) >> VLAN_PCP_SHIFT; } +/* Given the vlan_tci field from an 802.1Q header, in network byte order, + * returns the Canonical Format Indicator (CFI). */ +static inline int +vlan_tci_to_cfi(ovs_be16 vlan_tci) +{ + return (vlan_tci & htons(VLAN_CFI)) != 0; +} + #define VLAN_HEADER_LEN 4 struct vlan_header { ovs_be16 vlan_tci; /* Lowest 12 bits are VLAN ID. */ @@ -263,15 +297,76 @@ struct vlan_header { BUILD_ASSERT_DECL(VLAN_HEADER_LEN == sizeof(struct vlan_header)); #define VLAN_ETH_HEADER_LEN (ETH_HEADER_LEN + VLAN_HEADER_LEN) +OVS_PACKED( struct vlan_eth_header { uint8_t veth_dst[ETH_ADDR_LEN]; uint8_t veth_src[ETH_ADDR_LEN]; ovs_be16 veth_type; /* Always htons(ETH_TYPE_VLAN). */ ovs_be16 veth_tci; /* Lowest 12 bits are VLAN ID. */ ovs_be16 veth_next_type; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); +/* MPLS related definitions */ +#define MPLS_TTL_MASK 0x000000ff +#define MPLS_TTL_SHIFT 0 + +#define MPLS_BOS_MASK 0x00000100 +#define MPLS_BOS_SHIFT 8 + +#define MPLS_TC_MASK 0x00000e00 +#define MPLS_TC_SHIFT 9 + +#define MPLS_LABEL_MASK 0xfffff000 +#define MPLS_LABEL_SHIFT 12 + +#define MPLS_HLEN 4 + +struct mpls_hdr { + ovs_be32 mpls_lse; +}; +BUILD_ASSERT_DECL(MPLS_HLEN == sizeof(struct mpls_hdr)); + +/* Given a mpls label stack entry in network byte order + * return mpls label in host byte order */ +static inline uint32_t +mpls_lse_to_label(ovs_be32 mpls_lse) +{ + return (ntohl(mpls_lse) & MPLS_LABEL_MASK) >> MPLS_LABEL_SHIFT; +} + +/* Given a mpls label stack entry in network byte order + * return mpls tc */ +static inline uint8_t +mpls_lse_to_tc(ovs_be32 mpls_lse) +{ + return (ntohl(mpls_lse) & MPLS_TC_MASK) >> MPLS_TC_SHIFT; +} + +/* Given a mpls label stack entry in network byte order + * return mpls ttl */ +static inline uint8_t +mpls_lse_to_ttl(ovs_be32 mpls_lse) +{ + return (ntohl(mpls_lse) & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT; +} + +/* Set TTL in mpls lse. */ +static inline void +flow_set_mpls_lse_ttl(ovs_be32 *mpls_lse, uint8_t ttl) +{ + *mpls_lse &= ~htonl(MPLS_TTL_MASK); + *mpls_lse |= htonl(ttl << MPLS_TTL_SHIFT); +} + +/* Given a mpls label stack entry in network byte order + * return mpls BoS bit */ +static inline uint8_t +mpls_lse_to_bos(ovs_be32 mpls_lse) +{ + return (mpls_lse & htonl(MPLS_BOS_MASK)) != 0; +} + #define IP_FMT "%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32 #define IP_ARGS(ip) \ ntohl(ip) >> 24, \ @@ -413,6 +508,7 @@ BUILD_ASSERT_DECL(TCP_HEADER_LEN == sizeof(struct tcp_header)); #define ARP_OP_RARP 3 #define ARP_ETH_HEADER_LEN 28 +OVS_PACKED( struct arp_eth_header { /* Generic members. */ ovs_be16 ar_hrd; /* Hardware type. */ @@ -426,7 +522,7 @@ struct arp_eth_header { ovs_be32 ar_spa; /* Sender protocol address. */ uint8_t ar_tha[ETH_ADDR_LEN]; /* Target hardware address. */ ovs_be32 ar_tpa; /* Target protocol address. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(ARP_ETH_HEADER_LEN == sizeof(struct arp_eth_header)); /* The IPv6 flow label is in the lower 20 bits of the first 32-bit word. */ @@ -468,10 +564,15 @@ static inline bool ipv6_mask_is_exact(const struct in6_addr *mask) { return ipv6_addr_equals(mask, &in6addr_exact); } +static inline bool dl_type_is_ip_any(ovs_be16 dl_type) +{ + return dl_type == htons(ETH_TYPE_IP) + || dl_type == htons(ETH_TYPE_IPV6); +} + static inline bool is_ip_any(const struct flow *flow) { - return flow->dl_type == htons(ETH_TYPE_IP) - || flow->dl_type == htons(ETH_TYPE_IPV6); + return dl_type_is_ip_any(flow->dl_type); } void format_ipv6_addr(char *addr_str, const struct in6_addr *addr);