~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to lib/flow.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
 
2
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
3
3
 *
4
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
5
 * you may not use this file except in compliance with the License.
94
94
}
95
95
 
96
96
static void
 
97
parse_mpls(struct ofpbuf *b, struct flow *flow)
 
98
{
 
99
    struct mpls_hdr *mh;
 
100
 
 
101
    while ((mh = ofpbuf_try_pull(b, sizeof *mh))) {
 
102
        if (flow->mpls_depth++ == 0) {
 
103
            flow->mpls_lse = mh->mpls_lse;
 
104
        }
 
105
        if (mh->mpls_lse & htonl(MPLS_BOS_MASK)) {
 
106
            break;
 
107
        }
 
108
    }
 
109
}
 
110
 
 
111
static void
97
112
parse_vlan(struct ofpbuf *b, struct flow *flow)
98
113
{
99
114
    struct qtag_prefix {
322
337
}
323
338
 
324
339
/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
325
 
 * 'ofp_in_port'.
 
340
 * 'in_port'.
326
341
 *
327
342
 * Initializes 'packet' header pointers as follows:
328
343
 *
329
344
 *    - packet->l2 to the start of the Ethernet header.
330
345
 *
 
346
 *    - packet->l2_5 to the start of the MPLS shim header.
 
347
 *
331
348
 *    - packet->l3 to just past the Ethernet header, or just past the
332
349
 *      vlan_header if one is present, to the first byte of the payload of the
333
350
 *      Ethernet frame.
340
357
 */
341
358
void
342
359
flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
343
 
             const struct flow_tnl *tnl, uint16_t ofp_in_port,
 
360
             const struct flow_tnl *tnl, const union flow_in_port *in_port,
344
361
             struct flow *flow)
345
362
{
346
363
    struct ofpbuf b = *packet;
354
371
        ovs_assert(tnl != &flow->tunnel);
355
372
        flow->tunnel = *tnl;
356
373
    }
357
 
    flow->in_port = ofp_in_port;
 
374
    if (in_port) {
 
375
        flow->in_port = *in_port;
 
376
    }
358
377
    flow->skb_priority = skb_priority;
359
378
    flow->skb_mark = skb_mark;
360
379
 
361
 
    packet->l2 = b.data;
362
 
    packet->l3 = NULL;
363
 
    packet->l4 = NULL;
364
 
    packet->l7 = NULL;
 
380
    packet->l2   = b.data;
 
381
    packet->l2_5 = NULL;
 
382
    packet->l3   = NULL;
 
383
    packet->l4   = NULL;
 
384
    packet->l7   = NULL;
365
385
 
366
386
    if (b.size < sizeof *eth) {
367
387
        return;
379
399
    }
380
400
    flow->dl_type = parse_ethertype(&b);
381
401
 
 
402
    /* Parse mpls, copy l3 ttl. */
 
403
    if (eth_type_mpls(flow->dl_type)) {
 
404
        packet->l2_5 = b.data;
 
405
        parse_mpls(&b, flow);
 
406
    }
 
407
 
 
408
    /* Network layer. */
382
409
    packet->l3 = b.data;
383
 
    flow_extract_l3_onwards(packet, flow, flow->dl_type);
384
 
}
385
 
 
386
 
/* Initializes l3 and higher 'flow' members from 'packet'
387
 
 *
388
 
 * This should be called by or after flow_extract()
389
 
 *
390
 
 * Initializes 'packet' header pointers as follows:
391
 
 *
392
 
 *    - packet->l4 to just past the IPv4 header, if one is present and has a
393
 
 *      correct length, and otherwise NULL.
394
 
 *
395
 
 *    - packet->l7 to just past the TCP or UDP or ICMP header, if one is
396
 
 *      present and has a correct length, and otherwise NULL.
397
 
 */
398
 
void
399
 
flow_extract_l3_onwards(struct ofpbuf *packet, struct flow *flow,
400
 
                        ovs_be16 dl_type)
401
 
{
402
 
    struct ofpbuf b;
403
 
 
404
 
    ofpbuf_use_const(&b, packet->l3, packet->size -
405
 
                     (size_t)((char *)packet->l3 - (char *)packet->l2));
406
 
 
407
 
    /* Network layer. */
408
 
    if (dl_type == htons(ETH_TYPE_IP)) {
 
410
    if (flow->dl_type == htons(ETH_TYPE_IP)) {
409
411
        const struct ip_header *nh = pull_ip(&b);
410
412
        if (nh) {
411
413
            packet->l4 = b.data;
438
440
                }
439
441
            }
440
442
        }
441
 
    } else if (dl_type == htons(ETH_TYPE_IPV6)) {
 
443
    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
442
444
        if (parse_ipv6(&b, flow)) {
443
445
            return;
444
446
        }
453
455
                packet->l7 = b.data;
454
456
            }
455
457
        }
456
 
    } else if (dl_type == htons(ETH_TYPE_ARP) ||
457
 
               dl_type == htons(ETH_TYPE_RARP)) {
 
458
    } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
 
