Beispiel #1
0
static void
format_flow_tunnel(struct ds *s, const struct match *match)
{
    const struct flow_wildcards *wc = &match->wc;
    const struct flow_tnl *tnl = &match->flow.tunnel;

    switch (wc->masks.tunnel.tun_id) {
    case 0:
        break;
    case CONSTANT_HTONLL(UINT64_MAX):
        ds_put_format(s, "tun_id=%#"PRIx64",", ntohll(tnl->tun_id));
        break;
    default:
        ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64",",
                      ntohll(tnl->tun_id),
                      ntohll(wc->masks.tunnel.tun_id));
        break;
    }
    format_ip_netmask(s, "tun_src", tnl->ip_src, wc->masks.tunnel.ip_src);
    format_ip_netmask(s, "tun_dst", tnl->ip_dst, wc->masks.tunnel.ip_dst);

    if (wc->masks.tunnel.ip_tos) {
        ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos);
    }
    if (wc->masks.tunnel.ip_ttl) {
        ds_put_format(s, "tun_ttl=%"PRIu8",", tnl->ip_ttl);
    }
    if (wc->masks.tunnel.flags) {
        format_flags(s, flow_tun_flag_to_string, tnl->flags, '|');
        ds_put_char(s, ',');
    }
}
Beispiel #2
0
/* Appends a string representation of 'match' to 's'.  If 'priority' is
 * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
void
match_format(const struct match *match, struct ds *s, unsigned int priority)
{
    const struct flow_wildcards *wc = &match->wc;
    size_t start_len = s->length;
    const struct flow *f = &match->flow;
    bool skip_type = false;
    bool skip_proto = false;

    int i;

    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 19);

    if (priority != OFP_DEFAULT_PRIORITY) {
        ds_put_format(s, "priority=%u,", priority);
    }

    if (wc->masks.skb_mark) {
        ds_put_format(s, "skb_mark=%#"PRIx32",", f->skb_mark);
    }

    if (wc->masks.skb_priority) {
        ds_put_format(s, "skb_priority=%#"PRIx32",", f->skb_priority);
    }

    if (wc->masks.dl_type) {
        skip_type = true;
        if (f->dl_type == htons(ETH_TYPE_IP)) {
            if (wc->masks.nw_proto) {
                skip_proto = true;
                if (f->nw_proto == IPPROTO_ICMP) {
                    ds_put_cstr(s, "icmp,");
                } else if (f->nw_proto == IPPROTO_TCP) {
                    ds_put_cstr(s, "tcp,");
                } else if (f->nw_proto == IPPROTO_UDP) {
                    ds_put_cstr(s, "udp,");
                } else {
                    ds_put_cstr(s, "ip,");
                    skip_proto = false;
                }
            } else {
                ds_put_cstr(s, "ip,");
            }
        } else if (f->dl_type == htons(ETH_TYPE_IPV6)) {
            if (wc->masks.nw_proto) {
                skip_proto = true;
                if (f->nw_proto == IPPROTO_ICMPV6) {
                    ds_put_cstr(s, "icmp6,");
                } else if (f->nw_proto == IPPROTO_TCP) {
                    ds_put_cstr(s, "tcp6,");
                } else if (f->nw_proto == IPPROTO_UDP) {
                    ds_put_cstr(s, "udp6,");
                } else {
                    ds_put_cstr(s, "ipv6,");
                    skip_proto = false;
                }
            } else {
                ds_put_cstr(s, "ipv6,");
            }
        } else if (f->dl_type == htons(ETH_TYPE_ARP)) {
            ds_put_cstr(s, "arp,");
        } else if (f->dl_type == htons(ETH_TYPE_RARP)) {
            ds_put_cstr(s, "rarp,");
        } else if (f->mpls_depth) {
            flow_format_mpls(f, s);
        } else {
            skip_type = false;
        }
    }
    for (i = 0; i < FLOW_N_REGS; i++) {
        switch (wc->masks.regs[i]) {
        case 0:
            break;
        case UINT32_MAX:
            ds_put_format(s, "reg%d=0x%"PRIx32",", i, f->regs[i]);
            break;
        default:
            ds_put_format(s, "reg%d=0x%"PRIx32"/0x%"PRIx32",",
                          i, f->regs[i], wc->masks.regs[i]);
            break;
        }
    }

    format_flow_tunnel(s, match);

    switch (wc->masks.metadata) {
    case 0:
        break;
    case CONSTANT_HTONLL(UINT64_MAX):
        ds_put_format(s, "metadata=%#"PRIx64",", ntohll(f->metadata));
        break;
    default:
        ds_put_format(s, "metadata=%#"PRIx64"/%#"PRIx64",",
                      ntohll(f->metadata), ntohll(wc->masks.metadata));
        break;
    }
    if (wc->masks.in_port) {
        ds_put_cstr(s, "in_port=");
        ofputil_format_port(f->in_port, s);
        ds_put_char(s, ',');
    }
    if (wc->masks.vlan_tci) {
        ovs_be16 vid_mask = wc->masks.vlan_tci & htons(VLAN_VID_MASK);
        ovs_be16 pcp_mask = wc->masks.vlan_tci & htons(VLAN_PCP_MASK);
        ovs_be16 cfi = wc->masks.vlan_tci & htons(VLAN_CFI);

        if (cfi && f->vlan_tci & htons(VLAN_CFI)
            && (!vid_mask || vid_mask == htons(VLAN_VID_MASK))
            && (!pcp_mask || pcp_mask == htons(VLAN_PCP_MASK))
            && (vid_mask || pcp_mask)) {
            if (vid_mask) {
                ds_put_format(s, "dl_vlan=%"PRIu16",",
                              vlan_tci_to_vid(f->vlan_tci));
            }
            if (pcp_mask) {
                ds_put_format(s, "dl_vlan_pcp=%d,",
                              vlan_tci_to_pcp(f->vlan_tci));
            }
        } else if (wc->masks.vlan_tci == htons(0xffff)) {
            ds_put_format(s, "vlan_tci=0x%04"PRIx16",", ntohs(f->vlan_tci));
        } else {
            ds_put_format(s, "vlan_tci=0x%04"PRIx16"/0x%04"PRIx16",",
                          ntohs(f->vlan_tci), ntohs(wc->masks.vlan_tci));
        }
    }
    format_eth_masked(s, "dl_src", f->dl_src, wc->masks.dl_src);
    format_eth_masked(s, "dl_dst", f->dl_dst, wc->masks.dl_dst);
    if (!skip_type && wc->masks.dl_type) {
        ds_put_format(s, "dl_type=0x%04"PRIx16",", ntohs(f->dl_type));
    }
    if (f->dl_type == htons(ETH_TYPE_IPV6)) {
        format_ipv6_netmask(s, "ipv6_src", &f->ipv6_src, &wc->masks.ipv6_src);
        format_ipv6_netmask(s, "ipv6_dst", &f->ipv6_dst, &wc->masks.ipv6_dst);
        if (wc->masks.ipv6_label) {
            if (wc->masks.ipv6_label == htonl(UINT32_MAX)) {
                ds_put_format(s, "ipv6_label=0x%05"PRIx32",",
                              ntohl(f->ipv6_label));
            } else {
                ds_put_format(s, "ipv6_label=0x%05"PRIx32"/0x%05"PRIx32",",
                              ntohl(f->ipv6_label),
                              ntohl(wc->masks.ipv6_label));
            }
        }
    } else if (f->dl_type == htons(ETH_TYPE_ARP) ||
               f->dl_type == htons(ETH_TYPE_RARP)) {
        format_ip_netmask(s, "arp_spa", f->nw_src, wc->masks.nw_src);
        format_ip_netmask(s, "arp_tpa", f->nw_dst, wc->masks.nw_dst);
    } else {
        format_ip_netmask(s, "nw_src", f->nw_src, wc->masks.nw_src);
        format_ip_netmask(s, "nw_dst", f->nw_dst, wc->masks.nw_dst);
    }
    if (!skip_proto && wc->masks.nw_proto) {
        if (f->dl_type == htons(ETH_TYPE_ARP) ||
            f->dl_type == htons(ETH_TYPE_RARP)) {
            ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto);
        } else {
            ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto);
        }
    }
    if (f->dl_type == htons(ETH_TYPE_ARP) ||
        f->dl_type == htons(ETH_TYPE_RARP)) {
        format_eth_masked(s, "arp_sha", f->arp_sha, wc->masks.arp_sha);
        format_eth_masked(s, "arp_tha", f->arp_tha, wc->masks.arp_tha);
    }
    if (wc->masks.nw_tos & IP_DSCP_MASK) {
        ds_put_format(s, "nw_tos=%"PRIu8",", f->nw_tos & IP_DSCP_MASK);
    }
    if (wc->masks.nw_tos & IP_ECN_MASK) {
        ds_put_format(s, "nw_ecn=%"PRIu8",", f->nw_tos & IP_ECN_MASK);
    }
    if (wc->masks.nw_ttl) {
        ds_put_format(s, "nw_ttl=%"PRIu8",", f->nw_ttl);
    }
    if (wc->masks.mpls_lse & htonl(MPLS_LABEL_MASK)) {
        ds_put_format(s, "mpls_label=%"PRIu32",",
                 mpls_lse_to_label(f->mpls_lse));
    }
    if (wc->masks.mpls_lse & htonl(MPLS_TC_MASK)) {
        ds_put_format(s, "mpls_tc=%"PRIu8",",
                 mpls_lse_to_tc(f->mpls_lse));
    }
    if (wc->masks.mpls_lse & htonl(MPLS_BOS_MASK)) {
        ds_put_format(s, "mpls_bos=%"PRIu8",",
                 mpls_lse_to_bos(f->mpls_lse));
    }
    switch (wc->masks.nw_frag) {
    case FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_ANY
                      ? (f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "first")
                      : (f->nw_frag & FLOW_NW_FRAG_LATER ? "<error>" : "no"));
        break;

    case FLOW_NW_FRAG_ANY:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_ANY ? "yes" : "no");
        break;

    case FLOW_NW_FRAG_LATER:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "not_later");
        break;
    }
    if (f->dl_type == htons(ETH_TYPE_IP) &&
        f->nw_proto == IPPROTO_ICMP) {
        format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
    } else if (f->dl_type == htons(ETH_TYPE_IPV6) &&
               f->nw_proto == IPPROTO_ICMPV6) {
        format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
        format_ipv6_netmask(s, "nd_target", &f->nd_target,
                            &wc->masks.nd_target);
        format_eth_masked(s, "nd_sll", f->arp_sha, wc->masks.arp_sha);
        format_eth_masked(s, "nd_tll", f->arp_tha, wc->masks.arp_tha);
    } else {
        format_be16_masked(s, "tp_src", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "tp_dst", f->tp_dst, wc->masks.tp_dst);
    }

    if (s->length > start_len && ds_last(s) == ',') {
        s->length--;
    }
}
Beispiel #3
0
{
#ifndef __CHECKER__
    /* I picked some random numbers. */
    const uint16_t s = 0xc9bd;
    const uint32_t l = 0xffe56ae8;
    const uint64_t ll = UINT64_C(0xb6fe878a9117ecdb);

    assert(htons(ntohs(s)) == s);
    assert(ntohs(htons(s)) == s);
    assert(CONSTANT_HTONS(ntohs(s)) == s);
    assert(ntohs(CONSTANT_HTONS(s)) == s);
    assert(ntohs(CONSTANT_HTONS(l)) == (uint16_t) l);
    assert(ntohs(CONSTANT_HTONS(ll)) == (uint16_t) ll);

    assert(htonl(ntohl(l)) == l);
    assert(ntohl(htonl(l)) == l);
    assert(CONSTANT_HTONL(ntohl(l)) == l);
    assert(ntohl(CONSTANT_HTONL(l)) == l);
    assert(ntohl(CONSTANT_HTONL(ll)) == (uint32_t) ll);

    assert(htonll(ntohll(ll)) == ll);
    assert(ntohll(htonll(ll)) == ll);
    assert(CONSTANT_HTONLL(ntohll(ll)) == ll);
    assert(ntohll(CONSTANT_HTONLL(ll)));
#else  /* __CHECKER__ */
/* Making sparse happy with this code makes it unreadable, so don't bother. */
#endif
}

OVSTEST_REGISTER("test-byte-order", test_byte_order_main);