~ubuntu-branches/ubuntu/raring/openvswitch/raring-proposed

« back to all changes in this revision

Viewing changes to lib/odp-util.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-02-07 15:32:38 UTC
  • mfrom: (1.1.14)
  • Revision ID: package-import@ubuntu.com-20130207153238-4fw3p72zc0ms1g8p
Tags: 1.9.0~git20130207.84b39f2-0ubuntu1
* New upstream snapshot from 1.9 branch:
  - d/p/support-linux-3.8.patch,
    d/p/linux-Makefile.main.in-acinclude-preparation-for-lin.patch:
    Dropped as included upstream.
* Fix dependencies for ovsdbmonitor (LP: #1098324):
  - d/control: Add dependency on python-twisted-conch.
* d/control: Bumped Standards-Version, no changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
95
95
    case OVS_KEY_ATTR_PRIORITY: return "skb_priority";
96
96
    case OVS_KEY_ATTR_SKB_MARK: return "skb_mark";
97
97
    case OVS_KEY_ATTR_TUN_ID: return "tun_id";
98
 
    case OVS_KEY_ATTR_IPV4_TUNNEL: return "ipv4_tunnel";
 
98
    case OVS_KEY_ATTR_TUNNEL: return "tunnel";
99
99
    case OVS_KEY_ATTR_IN_PORT: return "in_port";
100
100
    case OVS_KEY_ATTR_ETHERNET: return "eth";
101
101
    case OVS_KEY_ATTR_VLAN: return "vlan";
617
617
    case OVS_KEY_ATTR_PRIORITY: return 4;
618
618
    case OVS_KEY_ATTR_SKB_MARK: return 4;
619
619
    case OVS_KEY_ATTR_TUN_ID: return 8;
620
 
    case OVS_KEY_ATTR_IPV4_TUNNEL: return sizeof(struct ovs_key_ipv4_tunnel);
 
620
    case OVS_KEY_ATTR_TUNNEL: return -2;
621
621
    case OVS_KEY_ATTR_IN_PORT: return 4;
622
622
    case OVS_KEY_ATTR_ETHERNET: return sizeof(struct ovs_key_ethernet);
623
623
    case OVS_KEY_ATTR_VLAN: return sizeof(ovs_be16);
672
672
    }
673
673
}
674
674
 
675
 
static const char *
676
 
odp_tun_flag_to_string(uint32_t flags)
677
 
