Using an minimatch in tnl_port_map_insert() and miniflow in tnl_port_map_delete() is slightly more efficient than using a full size match and flow, respectively.
Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- lib/tnl-ports.c | 56 ++++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c index 9832ef4..d9e4e63 100644 --- a/lib/tnl-ports.c +++ b/lib/tnl-ports.c @@ -56,36 +56,34 @@ tnl_port_free(struct tnl_port_in *p) } static void -tnl_port_init_flow(struct flow *flow, ovs_be32 ip_dst, ovs_be16 udp_port) +tnl_port_init_miniflow__(struct miniflow *mf, ovs_be16 dl_type, + uint8_t nw_frag, uint8_t nw_proto, ovs_be32 ip_dst, + ovs_be16 udp_port) { - memset(flow, 0, sizeof *flow); - flow->dl_type = htons(ETH_TYPE_IP); - if (udp_port) { - flow->nw_proto = IPPROTO_UDP; - } else { - flow->nw_proto = IPPROTO_GRE; - } - flow->tp_dst = udp_port; - /* When matching on incoming flow from remove tnl end point, - * our dst ip address is source ip for them. */ - flow->nw_src = ip_dst; + struct mf_ctx ctx = MF_CTX_INITIALIZER(mf->inline_values, MINI_N_INLINE); + + miniflow_push_be16(ctx, dl_type, dl_type); + miniflow_push_be16(ctx, vlan_tci, 0); + miniflow_push_be32(ctx, nw_src, ip_dst); + miniflow_push_be32(ctx, nw_frag, BYTES_TO_BE32(nw_frag, 0, 0, nw_proto)); + miniflow_push_be16(ctx, tp_src, 0); + miniflow_push_be16(ctx, tp_dst, udp_port); + MF_CTX_FINISH(ctx, mf); } void tnl_port_map_insert(odp_port_t port, ovs_be32 ip_dst, ovs_be16 udp_port, const char dev_name[]) { - const struct cls_rule *cr; struct tnl_port_in *p; - struct match match; - - memset(&match, 0, sizeof match); - tnl_port_init_flow(&match.flow, ip_dst, udp_port); + struct minimatch mm; + tnl_port_init_miniflow__(&mm.flow, htons(ETH_TYPE_IP), 0, + (udp_port) ? IPPROTO_UDP : IPPROTO_GRE, + ip_dst, udp_port); ovs_mutex_lock(&mutex); do { - cr = classifier_lookup(&cls, &match.flow, NULL); - p = tnl_port_cast(cr); + p = tnl_port_cast(classifier_lookup_miniflow(&cls, &mm.flow)); /* Try again if the rule was released before we get the reference. */ } while (p && !ovs_refcount_try_ref_rcu(&p->ref_cnt)); @@ -93,13 +91,11 @@ tnl_port_map_insert(odp_port_t port, ovs_be32 ip_dst, ovs_be16 udp_port, p = xzalloc(sizeof *p); p->portno = port; - match.wc.masks.dl_type = OVS_BE16_MAX; - match.wc.masks.nw_proto = 0xff; - match.wc.masks.nw_frag = 0xff; /* XXX: No fragments support. */ - match.wc.masks.tp_dst = OVS_BE16_MAX; - match.wc.masks.nw_src = OVS_BE32_MAX; + /* XXX: No fragments support. */ + tnl_port_init_miniflow__(&mm.mask.masks, OVS_BE16_MAX, UINT8_MAX, + UINT8_MAX, OVS_BE32_MAX, OVS_BE16_MAX); + cls_rule_init_from_minimatch(&p->cr, &mm, 0); /* Priority == 0. */ - cls_rule_init(&p->cr, &match, 0); /* Priority == 0. */ ovs_refcount_init(&p->ref_cnt); strncpy(p->dev_name, dev_name, IFNAMSIZ); @@ -125,13 +121,13 @@ tnl_port_unref(const struct cls_rule *cr) void tnl_port_map_delete(ovs_be32 ip_dst, ovs_be16 udp_port) { - const struct cls_rule *cr; - struct flow flow; + struct miniflow mf; - tnl_port_init_flow(&flow, ip_dst, udp_port); + tnl_port_init_miniflow__(&mf, htons(ETH_TYPE_IP), 0, + (udp_port) ? IPPROTO_UDP : IPPROTO_GRE, + ip_dst, udp_port); - cr = classifier_lookup(&cls, &flow, NULL); - tnl_port_unref(cr); + tnl_port_unref(classifier_lookup_miniflow(&cls, &mf)); } odp_port_t -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev