X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=lib%2Fmatch.c;h=e4b28fa5bba80834604ae72e822d1fb81eb007ab;hb=bef3f465bcd5f81823c7fb8750e3f639486b3587;hp=d527d04314c76a150bbb350ef09f18e47ca97f8e;hpb=07659514c3c1e8998a4935a998b627d716c559f9;p=cascardo%2Fovs.git diff --git a/lib/match.c b/lib/match.c index d527d0431..e4b28fa5b 100644 --- a/lib/match.c +++ b/lib/match.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -190,6 +190,36 @@ match_set_tun_dst_masked(struct match *match, ovs_be32 dst, ovs_be32 mask) match->flow.tunnel.ip_dst = dst & mask; } +void +match_set_tun_ipv6_src(struct match *match, const struct in6_addr *src) +{ + match->flow.tunnel.ipv6_src = *src; + match->wc.masks.tunnel.ipv6_src = in6addr_exact; +} + +void +match_set_tun_ipv6_src_masked(struct match *match, const struct in6_addr *src, + const struct in6_addr *mask) +{ + match->flow.tunnel.ipv6_src = ipv6_addr_bitand(src, mask); + match->wc.masks.tunnel.ipv6_src = *mask; +} + +void +match_set_tun_ipv6_dst(struct match *match, const struct in6_addr *dst) +{ + match->flow.tunnel.ipv6_dst = *dst; + match->wc.masks.tunnel.ipv6_dst = in6addr_exact; +} + +void +match_set_tun_ipv6_dst_masked(struct match *match, const struct in6_addr *dst, + const struct in6_addr *mask) +{ + match->flow.tunnel.ipv6_dst = ipv6_addr_bitand(dst, mask); + match->wc.masks.tunnel.ipv6_dst = *mask; +} + void match_set_tun_ttl(struct match *match, uint8_t ttl) { @@ -304,6 +334,38 @@ match_set_ct_zone(struct match *match, uint16_t ct_zone) match->wc.masks.ct_zone = UINT16_MAX; } +void +match_set_ct_mark(struct match *match, uint32_t ct_mark) +{ + match_set_ct_mark_masked(match, ct_mark, UINT32_MAX); +} + +void +match_set_ct_mark_masked(struct match *match, uint32_t ct_mark, + uint32_t mask) +{ + match->flow.ct_mark = ct_mark & mask; + match->wc.masks.ct_mark = mask; +} + +void +match_set_ct_label(struct match *match, ovs_u128 ct_label) +{ + ovs_u128 mask; + + mask.u64.lo = UINT64_MAX; + mask.u64.hi = UINT64_MAX; + match_set_ct_label_masked(match, ct_label, mask); +} + +void +match_set_ct_label_masked(struct match *match, ovs_u128 value, ovs_u128 mask) +{ + match->flow.ct_label.u64.lo = value.u64.lo & mask.u64.lo; + match->flow.ct_label.u64.hi = value.u64.hi & mask.u64.hi; + match->wc.masks.ct_label = mask; +} + void match_set_dl_type(struct match *match, ovs_be16 dl_type) { @@ -529,6 +591,23 @@ match_set_mpls_bos(struct match *match, int idx, uint8_t mpls_bos) flow_set_mpls_bos(&match->flow, idx, mpls_bos); } +/* Modifies 'match' so that the TTL of MPLS label 'idx' is wildcarded. */ +void +match_set_any_mpls_ttl(struct match *match, int idx) +{ + match->wc.masks.mpls_lse[idx] &= ~htonl(MPLS_TTL_MASK); + flow_set_mpls_ttl(&match->flow, idx, 0); +} + +/* Modifies 'match' so that it matches only packets in which the TTL of MPLS + * label 'idx' equals 'mpls_ttl'. */ +void +match_set_mpls_ttl(struct match *match, int idx, uint8_t mpls_ttl) +{ + match->wc.masks.mpls_lse[idx] |= htonl(MPLS_TTL_MASK); + flow_set_mpls_ttl(&match->flow, idx, mpls_ttl); +} + /* Modifies 'match' so that the MPLS LSE is wildcarded. */ void match_set_any_mpls_lse(struct match *match, int idx) @@ -830,7 +909,7 @@ format_ipv6_netmask(struct ds *s, const char *name, { if (!ipv6_mask_is_any(netmask)) { ds_put_format(s, "%s=", name); - print_ipv6_masked(s, addr, netmask); + ipv6_format_masked(addr, netmask, s); ds_put_char(s, ','); } } @@ -917,6 +996,10 @@ format_flow_tunnel(struct ds *s, const struct match *match) format_be64_masked(s, "tun_id", tnl->tun_id, wc->masks.tunnel.tun_id); 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); + format_ipv6_netmask(s, "tun_ipv6_src", &tnl->ipv6_src, + &wc->masks.tunnel.ipv6_src); + format_ipv6_netmask(s, "tun_ipv6_dst", &tnl->ipv6_dst, + &wc->masks.tunnel.ipv6_dst); if (wc->masks.tunnel.gbp_id) { format_be16_masked(s, "tun_gbp_id", tnl->gbp_id, @@ -943,6 +1026,22 @@ format_flow_tunnel(struct ds *s, const struct match *match) tun_metadata_match_format(s, match); } +static void +format_ct_label_masked(struct ds *s, const ovs_u128 *key, const ovs_u128 *mask) +{ + if (!ovs_u128_is_zero(mask)) { + ovs_be128 value = hton128(*key); + ds_put_format(s, "ct_label="); + ds_put_hex(s, &value, sizeof value); + if (!is_all_ones(mask, sizeof(*mask))) { + value = hton128(*mask); + ds_put_char(s, '/'); + ds_put_hex(s, &value, sizeof value); + } + ds_put_char(s, ','); + } +} + /* Appends a string representation of 'match' to 's'. If 'priority' is * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */ void @@ -956,7 +1055,7 @@ match_format(const struct match *match, struct ds *s, int priority) int i; - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 34); + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 35); if (priority != OFP_DEFAULT_PRIORITY) { ds_put_format(s, "priority=%d,", priority); @@ -1007,6 +1106,14 @@ match_format(const struct match *match, struct ds *s, int priority) format_uint16_masked(s, "ct_zone", f->ct_zone, wc->masks.ct_zone); } + if (wc->masks.ct_mark) { + format_uint32_masked(s, "ct_mark", f->ct_mark, wc->masks.ct_mark); + } + + if (!ovs_u128_is_zero(&wc->masks.ct_label)) { + format_ct_label_masked(s, &f->ct_label, &wc->masks.ct_label); + } + if (wc->masks.dl_type) { skip_type = true; if (f->dl_type == htons(ETH_TYPE_IP)) {