~ubuntu-branches/ubuntu/wily/openvswitch/wily

« back to all changes in this revision

Viewing changes to lib/packets.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-10 11:35:15 UTC
  • mfrom: (1.1.30)
  • Revision ID: package-import@ubuntu.com-20150810113515-575vj06oq29emxsn
Tags: 2.4.0~git20150810.97bab95-0ubuntu1
* New upstream snapshot from 2.4 branch:
  - d/*: Align any relevant packaging changes with upstream.
* d/*: wrap-and-sort.
* d/openvswitch-{common,vswitch}.install: Correct install location for
  bash completion files.
* d/tests/openflow.py: Explicitly use ovs-testcontroller as provided
  by 2.4.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "flow.h"
29
29
#include "hmap.h"
30
30
#include "dynamic-string.h"
31
 
#include "ofpbuf.h"
32
31
#include "ovs-thread.h"
33
32
#include "odp-util.h"
 
33
#include "dp-packet.h"
34
34
#include "unaligned.h"
35
35
 
36
36
const struct in6_addr in6addr_exact = IN6ADDR_EXACT_INIT;
145
145
 * The returned packet has enough headroom to insert an 802.1Q VLAN header if
146
146
 * desired. */
147
147
void
148
 
compose_rarp(struct ofpbuf *b, const uint8_t eth_src[ETH_ADDR_LEN])
 
148
compose_rarp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN])
149
149
{
150
150
    struct eth_header *eth;
151
151
    struct arp_eth_header *arp;
152
152
 
153
 
    ofpbuf_clear(b);
154
 
    ofpbuf_prealloc_tailroom(b, 2 + ETH_HEADER_LEN + VLAN_HEADER_LEN
 
153
    dp_packet_clear(b);
 
154
    dp_packet_prealloc_tailroom(b, 2 + ETH_HEADER_LEN + VLAN_HEADER_LEN
155
155
                             + ARP_ETH_HEADER_LEN);
156
 
    ofpbuf_reserve(b, 2 + VLAN_HEADER_LEN);
157
 
    eth = ofpbuf_put_uninit(b, sizeof *eth);
 
156
    dp_packet_reserve(b, 2 + VLAN_HEADER_LEN);
 
157
    eth = dp_packet_put_uninit(b, sizeof *eth);
158
158
    memcpy(eth->eth_dst, eth_addr_broadcast, ETH_ADDR_LEN);
159
159
    memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN);
160
160
    eth->eth_type = htons(ETH_TYPE_RARP);
161
161
 
162
 
    arp = ofpbuf_put_uninit(b, sizeof *arp);
 
162
    arp = dp_packet_put_uninit(b, sizeof *arp);
163
163
    arp->ar_hrd = htons(ARP_HRD_ETHERNET);
164
164
    arp->ar_pro = htons(ARP_PRO_IP);
165
165
    arp->ar_hln = sizeof arp->ar_sha;
170
170
    memcpy(arp->ar_tha, eth_src, ETH_ADDR_LEN);
171
171
    put_16aligned_be32(&arp->ar_tpa, htonl(0));
172
172
 
173
 
    ofpbuf_set_frame(b, eth);
174
 
    ofpbuf_set_l3(b, arp);
 
173
    dp_packet_reset_offsets(b);
 
174
    dp_packet_set_l3(b, arp);
175
175
}
176
176
 
177
177
/* Insert VLAN header according to given TCI. Packet passed must be Ethernet
179
179
 *
180
180
 * Also adjusts the layer offsets accordingly. */
181
181
void
182
 
eth_push_vlan(struct ofpbuf *packet, ovs_be16 tpid, ovs_be16 tci)
 