459
               flow->dl_type == htons(ETH_TYPE_RARP)) {
458
460
        const struct arp_eth_header *arp = pull_arp(&b);
459
461
        if (arp && arp->ar_hrd == htons(1)
460
462
            && arp->ar_pro == htons(ETH_TYPE_IP)
491
493
void
492
494
flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
493
495
{
494
 
    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 18);
 
496
    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20);
495
497
 
496
498
    fmd->tun_id = flow->tunnel.tun_id;
 
499
    fmd->tun_src = flow->tunnel.ip_src;
 
500
    fmd->tun_dst = flow->tunnel.ip_dst;
497
501
    fmd->metadata = flow->metadata;
498
502
    memcpy(fmd->regs, flow->regs, sizeof fmd->regs);
499
 
    fmd->in_port = flow->in_port;
 
503
    fmd->in_port = flow->in_port.ofp_port;
500
504
}
501
505
 
502
506
char *
602
606
    return true;
603
607
}
604
608
 
605
 
/* Initializes 'dst' as the combination of wildcards in 'src1' and 'src2'.
606
 
 * That is, a bit or a field is wildcarded in 'dst' if it is wildcarded in
607
 
 * 'src1' or 'src2' or both.  */
 
609
/* Sets 'dst' as the bitwise AND of wildcards in 'src1' and 'src2'.
 
610
 * That is, a bit or a field is wildcarded in 'dst' if it is wildcarded
 
611
 * in 'src1' or 'src2' or both.  */
608
612
void
609
 
flow_wildcards_combine(struct flow_wildcards *dst,
610
 
                       const struct flow_wildcards *src1,
611
 
                       const struct flow_wildcards *src2)
 
613
flow_wildcards_and(struct flow_wildcards *dst,
 
614
                   const struct flow_wildcards *src1,
 
615
                   const struct flow_wildcards *src2)
612
616
{
613
617
    uint32_t *dst_u32 = (uint32_t *) &dst->masks;
614
618
    const uint32_t *src1_u32 = (const uint32_t *) &src1->masks;
620
624
    }
621
625
}
622
626
 
 
627
/* Sets 'dst' as the bitwise OR of wildcards in 'src1' and 'src2'.  That
 
628
 * is, a bit or a field is wildcarded in 'dst' if it is neither
 
629
 * wildcarded in 'src1' nor 'src2'. */
 
630
void
 
631
flow_wildcards_or(struct flow_wildcards *dst,
 
632
                  const struct flow_wildcards *src1,
 
633
                  const struct flow_wildcards *src2)
 
634
{
 
635
    uint32_t *dst_u32 = (uint32_t *) &dst->masks;
 
636
    const uint32_t *src1_u32 = (const uint32_t *) &src1->masks;
 
637
    const uint32_t *src2_u32 = (const uint32_t *) &src2->masks;
 
638
    size_t i;
 
639
 
 
640
    for (i = 0; i < FLOW_U32S; i++) {
 
641
        dst_u32[i] = src1_u32[i] | src2_u32[i];
 
642
    }
 
643
}
 
644
 
 
645
/* Perform a bitwise OR of miniflow 'src' flow data with the equivalent
 
646
 * fields in 'dst', storing the result in 'dst'. */
 
647
static void
 
648
flow_union_with_miniflow(struct flow *dst, const struct miniflow *src)
 
649
{
 
650
    uint32_t *dst_u32 = (uint32_t *) dst;
 
651
    int ofs;
 
652
    int i;
 
653
 
 
654
    ofs = 0;
 
655
    for (i = 0; i < MINI_N_MAPS; i++) {
 
656
        uint32_t map;
 
657
 
 
658
        for (map = src->map[i]; map; map = zero_rightmost_1bit(map)) {
 
659
            dst_u32[raw_ctz(map) + i * 32] |= src->values[ofs++];
 
660
        }
 
661
    }
 
662
}
 
663
 
 
664
/* Fold minimask 'mask''s wildcard mask into 'wc's wildcard mask. */
 
665
void
 
666
flow_wildcards_fold_minimask(struct flow_wildcards *wc,
 
667
                             const struct minimask *mask)
 
668
{
 
669
    flow_union_with_miniflow(&wc->masks, &mask->masks);
 
670
}
 
671
 
623
672
/* Returns a hash of the wildcards in 'wc'. */
624
673
uint32_t
625
674
flow_wildcards_hash(const struct flow_wildcards *wc, uint32_t basis)
730
779
    return jhash_bytes(&fields, sizeof fields, basis);
731
780
}
732
781
 
 
782
/* Masks the fields in 'wc' that are used by the flow hash 'fields'. */
 
783
void
 
784
flow_mask_hash_fields(const struct flow *flow, struct flow_wildcards *wc,
 
785
                      enum nx_hash_fields fields)
 
786
{
 
787
    switch (fields) {
 
788
    case NX_HASH_FIELDS_ETH_SRC:
 
789
        memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
 
790
        break;
 
791
 
 
792
    case NX_HASH_FIELDS_SYMMETRIC_L4:
 
793
        memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
 
794
        memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
 
795
        if (flow->dl_type == htons(ETH_TYPE_IP)) {
 
796
            memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
 
797
            memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
 
798
        } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
 
799
            memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
 
800
            memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
 
801
        }
 
802
        if (is_ip_any(flow)) {
 
803
            memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
 
804
            memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
 
805
            memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
 
806
        }
 
807
        wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
 
808
        break;
 
809
 
 
810
    default:
 
811
        NOT_REACHED();
 
812
    }
 
813
}
 
814
 
733
815
/* Hashes the portions of 'flow' designated by 'fields'. */
734
816
uint32_t
735
817
flow_hash_fields(const struct flow *flow, enum nx_hash_fields fields,
766
848
        || fields == NX_HASH_FIELDS_SYMMETRIC_L4;
767
849
}
768
850
 
 
851
/* Returns a hash value for the bits of 'flow' that are active based on
 
852
 * 'wc', given 'basis'. */
 
853
uint32_t
 
854
flow_hash_in_wildcards(const struct flow *flow,
 
855
                       const struct flow_wildcards *wc, uint32_t basis)
 
856
{
 
857
    const uint32_t *wc_u32 = (const uint32_t *) &wc->masks;
 
858
    const uint32_t *flow_u32 = (const uint32_t *) flow;
 
859
    uint32_t hash;
 
860
    size_t i;
 
861
 
 
862
    hash = basis;
 
863
    for (i = 0; i < FLOW_U32S; i++) {
 
864
        hash = mhash_add(hash, flow_u32[i] & wc_u32[i]);
 
865
    }
 
866
    return mhash_finish(hash, 4 * FLOW_U32S);
 
867
}
 
868
 
769
869
/* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
770
870
 * OpenFlow 1.0 "dl_vlan" value:
771
871
 *
815
915
    flow->vlan_tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI);
816
916
}
817
917
 
 
918
/* Sets the MPLS Label that 'flow' matches to 'label', which is interpreted
 
919
 * as an OpenFlow 1.1 "mpls_label" value. */
 
920
void
 
921
flow_set_mpls_label(struct flow *flow, ovs_be32 label)
 
922
{
 
923
    set_mpls_lse_label(&flow->mpls_lse, label);
 
924
}
 
925
 
 
926
/* Sets the MPLS TTL that 'flow' matches to 'ttl', which should be in the
 
927
 * range 0...255. */
 
928
void
 
929
flow_set_mpls_ttl(struct flow *flow, uint8_t ttl)
 
930
{
 
931
    set_mpls_lse_ttl(&flow->mpls_lse, ttl);
 
932
}
 
933
 
 
934
/* Sets the MPLS TC that 'flow' matches to 'tc', which should be in the
 
935
 * range 0...7. */
 
936
void
 
937
flow_set_mpls_tc(struct flow *flow, uint8_t tc)
 
938
{
 
939
    set_mpls_lse_tc(&flow->mpls_lse, tc);
 
940
}
 
941
 
 
942
/* Sets the MPLS BOS bit that 'flow' matches to which should be 0 or 1. */
 
943
void
 
944
flow_set_mpls_bos(struct flow *flow, uint8_t bos)
 
945
{
 
946
    set_mpls_lse_bos(&flow->mpls_lse, bos);
 
947
}
 
948
 
818
949
/* Puts into 'b' a packet that flow_extract() would parse as having the given
819
950
 * 'flow'.
820
951
 *
902
1033
            memcpy(arp->ar_tha, flow->arp_tha, ETH_ADDR_LEN);
903
1034
        }
904
1035
    }
 
1036
 
 
1037
    if (eth_type_mpls(flow->dl_type)) {
 
1038
        b->l2_5 = b->l3;
 
1039
        push_mpls(b, flow->dl_type, flow->mpls_lse);
 
1040
    }
905
1041
}
906
1042
 
907
1043
/* Compressed flow. */
986
1122
void
987
1123
miniflow_expand(const struct miniflow *src, struct flow *dst)
988
1124
{
989
 
    uint32_t *dst_u32 = (uint32_t *) dst;
990
 
    int ofs;
991
 
    int i;
992
 
 
993
 
    memset(dst_u32, 0, sizeof *dst);
994
 
 
995
 
    ofs = 0;
996
 
    for (i = 0; i < MINI_N_MAPS; i++) {
997
 
        uint32_t map;
998
 
 
999
 
        for (map = src->map[i]; map; map = zero_rightmost_1bit(map)) {
1000
 
            dst_u32[raw_ctz(map) + i * 32] = src->values[ofs++];
1001
 
        }
1002
 
    }
 
1125
    memset(dst, 0, sizeof *dst);
 
1126
    flow_union_with_miniflow(dst, src);
1003
1127
}
1004
1128
 
1005
1129
static const uint32_t *