X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fpackets.h;h=f9e5bb6cef61ef44e6f63d68d356df238611be37;hb=e0edde6fee279cdbbf3c179f5f50adaf0c7c7f1e;hp=f45c33121fa11fead88950d88ac1418766c928e9;hpb=81aee5f901556e778069a70613d99a87ddcf2116;p=sliver-openvswitch.git diff --git a/lib/packets.h b/lib/packets.h index f45c33121..f9e5bb6ce 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ struct ofpbuf; struct ds; +struct flow; bool dpid_from_string(const char *s, uint64_t *dpidp); @@ -38,7 +39,7 @@ 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 }; + = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }; static const uint8_t eth_addr_lacp[ETH_ADDR_LEN] OVS_UNUSED = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }; @@ -56,8 +57,8 @@ 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)); + 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]) { @@ -131,7 +132,10 @@ void compose_benign_packet(struct ofpbuf *, const char *tag, uint16_t snap_type, const uint8_t eth_src[ETH_ADDR_LEN]); -void eth_set_vlan_tci(struct ofpbuf *, ovs_be16 tci); +void eth_push_vlan(struct ofpbuf *, ovs_be16 tci); +void eth_pop_vlan(struct ofpbuf *); + +const char *eth_from_hex(const char *hex, struct ofpbuf **packetp); /* Example: * @@ -264,6 +268,25 @@ BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); ((uint8_t *) ip)[2], \ ((uint8_t *) ip)[3] +/* Example: + * + * char *string = "1 33.44.55.66 2"; + * ovs_be32 ip; + * int a, b; + * + * if (sscanf(string, "%d"IP_SCAN_FMT"%d", + * &a, IP_SCAN_ARGS(&ip), &b) == 1 + IP_SCAN_COUNT + 1) { + * ... + * } + */ +#define IP_SCAN_FMT "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8 +#define IP_SCAN_ARGS(ip) \ + ((void) (ovs_be32) *(ip), &((uint8_t *) ip)[0]), \ + &((uint8_t *) ip)[1], \ + &((uint8_t *) ip)[2], \ + &((uint8_t *) ip)[3] +#define IP_SCAN_COUNT 4 + /* 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 @@ -272,6 +295,13 @@ ip_is_cidr(ovs_be32 netmask) uint32_t x = ~ntohl(netmask); return !(x & (x + 1)); } +static inline bool +ip_is_multicast(ovs_be32 ip) +{ + return (ip & htonl(0xf0000000)) == htonl(0xe0000000); +} +int ip_count_cidr_bits(ovs_be32 netmask); +void ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *); #define IP_VER(ip_ihl_ver) ((ip_ihl_ver) >> 4) #define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15) @@ -304,11 +334,23 @@ struct ip_header { }; BUILD_ASSERT_DECL(IP_HEADER_LEN == sizeof(struct ip_header)); -#define ICMP_HEADER_LEN 4 +#define ICMP_HEADER_LEN 8 struct icmp_header { uint8_t icmp_type; uint8_t icmp_code; ovs_be16 icmp_csum; + union { + struct { + ovs_be16 id; + ovs_be16 seq; + } echo; + struct { + ovs_be16 empty; + ovs_be16 mtu; + } frag; + ovs_be32 gateway; + } icmp_fields; + uint8_t icmp_data[0]; }; BUILD_ASSERT_DECL(ICMP_HEADER_LEN == sizeof(struct icmp_header)); @@ -328,8 +370,9 @@ BUILD_ASSERT_DECL(UDP_HEADER_LEN == sizeof(struct udp_header)); #define TCP_ACK 0x10 #define TCP_URG 0x20 -#define TCP_FLAGS(tcp_ctl) (htons(tcp_ctl) & 0x003f) -#define TCP_OFFSET(tcp_ctl) (htons(tcp_ctl) >> 12) +#define TCP_CTL(flags, offset) (htons((flags) | ((offset) << 12))) +#define TCP_FLAGS(tcp_ctl) (ntohs(tcp_ctl) & 0x003f) +#define TCP_OFFSET(tcp_ctl) (ntohs(tcp_ctl) >> 12) #define TCP_HEADER_LEN 20 struct tcp_header { @@ -366,6 +409,23 @@ struct arp_eth_header { } __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. */ +#define IPV6_LABEL_MASK 0x000fffff + +/* Example: + * + * char *string = "1 ::1 2"; + * char ipv6_s[IPV6_SCAN_LEN + 1]; + * struct in6_addr ipv6; + * + * if (sscanf(string, "%d"IPV6_SCAN_FMT"%d", &a, ipv6_s, &b) == 3 + * && inet_pton(AF_INET6, ipv6_s, &ipv6) == 1) { + * ... + * } + */ +#define IPV6_SCAN_FMT "%46[0123456789abcdefABCDEF:.]" +#define IPV6_SCAN_LEN 46 + extern const struct in6_addr in6addr_exact; #define IN6ADDR_EXACT_INIT { { { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } } } @@ -390,6 +450,8 @@ static inline bool ipv6_mask_is_exact(const struct in6_addr *mask) { void format_ipv6_addr(char *addr_str, const struct in6_addr *addr); void print_ipv6_addr(struct ds *string, const struct in6_addr *addr); +void print_ipv6_masked(struct ds *string, const struct in6_addr *addr, + const struct in6_addr *mask); struct in6_addr ipv6_addr_bitand(const struct in6_addr *src, const struct in6_addr *mask); struct in6_addr ipv6_create_mask(int mask); @@ -402,5 +464,12 @@ void *eth_compose(struct ofpbuf *, const uint8_t eth_dst[ETH_ADDR_LEN], void *snap_compose(struct ofpbuf *, const uint8_t eth_dst[ETH_ADDR_LEN], const uint8_t eth_src[ETH_ADDR_LEN], unsigned int oui, uint16_t snap_type, size_t size); +void packet_set_ipv4(struct ofpbuf *, ovs_be32 src, ovs_be32 dst, uint8_t tos, + uint8_t ttl); +void packet_set_tcp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst); +void packet_set_udp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst); + +uint8_t packet_get_tcp_flags(const struct ofpbuf *, const struct flow *); +void packet_format_tcp_flags(struct ds *, uint8_t); #endif /* packets.h */