182
eth_push_vlan(struct dp_packet *packet, ovs_be16 tpid, ovs_be16 tci)
183
183
{
184
184
    struct vlan_eth_header *veh;
185
185
 
186
186
    /* Insert new 802.1Q header. */
187
 
    veh = ofpbuf_resize_l2(packet, VLAN_HEADER_LEN);
 
187
    veh = dp_packet_resize_l2(packet, VLAN_HEADER_LEN);
188
188
    memmove(veh, (char *)veh + VLAN_HEADER_LEN, 2 * ETH_ADDR_LEN);
189
189
    veh->veth_type = tpid;
190
190
    veh->veth_tci = tci & htons(~VLAN_CFI);
192
192
 
193
193
/* Removes outermost VLAN header (if any is present) from 'packet'.
194
194
 *
195
 
 * 'packet->l2_5' should initially point to 'packet''s outer-most MPLS header
196
 
 * or may be NULL if there are no MPLS headers. */
 
195
 * 'packet->l2_5' should initially point to 'packet''s outer-most VLAN header
 
196
 * or may be NULL if there are no VLAN headers. */
197
197
void
198
 
eth_pop_vlan(struct ofpbuf *packet)
 
198
eth_pop_vlan(struct dp_packet *packet)
199
199
{
200
 
    struct vlan_eth_header *veh = ofpbuf_l2(packet);
 
200
    struct vlan_eth_header *veh = dp_packet_l2(packet);
201
201
 
202
 
    if (veh && ofpbuf_size(packet) >= sizeof *veh
203
 
        && veh->veth_type == htons(ETH_TYPE_VLAN)) {
 
202
    if (veh && dp_packet_size(packet) >= sizeof *veh
 
203
        && eth_type_vlan(veh->veth_type)) {
204
204
 
205
205
        memmove((char *)veh + VLAN_HEADER_LEN, veh, 2 * ETH_ADDR_LEN);
206
 
        ofpbuf_resize_l2(packet, -VLAN_HEADER_LEN);
 
206
        dp_packet_resize_l2(packet, -VLAN_HEADER_LEN);
207
207
    }
208
208
}
209
209
 
210
210
/* Set ethertype of the packet. */
211
211
static void
212
 
set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type)
 
212
set_ethertype(struct dp_packet *packet, ovs_be16 eth_type)
213
213
{
214
 
    struct eth_header *eh = ofpbuf_l2(packet);
 
214
    struct eth_header *eh = dp_packet_l2(packet);
215
215
 
216
216
    if (!eh) {
217
217
        return;
218
218
    }
219
219
 
220
 
    if (eh->eth_type == htons(ETH_TYPE_VLAN)) {
 
220
    if (eth_type_vlan(eh->eth_type)) {
221
221
        ovs_be16 *p;
222
 
        char *l2_5 = ofpbuf_l2_5(packet);
 
222
        char *l2_5 = dp_packet_l2_5(packet);
223
223
 
224
224
        p = ALIGNED_CAST(ovs_be16 *,
225
 
                         (l2_5 ? l2_5 : (char *)ofpbuf_l3(packet)) - 2);
 
225
                         (l2_5 ? l2_5 : (char *)dp_packet_l3(packet)) - 2);
226
226
        *p = eth_type;
227
227
    } else {
228
228
        eh->eth_type = eth_type;
229
229
    }
230
230
}
231
231
 
232
 
static bool is_mpls(struct ofpbuf *packet)
 
232
static bool is_mpls(struct dp_packet *packet)
233
233
{
234
234
    return packet->l2_5_ofs != UINT16_MAX;
235
235
}
282
282
 
283
283
/* Set MPLS label stack entry to outermost MPLS header.*/
284
284
void
285
 
set_mpls_lse(struct ofpbuf *packet, ovs_be32 mpls_lse)
 
285
set_mpls_lse(struct dp_packet *packet, ovs_be32 mpls_lse)
286
286
{
287
287
    /* Packet type should be MPLS to set label stack entry. */
288
288
    if (is_mpls(packet)) {
289
 
        struct mpls_hdr *mh = ofpbuf_l2_5(packet);
 
289
        struct mpls_hdr *mh = dp_packet_l2_5(packet);
290
290
 
291
291
        /* Update mpls label stack entry. */
292
292
        put_16aligned_be32(&mh->mpls_lse, mpls_lse);
297
297
 * header.  If 'packet' does not already have any MPLS labels, then its
298
298
 * Ethertype is changed to 'ethtype' (which must be an MPLS Ethertype). */
299
299
void
300
 
push_mpls(struct ofpbuf *packet, ovs_be16 ethtype, ovs_be32 lse)
 
300
push_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse)
301
301
{
302
302
    char * header;
303
303
    size_t len;
315
315
 
316
316
    /* Push new MPLS shim header onto packet. */
317
317
    len = packet->l2_5_ofs;
318
 
    header = ofpbuf_resize_l2_5(packet, MPLS_HLEN);
 
318
    header = dp_packet_resize_l2_5(packet, MPLS_HLEN);
319
319
    memmove(header, header + MPLS_HLEN, len);
320
320
    memcpy(header + len, &lse, sizeof lse);
321
321
}
325
325
 * Ethertype to 'ethtype' (which ordinarily should not be an MPLS
326
326
 * Ethertype). */
327
327
void
328
 
pop_mpls(struct ofpbuf *packet, ovs_be16 ethtype)
 
328
pop_mpls(struct dp_packet *packet, ovs_be16 ethtype)
329
329
{
330
330
    if (is_mpls(packet)) {
331
 
        struct mpls_hdr *mh = ofpbuf_l2_5(packet);
 
331
        struct mpls_hdr *mh = dp_packet_l2_5(packet);
332
332
        size_t len = packet->l2_5_ofs;
333
333
 
334
334
        set_ethertype(packet, ethtype);
335
335
        if (get_16aligned_be32(&mh->mpls_lse) & htonl(MPLS_BOS_MASK)) {
336
 
            ofpbuf_set_l2_5(packet, NULL);
 
336
            dp_packet_set_l2_5(packet, NULL);
337
337
        }
338
338
        /* Shift the l2 header forward. */
339
 
        memmove((char*)ofpbuf_data(packet) + MPLS_HLEN, ofpbuf_data(packet), len);
340
 
        ofpbuf_resize_l2_5(packet, -MPLS_HLEN);
 
339
        memmove((char*)dp_packet_data(packet) + MPLS_HLEN, dp_packet_data(packet), len);
 
340
        dp_packet_resize_l2_5(packet, -MPLS_HLEN);
341
341
    }
342
342
}
343
343
 
347
347
 *
348
348
 * Aligns the L3 header of '*packetp' on a 32-bit boundary. */
349
349
const char *
350
 
eth_from_hex(const char *hex, struct ofpbuf **packetp)
 
350
eth_from_hex(const char *hex, struct dp_packet **packetp)
351
351
{
352
 
    struct ofpbuf *packet;
 
352
    struct dp_packet *packet;
353
353
 
354
354
    /* Use 2 bytes of headroom to 32-bit align the L3 header. */
355
 
    packet = *packetp = ofpbuf_new_with_headroom(strlen(hex) / 2, 2);
 
355
    packet = *packetp = dp_packet_new_with_headroom(strlen(hex) / 2, 2);
356
356
 
357
 
    if (ofpbuf_put_hex(packet, hex, NULL)[0] != '\0') {
358
 
        ofpbuf_delete(packet);
 
357
    if (dp_packet_put_hex(packet, hex, NULL)[0] != '\0') {
 
358
        dp_packet_delete(packet);
359
359
        *packetp = NULL;
360
360
        return "Trailing garbage in packet data";
361
361
    }
362
362
 
363
 
    if (ofpbuf_size(packet) < ETH_HEADER_LEN) {
364
 
        ofpbuf_delete(packet);
 
363
    if (dp_packet_size(packet) < ETH_HEADER_LEN) {
 
364
        dp_packet_delete(packet);
365
365
        *packetp = NULL;
366
366
        return "Packet data too short for Ethernet";
367
367
    }
559
559
 * The returned packet has enough headroom to insert an 802.1Q VLAN header if
560
560
 * desired. */
561
561
void *
562
 
eth_compose(struct ofpbuf *b, const uint8_t eth_dst[ETH_ADDR_LEN],
 
562
eth_compose(struct dp_packet *b, const uint8_t eth_dst[ETH_ADDR_LEN],
563
563
            const uint8_t eth_src[ETH_ADDR_LEN], uint16_t eth_type,
564
564
            size_t size)
565
565
{
566
566
    void *data;
567
567
    struct eth_header *eth;
568
568
 
569
 
    ofpbuf_clear(b);
 
569
    dp_packet_clear(b);
570
570
 
571
571
    /* The magic 2 here ensures that the L3 header (when it is added later)
572
572
     * will be 32-bit aligned. */
573
 
    ofpbuf_prealloc_tailroom(b, 2 + ETH_HEADER_LEN + VLAN_HEADER_LEN + size);
574
 
    ofpbuf_reserve(b, 2 + VLAN_HEADER_LEN);
575
 
    eth = ofpbuf_put_uninit(b, ETH_HEADER_LEN);
576
 
    data = ofpbuf_put_uninit(b, size);
 
573
    dp_packet_prealloc_tailroom(b, 2 + ETH_HEADER_LEN + VLAN_HEADER_LEN + size);
 
574
    dp_packet_reserve(b, 2 + VLAN_HEADER_LEN);
 
575
    eth = dp_packet_put_uninit(b, ETH_HEADER_LEN);
 
576
    data = dp_packet_put_uninit(b, size);
577
577
 
578
578
    memcpy(eth->eth_dst, eth_dst, ETH_ADDR_LEN);
579
579
    memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN);
580
580
    eth->eth_type = htons(eth_type);
581
581
 
582
 
    ofpbuf_set_frame(b, eth);
583
 
    ofpbuf_set_l3(b, data);
 
582
    dp_packet_reset_offsets(b);
 
583
    dp_packet_set_l3(b, data);
584
584
 
585
585
    return data;
586
586
}
587
587
 
588
588
static void
589
 
packet_set_ipv4_addr(struct ofpbuf *packet,
 
589
packet_set_ipv4_addr(struct dp_packet *packet,
590
590
                     ovs_16aligned_be32 *addr, ovs_be32 new_addr)
591
591
{
592
 
    struct ip_header *nh = ofpbuf_l3(packet);
 
592
    struct ip_header *nh = dp_packet_l3(packet);
593
593
    ovs_be32 old_addr = get_16aligned_be32(addr);
594
 
    size_t l4_size = ofpbuf_l4_size(packet);
 
594
    size_t l4_size = dp_packet_l4_size(packet);
595
595
 
596
596
    if (nh->ip_proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {
597
 
        struct tcp_header *th = ofpbuf_l4(packet);
 
597
        struct tcp_header *th = dp_packet_l4(packet);
598
598
 
599
599
        th->tcp_csum = recalc_csum32(th->tcp_csum, old_addr, new_addr);
600
600
    } else if (nh->ip_proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN ) {
601
 
        struct udp_header *uh = ofpbuf_l4(packet);
 
601
        struct udp_header *uh = dp_packet_l4(packet);
602
602
 
603
603
        if (uh->udp_csum) {
604
604
            uh->udp_csum = recalc_csum32(uh->udp_csum, old_addr, new_addr);
616
616
 *
617
617
 * This function assumes that L3 and L4 offsets are set in the packet. */
618
618
static bool
619
 
packet_rh_present(struct ofpbuf *packet)
 
619
packet_rh_present(struct dp_packet *packet)
620
620
{
621
621
    const struct ovs_16aligned_ip6_hdr *nh;
622
622
    int nexthdr;
623
623
    size_t len;
624
624
    size_t remaining;
625
 
    uint8_t *data = ofpbuf_l3(packet);
 
625
    uint8_t *data = dp_packet_l3(packet);
626
626
 
627
627
    remaining = packet->l4_ofs - packet->l3_ofs;
628
628
 
697
697
}
698
698
 
699
699
static void
700
 
packet_update_csum128(struct ofpbuf *packet, uint8_t proto,
 
700
packet_update_csum128(struct dp_packet *packet, uint8_t proto,
701
701
                     ovs_16aligned_be32 addr[4], const ovs_be32 new_addr[4])
702
702
{
703
 
    size_t l4_size = ofpbuf_l4_size(packet);
 
703
    size_t l4_size = dp_packet_l4_size(packet);
704
704
 
705
705
    if (proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {
706
 
        struct tcp_header *th = ofpbuf_l4(packet);
 
706
        struct tcp_header *th = dp_packet_l4(packet);
707
707
 
708
708
        th->tcp_csum = recalc_csum128(th->tcp_csum, addr, new_addr);
709
709
    } else if (proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN) {
710
 
        struct udp_header *uh = ofpbuf_l4(packet);
 
710
        struct udp_header *uh = dp_packet_l4(packet);
711
711
 
712
712
        if (uh->udp_csum) {
713
713
            uh->udp_csum = recalc_csum128(uh->udp_csum, addr, new_addr);
717
717
        }
718
718
    } else if (proto == IPPROTO_ICMPV6 &&
719
719
               l4_size >= sizeof(struct icmp6_header)) {
720
 
        struct icmp6_header *icmp = ofpbuf_l4(packet);
 
720
        struct icmp6_header *icmp = dp_packet_l4(packet);
721
721
 
722
722
        icmp->icmp6_cksum = recalc_csum128(icmp->icmp6_cksum, addr, new_addr);
723
723
    }
724
724
}
725
725
 
726
726
static void
727
 
packet_set_ipv6_addr(struct ofpbuf *packet, uint8_t proto,
 
727
packet_set_ipv6_addr(struct dp_packet *packet, uint8_t proto,
728
728
                     ovs_16aligned_be32 addr[4], const ovs_be32 new_addr[4],
729
729
                     bool recalculate_csum)
730
730
{
755
755
 * 'packet' must contain a valid IPv4 packet with correctly populated l[347]
756
756
 * markers. */
757
757
void
758
 
packet_set_ipv4(struct ofpbuf *packet, ovs_be32 src, ovs_be32 dst,
 
758
packet_set_ipv4(struct dp_packet *packet, ovs_be32 src, ovs_be32 dst,
759
759
                uint8_t tos, uint8_t ttl)
760
760
{
761
 
    struct ip_header *nh = ofpbuf_l3(packet);
 
761
    struct ip_header *nh = dp_packet_l3(packet);
762
762
 
763
763
    if (get_16aligned_be32(&nh->ip_src) != src) {
764
764
        packet_set_ipv4_addr(packet, &nh->ip_src, src);
790
790
 * appropriate. 'packet' must contain a valid IPv6 packet with correctly
791
791
 * populated l[34] offsets. */
792
792
void
793
 
packet_set_ipv6(struct ofpbuf *packet, uint8_t proto, const ovs_be32 src[4],
 
793
packet_set_ipv6(struct dp_packet *packet, uint8_t proto, const ovs_be32 src[4],
794
794
                const ovs_be32 dst[4], uint8_t key_tc, ovs_be32 key_fl,
795
795
                uint8_t key_hl)
796
796
{
797
 
    struct ovs_16aligned_ip6_hdr *nh = ofpbuf_l3(packet);
 
797
    struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);
798
798
 
799
799
    if (memcmp(&nh->ip6_src, src, sizeof(ovs_be32[4]))) {
800
800
        packet_set_ipv6_addr(packet, proto, nh->ip6_src.be32, src, true);
825
825
 * the TCP header contained in 'packet'.  'packet' must be a valid TCP packet
826
826
 * with its l4 offset properly populated. */
827
827
void
828
 
packet_set_tcp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
 
828
packet_set_tcp_port(struct dp_packet *packet, ovs_be16 src, ovs_be16 dst)
829
829
{
830
 
    struct tcp_header *th = ofpbuf_l4(packet);
 
830
    struct tcp_header *th = dp_packet_l4(packet);
831
831
 
832
832
    packet_set_port(&th->tcp_src, src, &th->tcp_csum);
833
833
    packet_set_port(&th->tcp_dst, dst, &th->tcp_csum);
837
837
 * the UDP header contained in 'packet'.  'packet' must be a valid UDP packet
838
838
 * with its l4 offset properly populated. */
839
839
void
840
 
packet_set_udp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
 
840
packet_set_udp_port(struct dp_packet *packet, ovs_be16 src, ovs_be16 dst)
841
841
{
842
 
    struct udp_header *uh = ofpbuf_l4(packet);
 
842
    struct udp_header *uh = dp_packet_l4(packet);
843
843
 
844
844
    if (uh->udp_csum) {
845
845
        packet_set_port(&uh->udp_src, src, &uh->udp_csum);
858
858
 * the SCTP header contained in 'packet'.  'packet' must be a valid SCTP packet
859
859
 * with its l4 offset properly populated. */
860
860
void
861
 
packet_set_sctp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
 
861
packet_set_sctp_port(struct dp_packet *packet, ovs_be16 src, ovs_be16 dst)
862
862
{
863
 
    struct sctp_header *sh = ofpbuf_l4(packet);
 
863
    struct sctp_header *sh = dp_packet_l4(packet);
864
864
    ovs_be32 old_csum, old_correct_csum, new_csum;
865
 
    uint16_t tp_len = ofpbuf_l4_size(packet);
 
865
    uint16_t tp_len = dp_packet_l4_size(packet);
866
866
 
867
867
    old_csum = get_16aligned_be32(&sh->sctp_csum);
868
868
    put_16aligned_be32(&sh->sctp_csum, 0);
875
875
    put_16aligned_be32(&sh->sctp_csum, old_csum ^ old_correct_csum ^ new_csum);
876
876
}
877
877
 
 
878
void
 
879
packet_set_nd(struct dp_packet *packet, const ovs_be32 target[4],
 
880
              const uint8_t sll[ETH_ADDR_LEN],
 
881
              const uint8_t tll[ETH_ADDR_LEN]) {
 
882
    struct ovs_nd_msg *ns;
 
883
    struct ovs_nd_opt *nd_opt;
 
884
    int bytes_remain = dp_packet_l4_size(packet);
 
885
 
 
886
    if (OVS_UNLIKELY(bytes_remain < sizeof(*ns))) {
 
887
        return;
 
888
    }
 
889
 
 
890
    ns = dp_packet_l4(packet);
 
891
    nd_opt = &ns->options[0];
 
892
    bytes_remain -= sizeof(*ns);
 
893
 
 
894
    if (memcmp(&ns->target, target, sizeof(ovs_be32[4]))) {
 
895
        packet_set_ipv6_addr(packet, IPPROTO_ICMPV6,
 
896
                             ns->target.be32,
 
897
                             target, true);
 
898
    }
 
899
 
 
900
    while (bytes_remain >= ND_OPT_LEN && nd_opt->nd_opt_len != 0) {
 
901
        if (nd_opt->nd_opt_type == ND_OPT_SOURCE_LINKADDR
 
902
            && nd_opt->nd_opt_len == 1) {
 
903
            if (memcmp(nd_opt->nd_opt_data, sll, ETH_ADDR_LEN)) {
 
904
                ovs_be16 *csum = &(ns->icmph.icmp6_cksum);
 
905
 
 
906
                *csum = recalc_csum48(*csum, nd_opt->nd_opt_data, sll);
 
907
                memcpy(nd_opt->nd_opt_data, sll, ETH_ADDR_LEN);
 
908
            }
 
909
 
 
910
            /* A packet can only contain one SLL or TLL option */
 
911
            break;
 
912
        } else if (nd_opt->nd_opt_type == ND_OPT_TARGET_LINKADDR
 
913
                   && nd_opt->nd_opt_len == 1) {
 
914
            if (memcmp(nd_opt->nd_opt_data, tll, ETH_ADDR_LEN)) {
 
915
                ovs_be16 *csum = &(ns->icmph.icmp6_cksum);
 
916
 
 
917
                *csum = recalc_csum48(*csum, nd_opt->nd_opt_data, tll);
 
918
                memcpy(nd_opt->nd_opt_data, tll, ETH_ADDR_LEN);
 
919
            }
 
920
 
 
921
            /* A packet can only contain one SLL or TLL option */
 
922
            break;
 
923
        }
 
924
 
 
925
        nd_opt += nd_opt->nd_opt_len;
 
926
        bytes_remain -= nd_opt->nd_opt_len * ND_OPT_LEN;
 
927
    }
 
928
}
 
929
 
878
930
const char *
879
931
packet_tcp_flag_to_string(uint32_t flag)
880
932
{
956
1008
        ds_put_cstr(s, "[800]");
957
1009
    }
958
1010
}
 
1011
 
 
1012
#define ARP_PACKET_SIZE  (2 + ETH_HEADER_LEN + VLAN_HEADER_LEN + \
 
1013
                          ARP_ETH_HEADER_LEN)
 
1014
 
 
1015
void
 
1016
compose_arp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN],
 
1017
            ovs_be32 ip_src, ovs_be32 ip_dst)
 
1018
{
 
1019
    struct eth_header *eth;
 
1020
    struct arp_eth_header *arp;
 
1021
 
 
1022
    dp_packet_clear(b);
 
1023
    dp_packet_prealloc_tailroom(b, ARP_PACKET_SIZE);
 
1024
    dp_packet_reserve(b, 2 + VLAN_HEADER_LEN);
 
1025
 
 
1026
    eth = dp_packet_put_uninit(b, sizeof *eth);
 
1027
    memcpy(eth->eth_dst, eth_addr_broadcast, ETH_ADDR_LEN);
 
1028
    memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN);
 
1029
    eth->eth_type = htons(ETH_TYPE_ARP);
 
1030
 
 
1031
    arp = dp_packet_put_uninit(b, sizeof *arp);
 
1032
    arp->ar_hrd = htons(ARP_HRD_ETHERNET);
 
1033
    arp->ar_pro = htons(ARP_PRO_IP);
 
1034
    arp->ar_hln = sizeof arp->ar_sha;
 
1035
    arp->ar_pln = sizeof arp->ar_spa;
 
1036
    arp->ar_op = htons(ARP_OP_REQUEST);
 
1037
    memcpy(arp->ar_sha, eth_src, ETH_ADDR_LEN);
 
1038
    memset(arp->ar_tha, 0, ETH_ADDR_LEN);
 
1039
 
 
1040
    put_16aligned_be32(&arp->ar_spa, ip_src);
 
1041
    put_16aligned_be32(&arp->ar_tpa, ip_dst);
 
1042
 
 
1043
    dp_packet_reset_offsets(b);
 
1044
    dp_packet_set_l3(b, arp);
 
1045
}
 
1046
 
 
1047
uint32_t
 
1048
packet_csum_pseudoheader(const struct ip_header *ip)
 
1049
{
 
1050
    uint32_t partial = 0;
 
1051
 
 
1052
    partial = csum_add32(partial, get_16aligned_be32(&ip->ip_src));
 
1053
    partial = csum_add32(partial, get_16aligned_be32(&ip->ip_dst));
 
1054
    partial = csum_add16(partial, htons(ip->ip_proto));
 
1055
    partial = csum_add16(partial, htons(ntohs(ip->ip_tot_len) -
 
1056
                                        IP_IHL(ip->ip_ihl_ver) * 4));
 
1057
 
 
1058
    return partial;
 
1059
}