X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdpif-netdev.c;h=96c5feb428bdaaa508013c917848a5236be476ed;hb=8ba0a5227f6e6b50838c157bd303c2d5bf6f4e59;hp=9ad9386916cff8ff1d313f1862944fd403be5e4c;hpb=cd527139bbe08729f18112eea5073ffd0f435979;p=sliver-openvswitch.git diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 9ad938691..96c5feb42 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -323,7 +323,6 @@ struct pmd_thread { pthread_t thread; int id; atomic_uint change_seq; - char *name; }; /* Interface to netdev-based datapath. */ @@ -353,10 +352,11 @@ static int dpif_netdev_open(const struct dpif_class *, const char *name, bool create, struct dpif **); static int dp_netdev_output_userspace(struct dp_netdev *dp, struct ofpbuf *, int queue_no, int type, - const struct flow *, + const struct miniflow *, const struct nlattr *userdata); static void dp_netdev_execute_actions(struct dp_netdev *dp, - const struct flow *, struct ofpbuf *, bool may_steal, + const struct miniflow *, + struct ofpbuf *, bool may_steal, struct pkt_metadata *, const struct nlattr *actions, size_t actions_len); @@ -1063,13 +1063,15 @@ dp_netdev_flow_cast(const struct cls_rule *cr) } static struct dp_netdev_flow * -dp_netdev_lookup_flow(const struct dp_netdev *dp, const struct flow *flow) +dp_netdev_lookup_flow(const struct dp_netdev *dp, const struct miniflow *key) OVS_EXCLUDED(dp->cls.rwlock) { struct dp_netdev_flow *netdev_flow; + struct cls_rule *rule; fat_rwlock_rdlock(&dp->cls.rwlock); - netdev_flow = dp_netdev_flow_cast(classifier_lookup(&dp->cls, flow, NULL)); + rule = classifier_lookup_miniflow_first(&dp->cls, key); + netdev_flow = dp_netdev_flow_cast(rule); fat_rwlock_unlock(&dp->cls.rwlock); return netdev_flow; @@ -1294,6 +1296,7 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put) struct dp_netdev *dp = get_dp_netdev(dpif); struct dp_netdev_flow *netdev_flow; struct flow flow; + struct miniflow miniflow; struct flow_wildcards wc; int error; @@ -1307,9 +1310,10 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put) if (error) { return error; } + miniflow_init(&miniflow, &flow); ovs_mutex_lock(&dp->flow_mutex); - netdev_flow = dp_netdev_lookup_flow(dp, &flow); + netdev_flow = dp_netdev_lookup_flow(dp, &miniflow); if (!netdev_flow) { if (put->flags & DPIF_FP_CREATE) { if (hmap_count(&dp->flow_table) < MAX_FLOWS) { @@ -1442,6 +1446,7 @@ dpif_netdev_flow_dump_next(const struct dpif *dpif, void *iter_, void *state_, struct dp_netdev_flow_state *state = state_; struct dp_netdev *dp = get_dp_netdev(dpif); struct dp_netdev_flow *netdev_flow; + struct flow_wildcards wc; int error; ovs_mutex_lock(&iter->mutex); @@ -1464,11 +1469,13 @@ dpif_netdev_flow_dump_next(const struct dpif *dpif, void *iter_, void *state_, return error; } + minimask_expand(&netdev_flow->cr.match.mask, &wc); + if (key) { struct ofpbuf buf; ofpbuf_use_stack(&buf, &state->keybuf, sizeof state->keybuf); - odp_flow_key_from_flow(&buf, &netdev_flow->flow, + odp_flow_key_from_flow(&buf, &netdev_flow->flow, &wc.masks, netdev_flow->flow.in_port.odp_port); *key = ofpbuf_data(&buf); @@ -1477,10 +1484,8 @@ dpif_netdev_flow_dump_next(const struct dpif *dpif, void *iter_, void *state_, if (key && mask) { struct ofpbuf buf; - struct flow_wildcards wc; ofpbuf_use_stack(&buf, &state->maskbuf, sizeof state->maskbuf); - minimask_expand(&netdev_flow->cr.match.mask, &wc); odp_flow_key_from_mask(&buf, &wc.masks, &netdev_flow->flow, odp_to_u32(wc.masks.in_port.odp_port), SIZE_MAX); @@ -1522,7 +1527,8 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) { struct dp_netdev *dp = get_dp_netdev(dpif); struct pkt_metadata *md = &execute->md; - struct flow key; + struct miniflow key; + uint32_t buf[FLOW_U32S]; if (ofpbuf_size(execute->packet) < ETH_HEADER_LEN || ofpbuf_size(execute->packet) > UINT16_MAX) { @@ -1530,7 +1536,8 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) } /* Extract flow key. */ - flow_extract(execute->packet, md, &key); + miniflow_initialize(&key, buf); + miniflow_extract(execute->packet, md, &key); ovs_rwlock_rdlock(&dp->port_rwlock); dp_netdev_execute_actions(dp, &key, execute->packet, false, md, @@ -1869,8 +1876,6 @@ pmd_thread_main(void *f_) int poll_cnt; int i; - f->name = xasprintf("pmd_%u", ovsthread_id_self()); - set_subprogram_name("%s", f->name); poll_cnt = 0; poll_list = NULL; @@ -1910,7 +1915,6 @@ reload: } free(poll_list); - free(f->name); return NULL; } @@ -1947,7 +1951,7 @@ dp_netdev_set_pmd_threads(struct dp_netdev *dp, int n) /* Each thread will distribute all devices rx-queues among * themselves. */ - xpthread_create(&f->thread, NULL, pmd_thread_main, f); + f->thread = ovs_thread_create("pmd", pmd_thread_main, f); } } @@ -1963,9 +1967,9 @@ dp_netdev_flow_stats_new_cb(void) static void dp_netdev_flow_used(struct dp_netdev_flow *netdev_flow, const struct ofpbuf *packet, - const struct flow *key) + const struct miniflow *key) { - uint16_t tcp_flags = ntohs(key->tcp_flags); + uint16_t tcp_flags = miniflow_get_tcp_flags(key); long long int now = time_msec(); struct dp_netdev_flow_stats *bucket; @@ -2005,13 +2009,16 @@ dp_netdev_input(struct dp_netdev *dp, struct ofpbuf *packet, OVS_REQ_RDLOCK(dp->port_rwlock) { struct dp_netdev_flow *netdev_flow; - struct flow key; + struct miniflow key; + uint32_t buf[FLOW_U32S]; if (ofpbuf_size(packet) < ETH_HEADER_LEN) { ofpbuf_delete(packet); return; } - flow_extract(packet, md, &key); + miniflow_initialize(&key, buf); + miniflow_extract(packet, md, &key); + netdev_flow = dp_netdev_lookup_flow(dp, &key); if (netdev_flow) { struct dp_netdev_actions *actions; @@ -2025,7 +2032,8 @@ dp_netdev_input(struct dp_netdev *dp, struct ofpbuf *packet, } else if (dp->handler_queues) { dp_netdev_count_packet(dp, DP_STAT_MISS); dp_netdev_output_userspace(dp, packet, - flow_hash_5tuple(&key, 0) % dp->n_handlers, + miniflow_hash_5tuple(&key, 0) + % dp->n_handlers, DPIF_UC_MISS, &key, NULL); ofpbuf_delete(packet); } @@ -2044,7 +2052,7 @@ dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet, static int dp_netdev_output_userspace(struct dp_netdev *dp, struct ofpbuf *packet, - int queue_no, int type, const struct flow *flow, + int queue_no, int type, const struct miniflow *key, const struct nlattr *userdata) { struct dp_netdev_queue *q; @@ -2058,6 +2066,7 @@ dp_netdev_output_userspace(struct dp_netdev *dp, struct ofpbuf *packet, struct dpif_upcall *upcall = &u->upcall; struct ofpbuf *buf = &u->buf; size_t buf_size; + struct flow flow; upcall->type = type; @@ -2070,7 +2079,8 @@ dp_netdev_output_userspace(struct dp_netdev *dp, struct ofpbuf *packet, ofpbuf_init(buf, buf_size); /* Put ODP flow. */ - odp_flow_key_from_flow(buf, flow, flow->in_port.odp_port); + miniflow_expand(key, &flow); + odp_flow_key_from_flow(buf, &flow, NULL, flow.in_port.odp_port); upcall->key = ofpbuf_data(buf); upcall->key_len = ofpbuf_size(buf); @@ -2099,7 +2109,7 @@ dp_netdev_output_userspace(struct dp_netdev *dp, struct ofpbuf *packet, struct dp_netdev_execute_aux { struct dp_netdev *dp; - const struct flow *key; + const struct miniflow *key; }; static void @@ -2127,7 +2137,7 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet, userdata = nl_attr_find_nested(a, OVS_USERSPACE_ATTR_USERDATA); dp_netdev_output_userspace(aux->dp, packet, - flow_hash_5tuple(aux->key, 0) + miniflow_hash_5tuple(aux->key, 0) % aux->dp->n_handlers, DPIF_UC_ACTION, aux->key, userdata); @@ -2138,25 +2148,35 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet, break; } + case OVS_ACTION_ATTR_HASH: { + const struct ovs_action_hash *hash_act; + uint32_t hash; + + hash_act = nl_attr_get(a); + if (hash_act->hash_alg == OVS_HASH_ALG_L4) { + /* Hash need not be symmetric, nor does it need to include + * L2 fields. */ + hash = miniflow_hash_5tuple(aux->key, hash_act->hash_basis); + if (!hash) { + hash = 1; /* 0 is not valid */ + } + + } else { + VLOG_WARN("Unknown hash algorithm specified for the hash action."); + hash = 2; + } + + md->dp_hash = hash; + break; + } + case OVS_ACTION_ATTR_RECIRC: if (*depth < MAX_RECIRC_DEPTH) { struct pkt_metadata recirc_md = *md; struct ofpbuf *recirc_packet; - const struct ovs_action_recirc *act; recirc_packet = may_steal ? packet : ofpbuf_clone(packet); - - act = nl_attr_get(a); - recirc_md.recirc_id = act->recirc_id; - recirc_md.dp_hash = 0; - - if (act->hash_alg == OVS_RECIRC_HASH_ALG_L4) { - recirc_md.dp_hash = flow_hash_symmetric_l4(aux->key, - act->hash_bias); - if (!recirc_md.dp_hash) { - recirc_md.dp_hash = 1; /* 0 is not valid */ - } - } + recirc_md.recirc_id = nl_attr_get_u32(a); (*depth)++; dp_netdev_input(aux->dp, recirc_packet, &recirc_md); @@ -2181,7 +2201,7 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet, } static void -dp_netdev_execute_actions(struct dp_netdev *dp, const struct flow *key, +dp_netdev_execute_actions(struct dp_netdev *dp, const struct miniflow *key, struct ofpbuf *packet, bool may_steal, struct pkt_metadata *md, const struct nlattr *actions, size_t actions_len)