{
678
 
    switch (flags) {
679
 
    case OVS_TNL_F_DONT_FRAGMENT:
680
 
        return "df";
681
 
    case OVS_TNL_F_CSUM:
682
 
        return "csum";
683
 
    case OVS_TNL_F_KEY:
684
 
        return "key";
685
 
    default:
686
 
        return NULL;
687
 
    }
 
675
static int
 
676
tunnel_key_attr_len(int type)
 
677
{
 
678
    switch (type) {
 
679
    case OVS_TUNNEL_KEY_ATTR_ID: return 8;
 
680
    case OVS_TUNNEL_KEY_ATTR_IPV4_SRC: return 4;
 
681
    case OVS_TUNNEL_KEY_ATTR_IPV4_DST: return 4;
 
682
    case OVS_TUNNEL_KEY_ATTR_TOS: return 1;
 
683
    case OVS_TUNNEL_KEY_ATTR_TTL: return 1;
 
684
    case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT: return 0;
 
685
    case OVS_TUNNEL_KEY_ATTR_CSUM: return 0;
 
686
    case __OVS_TUNNEL_KEY_ATTR_MAX:
 
687
        return -1;
 
688
    }
 
689
    return -1;
 
690
}
 
691
 
 
692
static enum odp_key_fitness
 
693
tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
 
694
{
 
695
    unsigned int left;
 
696
    const struct nlattr *a;
 
697
    bool ttl = false;
 
698
    bool unknown = false;
 
699
 
 
700
    NL_NESTED_FOR_EACH(a, left, attr) {
 
701
        uint16_t type = nl_attr_type(a);
 
702
        size_t len = nl_attr_get_size(a);
 
703
        int expected_len = tunnel_key_attr_len(type);
 
704
 
 
705
        if (len != expected_len && expected_len >= 0) {
 
706
            return ODP_FIT_ERROR;
 
707
        }
 
708
 
 
709
        switch (type) {
 
710
        case OVS_TUNNEL_KEY_ATTR_ID:
 
711
            tun->tun_id = nl_attr_get_be64(a);
 
712
            tun->flags |= FLOW_TNL_F_KEY;
 
713
            break;
 
714
        case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
 
715
            tun->ip_src = nl_attr_get_be32(a);
 
716
            break;
 
717
        case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
 
718
            tun->ip_dst = nl_attr_get_be32(a);
 
719
            break;
 
720
        case OVS_TUNNEL_KEY_ATTR_TOS:
 
721
            tun->ip_tos = nl_attr_get_u8(a);
 
722
            break;
 
723
        case OVS_TUNNEL_KEY_ATTR_TTL:
 
724
            tun->ip_ttl = nl_attr_get_u8(a);
 
725
            ttl = true;
 
726
            break;
 
727
        case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
 
728
            tun->flags |= FLOW_TNL_F_DONT_FRAGMENT;
 
729
            break;
 
730
        case OVS_TUNNEL_KEY_ATTR_CSUM:
 
731
            tun->flags |= FLOW_TNL_F_CSUM;
 
732
            break;
 
733
        default:
 
734
            /* Allow this to show up as unexpected, if there are unknown
 
735
             * tunnel attribute, eventually resulting in ODP_FIT_TOO_MUCH. */
 
736
            unknown = true;
 
737
            break;
 
738
        }
 
739
    }
 
740
 
 
741
    if (!ttl) {
 
742
        return ODP_FIT_ERROR;
 
743
    }
 
744
    if (unknown) {
 
745
            return ODP_FIT_TOO_MUCH;
 
746
    }
 
747
    return ODP_FIT_PERFECT;
 
748
}
 
749
 
 
750
static void
 
751
tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key)
 
752
{
 
753
    size_t tun_key_ofs;
 
754
 
 
755
    tun_key_ofs = nl_msg_start_nested(a, OVS_KEY_ATTR_TUNNEL);
 
756
 
 
757
    if (tun_key->flags & FLOW_TNL_F_KEY) {
 
758
        nl_msg_put_be64(a, OVS_TUNNEL_KEY_ATTR_ID, tun_key->tun_id);
 
759
    }
 
760
    if (tun_key->ip_src) {
 
761
        nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, tun_key->ip_src);
 
762
    }
 
763
    if (tun_key->ip_dst) {
 
764
        nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_DST, tun_key->ip_dst);
 
765
    }
 
766
    if (tun_key->ip_tos) {
 
767
        nl_msg_put_u8(a, OVS_TUNNEL_KEY_ATTR_TOS, tun_key->ip_tos);
 
768
    }
 
769
    nl_msg_put_u8(a, OVS_TUNNEL_KEY_ATTR_TTL, tun_key->ip_ttl);
 
770
    if (tun_key->flags & FLOW_TNL_F_DONT_FRAGMENT) {
 
771
        nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT);
 
772
    }
 
773
    if (tun_key->flags & FLOW_TNL_F_CSUM) {
 
774
        nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_CSUM);
 
775
    }
 
776
 
 
777
    nl_msg_end_nested(a, tun_key_ofs);
688
778
}
689
779
 
690
780
static void
699
789
    const struct ovs_key_icmpv6 *icmpv6_key;
700
790
    const struct ovs_key_arp *arp_key;
701
791
    const struct ovs_key_nd *nd_key;
702
 
    const struct ovs_key_ipv4_tunnel *ipv4_tun_key;
 
792
    struct flow_tnl tun_key;
703
793
    enum ovs_key_attr attr = nl_attr_type(a);
704
794
    int expected_len;
705
795
 
734
824
        ds_put_format(ds, "(%#"PRIx64")", ntohll(nl_attr_get_be64(a)));
735
825
        break;
