X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fpackets.c;h=6244c3f5fac85049a7788a32fb83639802ebb8ae;hb=cfc50ae514f805dcd9c14589f21158185424daf6;hp=3366089c101c4516db010057550160083d700c3e;hpb=437d0d22ab42d4101157b48a75fa844e7039e326;p=sliver-openvswitch.git diff --git a/lib/packets.c b/lib/packets.c index 3366089c1..6244c3f5f 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,13 +168,15 @@ compose_rarp(struct ofpbuf *b, const uint8_t eth_src[ETH_ADDR_LEN]) put_16aligned_be32(&arp->ar_spa, htonl(0)); memcpy(arp->ar_tha, eth_src, ETH_ADDR_LEN); put_16aligned_be32(&arp->ar_tpa, htonl(0)); + + ofpbuf_set_frame(b, eth); + ofpbuf_set_l3(b, arp); } /* Insert VLAN header according to given TCI. Packet passed must be Ethernet * packet. Ignores the CFI bit of 'tci' using 0 instead. * - * Also sets 'packet->l2' to point to the new Ethernet header and adjusts - * the layer offsets accordingly. */ + * Also adjusts the layer offsets accordingly. */ void eth_push_vlan(struct ofpbuf *packet, ovs_be16 tpid, ovs_be16 tci) { @@ -194,9 +196,9 @@ eth_push_vlan(struct ofpbuf *packet, ovs_be16 tpid, ovs_be16 tci) void eth_pop_vlan(struct ofpbuf *packet) { - struct vlan_eth_header *veh = packet->l2; + struct vlan_eth_header *veh = ofpbuf_l2(packet); - if (packet->size >= sizeof *veh + if (veh && ofpbuf_size(packet) >= sizeof *veh && veh->veth_type == htons(ETH_TYPE_VLAN)) { memmove((char *)veh + VLAN_HEADER_LEN, veh, 2 * ETH_ADDR_LEN); @@ -208,14 +210,18 @@ eth_pop_vlan(struct ofpbuf *packet) static void set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type) { - struct eth_header *eh = packet->l2; + struct eth_header *eh = ofpbuf_l2(packet); + + if (!eh) { + return; + } if (eh->eth_type == htons(ETH_TYPE_VLAN)) { ovs_be16 *p; - char *l2_5 = ofpbuf_get_l2_5(packet); + char *l2_5 = ofpbuf_l2_5(packet); p = ALIGNED_CAST(ovs_be16 *, - (l2_5 ? l2_5 : (char *)ofpbuf_get_l3(packet)) - 2); + (l2_5 ? l2_5 : (char *)ofpbuf_l3(packet)) - 2); *p = eth_type; } else { eh->eth_type = eth_type; @@ -279,10 +285,10 @@ set_mpls_lse(struct ofpbuf *packet, ovs_be32 mpls_lse) { /* Packet type should be MPLS to set label stack entry. */ if (is_mpls(packet)) { - struct mpls_hdr *mh = ofpbuf_get_l2_5(packet); + struct mpls_hdr *mh = ofpbuf_l2_5(packet); /* Update mpls label stack entry. */ - mh->mpls_lse = mpls_lse; + put_16aligned_be32(&mh->mpls_lse, mpls_lse); } } @@ -321,15 +327,15 @@ void pop_mpls(struct ofpbuf *packet, ovs_be16 ethtype) { if (is_mpls(packet)) { - struct mpls_hdr *mh = ofpbuf_get_l2_5(packet); + struct mpls_hdr *mh = ofpbuf_l2_5(packet); size_t len = packet->l2_5_ofs; set_ethertype(packet, ethtype); - if (mh->mpls_lse & htonl(MPLS_BOS_MASK)) { + if (get_16aligned_be32(&mh->mpls_lse) & htonl(MPLS_BOS_MASK)) { ofpbuf_set_l2_5(packet, NULL); } /* Shift the l2 header forward. */ - memmove((char*)packet->data + MPLS_HLEN, packet->data, len); + memmove((char*)ofpbuf_data(packet) + MPLS_HLEN, ofpbuf_data(packet), len); ofpbuf_resize_l2_5(packet, -MPLS_HLEN); } } @@ -353,7 +359,7 @@ eth_from_hex(const char *hex, struct ofpbuf **packetp) return "Trailing garbage in packet data"; } - if (packet->size < ETH_HEADER_LEN) { + if (ofpbuf_size(packet) < ETH_HEADER_LEN) { ofpbuf_delete(packet); *packetp = NULL; return "Packet data too short for Ethernet"; @@ -545,8 +551,8 @@ ipv6_is_cidr(const struct in6_addr *netmask) /* Populates 'b' with an Ethernet II packet headed with the given 'eth_dst', * 'eth_src' and 'eth_type' parameters. A payload of 'size' bytes is allocated * in 'b' and returned. This payload may be populated with appropriate - * information by the caller. Sets 'b''s 'l2' pointer and 'l3' offset to the - * Ethernet header and payload respectively. Aligns b->l3 on a 32-bit + * information by the caller. Sets 'b''s 'frame' pointer and 'l3' offset to + * the Ethernet header and payload respectively. Aligns b->l3 on a 32-bit * boundary. * * The returned packet has enough headroom to insert an 802.1Q VLAN header if @@ -572,7 +578,7 @@ eth_compose(struct ofpbuf *b, const uint8_t eth_dst[ETH_ADDR_LEN], memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN); eth->eth_type = htons(eth_type); - b->l2 = eth; + ofpbuf_set_frame(b, eth); ofpbuf_set_l3(b, data); return data; @@ -582,16 +588,16 @@ static void packet_set_ipv4_addr(struct ofpbuf *packet, ovs_16aligned_be32 *addr, ovs_be32 new_addr) { - struct ip_header *nh = ofpbuf_get_l3(packet); + struct ip_header *nh = ofpbuf_l3(packet); ovs_be32 old_addr = get_16aligned_be32(addr); - size_t l4_size = ofpbuf_get_l4_size(packet); + size_t l4_size = ofpbuf_l4_size(packet); if (nh->ip_proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) { - struct tcp_header *th = ofpbuf_get_l4(packet); + struct tcp_header *th = ofpbuf_l4(packet); th->tcp_csum = recalc_csum32(th->tcp_csum, old_addr, new_addr); } else if (nh->ip_proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN ) { - struct udp_header *uh = ofpbuf_get_l4(packet); + struct udp_header *uh = ofpbuf_l4(packet); if (uh->udp_csum) { uh->udp_csum = recalc_csum32(uh->udp_csum, old_addr, new_addr); @@ -615,7 +621,7 @@ packet_rh_present(struct ofpbuf *packet) int nexthdr; size_t len; size_t remaining; - uint8_t *data = ofpbuf_get_l3(packet); + uint8_t *data = ofpbuf_l3(packet); remaining = packet->l4_ofs - packet->l3_ofs; @@ -693,14 +699,14 @@ static void packet_update_csum128(struct ofpbuf *packet, uint8_t proto, ovs_16aligned_be32 addr[4], const ovs_be32 new_addr[4]) { - size_t l4_size = ofpbuf_get_l4_size(packet); + size_t l4_size = ofpbuf_l4_size(packet); if (proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) { - struct tcp_header *th = ofpbuf_get_l4(packet); + struct tcp_header *th = ofpbuf_l4(packet); th->tcp_csum = recalc_csum128(th->tcp_csum, addr, new_addr); } else if (proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN) { - struct udp_header *uh = ofpbuf_get_l4(packet); + struct udp_header *uh = ofpbuf_l4(packet); if (uh->udp_csum) { uh->udp_csum = recalc_csum128(uh->udp_csum, addr, new_addr); @@ -746,7 +752,7 @@ void packet_set_ipv4(struct ofpbuf *packet, ovs_be32 src, ovs_be32 dst, uint8_t tos, uint8_t ttl) { - struct ip_header *nh = ofpbuf_get_l3(packet); + struct ip_header *nh = ofpbuf_l3(packet); if (get_16aligned_be32(&nh->ip_src) != src) { packet_set_ipv4_addr(packet, &nh->ip_src, src); @@ -782,7 +788,7 @@ packet_set_ipv6(struct ofpbuf *packet, uint8_t proto, const ovs_be32 src[4], const ovs_be32 dst[4], uint8_t key_tc, ovs_be32 key_fl, uint8_t key_hl) { - struct ovs_16aligned_ip6_hdr *nh = ofpbuf_get_l3(packet); + struct ovs_16aligned_ip6_hdr *nh = ofpbuf_l3(packet); if (memcmp(&nh->ip6_src, src, sizeof(ovs_be32[4]))) { packet_set_ipv6_addr(packet, proto, nh->ip6_src.be32, src, true); @@ -815,7 +821,7 @@ packet_set_port(ovs_be16 *port, ovs_be16 new_port, ovs_be16 *csum) void packet_set_tcp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst) { - struct tcp_header *th = ofpbuf_get_l4(packet); + struct tcp_header *th = ofpbuf_l4(packet); packet_set_port(&th->tcp_src, src, &th->tcp_csum); packet_set_port(&th->tcp_dst, dst, &th->tcp_csum); @@ -827,7 +833,7 @@ packet_set_tcp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst) void packet_set_udp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst) { - struct udp_header *uh = ofpbuf_get_l4(packet); + struct udp_header *uh = ofpbuf_l4(packet); if (uh->udp_csum) { packet_set_port(&uh->udp_src, src, &uh->udp_csum); @@ -848,19 +854,19 @@ packet_set_udp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst) void packet_set_sctp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst) { - struct sctp_header *sh = ofpbuf_get_l4(packet); + struct sctp_header *sh = ofpbuf_l4(packet); ovs_be32 old_csum, old_correct_csum, new_csum; - uint16_t tp_len = packet->size - ((uint8_t*)sh - (uint8_t*)packet->data); + uint16_t tp_len = ofpbuf_l4_size(packet); - old_csum = sh->sctp_csum; - sh->sctp_csum = 0; + old_csum = get_16aligned_be32(&sh->sctp_csum); + put_16aligned_be32(&sh->sctp_csum, 0); old_correct_csum = crc32c((void *)sh, tp_len); sh->sctp_src = src; sh->sctp_dst = dst; new_csum = crc32c((void *)sh, tp_len); - sh->sctp_csum = old_csum ^ old_correct_csum ^ new_csum; + put_16aligned_be32(&sh->sctp_csum, old_csum ^ old_correct_csum ^ new_csum); } const char *