736
826
 
737
 
    case OVS_KEY_ATTR_IPV4_TUNNEL:
738
 
        ipv4_tun_key = nl_attr_get(a);
739
 
        ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
740
 
                      "tos=0x%"PRIx8",ttl=%"PRIu8",flags(",
741
 
                      ntohll(ipv4_tun_key->tun_id),
742
 
                      IP_ARGS(&ipv4_tun_key->ipv4_src),
743
 
                      IP_ARGS(&ipv4_tun_key->ipv4_dst),
744
 
                      ipv4_tun_key->ipv4_tos, ipv4_tun_key->ipv4_ttl);
745
 
 
746
 
        format_flags(ds, odp_tun_flag_to_string,
747
 
                     ipv4_tun_key->tun_flags, ',');
748
 
        ds_put_format(ds, "))");
 
827
    case OVS_KEY_ATTR_TUNNEL:
 
828
        memset(&tun_key, 0, sizeof tun_key);
 
829
        if (tun_key_from_attr(a, &tun_key) == ODP_FIT_ERROR) {
 
830
            ds_put_format(ds, "(error)");
 
831
        } else {
 
832
            ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
 
833
                          "tos=0x%"PRIx8",ttl=%"PRIu8",flags(",
 
834
                          ntohll(tun_key.tun_id),
 
835
                          IP_ARGS(&tun_key.ip_src),
 
836
                          IP_ARGS(&tun_key.ip_dst),
 
837
                          tun_key.ip_tos, tun_key.ip_ttl);
 
838
 
 
839
            format_flags(ds, flow_tun_flag_to_string,
 
840
                         (uint32_t) tun_key.flags, ',');
 
841
            ds_put_format(ds, "))");
 
842
        }
 
843
 
749
844
        break;
750
845
 
751
846
    case OVS_KEY_ATTR_IN_PORT:
974
1069
    {
975
1070
        char tun_id_s[32];
976
1071
        int tos, ttl;
977
 
        struct ovs_key_ipv4_tunnel tun_key;
 
1072
        struct flow_tnl tun_key;
978
1073
        int n = -1;
979
1074
 
980
 
        if (sscanf(s, "ipv4_tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
 
1075
        if (sscanf(s, "tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
981
1076
                   "src="IP_SCAN_FMT",dst="IP_SCAN_FMT
982
1077
                   ",tos=%i,ttl=%i,flags%n", tun_id_s,
983
 
                    IP_SCAN_ARGS(&tun_key.ipv4_src),
984
 
                    IP_SCAN_ARGS(&tun_key.ipv4_dst), &tos, &ttl,
 
1078
                    IP_SCAN_ARGS(&tun_key.ip_src),
 
1079
                    IP_SCAN_ARGS(&tun_key.ip_dst), &tos, &ttl,
985
1080
                    &n) > 0 && n > 0) {
986
1081
            int res;
 
1082
            uint32_t flags;
987
1083
 
988
1084
            tun_key.tun_id = htonll(strtoull(tun_id_s, NULL, 0));
989
 
            tun_key.ipv4_tos = tos;
990
 
            tun_key.ipv4_ttl = ttl;
 
1085
            tun_key.ip_tos = tos;
 
1086
            tun_key.ip_ttl = ttl;
 
1087
            res = parse_flags(&s[n], flow_tun_flag_to_string, &flags);
 
1088
            tun_key.flags = (uint16_t) flags;
991
1089
 
992
 
            res = parse_flags(&s[n], odp_tun_flag_to_string,
993
 
                              &tun_key.tun_flags);
994
1090
            if (res < 0) {
995
1091
                return res;
996
1092
            }
999
1095
                return -EINVAL;
1000
1096
            }
1001
1097
            n++;
1002
 
 
1003
 
            memset(&tun_key.pad, 0, sizeof tun_key.pad);
1004
 
            nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV4_TUNNEL, &tun_key,
1005
 
                              sizeof tun_key);
 
1098
            tun_key_to_attr(key, &tun_key);
1006
1099
            return n;
1007
1100
        }
1008
1101
    }