X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=datapath%2Fdatapath.c;h=9eeb28cd1d12c04be4253c94e1f575ea6f52535e;hb=309eaa2bc4f9367cb1ca6ec91b583a7a6cabf079;hp=aa563fb6d43cdca38b814cf63930b59b95f827e6;hpb=f1588b1fa1be46231ee079358e428dae74ff09cc;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index aa563fb6..9eeb28cd 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -591,7 +591,7 @@ void dp_process_received_packet(struct dp_port *p, struct sk_buff *skb) /* Execute actions. */ execute_actions(dp, skb, &OVS_CB(skb)->flow->key, acts->actions, - acts->n_actions, GFP_ATOMIC); + acts->n_actions); stats_counter_off = offsetof(struct dp_stats_percpu, n_hit); /* Check whether sub-actions looped too much. */ @@ -904,6 +904,8 @@ static int validate_actions(const struct sw_flow_actions *actions) for (i = 0; i < actions->n_actions; i++) { const union odp_action *a = &actions->actions[i]; + __be16 mask; + switch (a->type) { case ODPAT_CONTROLLER: case ODPAT_STRIP_VLAN: @@ -925,14 +927,13 @@ static int validate_actions(const struct sw_flow_actions *actions) return -EINVAL; break; - case ODPAT_SET_VLAN_VID: - if (a->vlan_vid.vlan_vid & htons(~VLAN_VID_MASK)) + case ODPAT_SET_DL_TCI: + mask = a->dl_tci.mask; + if (mask != htons(VLAN_VID_MASK) && + mask != htons(VLAN_PCP_MASK) && + mask != htons(VLAN_VID_MASK | VLAN_PCP_MASK)) return -EINVAL; - break; - - case ODPAT_SET_VLAN_PCP: - if (a->vlan_pcp.vlan_pcp - & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT)) + if (a->dl_tci.tci & ~mask) return -EINVAL; break; @@ -975,24 +976,15 @@ error: return ERR_PTR(error); } -static struct timespec get_time_offset(void) -{ - struct timespec now_mono, now_jiffies; - - ktime_get_ts(&now_mono); - jiffies_to_timespec(jiffies, &now_jiffies); - return timespec_sub(now_mono, now_jiffies); -} - -static void get_stats(struct sw_flow *flow, struct odp_flow_stats *stats, - struct timespec time_offset) +static void get_stats(struct sw_flow *flow, struct odp_flow_stats *stats) { if (flow->used) { - struct timespec flow_ts, used; + struct timespec offset_ts, used, now_mono; - jiffies_to_timespec(flow->used, &flow_ts); - set_normalized_timespec(&used, flow_ts.tv_sec + time_offset.tv_sec, - flow_ts.tv_nsec + time_offset.tv_nsec); + ktime_get_ts(&now_mono); + jiffies_to_timespec(jiffies - flow->used, &offset_ts); + set_normalized_timespec(&used, now_mono.tv_sec - offset_ts.tv_sec, + now_mono.tv_nsec - offset_ts.tv_nsec); stats->used_sec = used.tv_sec; stats->used_nsec = used.tv_nsec; @@ -1039,8 +1031,6 @@ static int do_put_flow(struct datapath *dp, struct odp_flow_put *uf, struct tbl *table; int error; - memset(uf->flow.key.reserved, 0, sizeof uf->flow.key.reserved); - table = rcu_dereference(dp->table); flow_node = tbl_lookup(table, &uf->flow.key, flow_hash(&uf->flow.key), flow_cmp); if (!flow_node) { @@ -1109,7 +1099,7 @@ static int do_put_flow(struct datapath *dp, struct odp_flow_put *uf, /* Fetch stats, then clear them if necessary. */ spin_lock_bh(&flow->lock); - get_stats(flow, stats, get_time_offset()); + get_stats(flow, stats); if (uf->flags & ODPPF_ZERO_STATS) clear_stats(flow); spin_unlock_bh(&flow->lock); @@ -1147,7 +1137,6 @@ static int put_flow(struct datapath *dp, struct odp_flow_put __user *ufp) } static int do_answer_query(struct sw_flow *flow, u32 query_flags, - struct timespec time_offset, struct odp_flow_stats __user *ustats, union odp_action __user *actions, u32 __user *n_actionsp) @@ -1157,7 +1146,7 @@ static int do_answer_query(struct sw_flow *flow, u32 query_flags, u32 n_actions; spin_lock_bh(&flow->lock); - get_stats(flow, &stats, time_offset); + get_stats(flow, &stats); if (query_flags & ODPFF_ZERO_TCP_FLAGS) flow->tcp_flags = 0; @@ -1181,7 +1170,6 @@ static int do_answer_query(struct sw_flow *flow, u32 query_flags, } static int answer_query(struct sw_flow *flow, u32 query_flags, - struct timespec time_offset, struct odp_flow __user *ufp) { union odp_action *actions; @@ -1189,7 +1177,7 @@ static int answer_query(struct sw_flow *flow, u32 query_flags, if (get_user(actions, &ufp->actions)) return -EFAULT; - return do_answer_query(flow, query_flags, time_offset, + return do_answer_query(flow, query_flags, &ufp->stats, actions, &ufp->n_actions); } @@ -1199,7 +1187,6 @@ static struct sw_flow *do_del_flow(struct datapath *dp, struct odp_flow_key *key struct tbl_node *flow_node; int error; - memset(key->reserved, 0, sizeof key->reserved); flow_node = tbl_lookup(table, key, flow_hash(key), flow_cmp); if (!flow_node) return ERR_PTR(-ENOENT); @@ -1228,7 +1215,7 @@ static int del_flow(struct datapath *dp, struct odp_flow __user *ufp) if (IS_ERR(flow)) return PTR_ERR(flow); - error = answer_query(flow, 0, get_time_offset(), ufp); + error = answer_query(flow, 0, ufp); flow_deferred_free(flow); return error; } @@ -1236,11 +1223,8 @@ static int del_flow(struct datapath *dp, struct odp_flow __user *ufp) static int do_query_flows(struct datapath *dp, const struct odp_flowvec *flowvec) { struct tbl *table = rcu_dereference(dp->table); - struct timespec time_offset; u32 i; - time_offset = get_time_offset(); - for (i = 0; i < flowvec->n_flows; i++) { struct odp_flow __user *ufp = &flowvec->flows[i]; struct odp_flow uf; @@ -1249,13 +1233,12 @@ static int do_query_flows(struct datapath *dp, const struct odp_flowvec *flowvec if (copy_from_user(&uf, ufp, sizeof uf)) return -EFAULT; - memset(uf.key.reserved, 0, sizeof uf.key.reserved); flow_node = tbl_lookup(table, &uf.key, flow_hash(&uf.key), flow_cmp); if (!flow_node) error = put_user(ENOENT, &ufp->stats.error); else - error = answer_query(flow_cast(flow_node), uf.flags, time_offset, ufp); + error = answer_query(flow_cast(flow_node), uf.flags, ufp); if (error) return -EFAULT; } @@ -1266,7 +1249,6 @@ struct list_flows_cbdata { struct odp_flow __user *uflows; u32 n_flows; u32 listed_flows; - struct timespec time_offset; }; static int list_flow(struct tbl_node *node, void *cbdata_) @@ -1278,7 +1260,7 @@ static int list_flow(struct tbl_node *node, void *cbdata_) if (copy_to_user(&ufp->key, &flow->key, sizeof flow->key)) return -EFAULT; - error = answer_query(flow, 0, cbdata->time_offset, ufp); + error = answer_query(flow, 0, ufp); if (error) return error; @@ -1298,7 +1280,6 @@ static int do_list_flows(struct datapath *dp, const struct odp_flowvec *flowvec) cbdata.uflows = flowvec->flows; cbdata.n_flows = flowvec->n_flows; cbdata.listed_flows = 0; - cbdata.time_offset = get_time_offset(); error = tbl_foreach(rcu_dereference(dp->table), list_flow, &cbdata); return error ? error : cbdata.listed_flows; @@ -1379,8 +1360,7 @@ static int do_execute(struct datapath *dp, const struct odp_execute *execute) goto error_free_skb; rcu_read_lock(); - err = execute_actions(dp, skb, &key, actions->actions, - actions->n_actions, GFP_KERNEL); + err = execute_actions(dp, skb, &key, actions->actions, actions->n_actions); rcu_read_unlock(); kfree(actions); @@ -1805,7 +1785,6 @@ static int compat_put_flow(struct datapath *dp, struct compat_odp_flow_put __use } static int compat_answer_query(struct sw_flow *flow, u32 query_flags, - struct timespec time_offset, struct compat_odp_flow __user *ufp) { compat_uptr_t actions; @@ -1813,7 +1792,7 @@ static int compat_answer_query(struct sw_flow *flow, u32 query_flags, if (get_user(actions, &ufp->actions)) return -EFAULT; - return do_answer_query(flow, query_flags, time_offset, &ufp->stats, + return do_answer_query(flow, query_flags, &ufp->stats, compat_ptr(actions), &ufp->n_actions); } @@ -1830,7 +1809,7 @@ static int compat_del_flow(struct datapath *dp, struct compat_odp_flow __user *u if (IS_ERR(flow)) return PTR_ERR(flow); - error = compat_answer_query(flow, 0, get_time_offset(), ufp); + error = compat_answer_query(flow, 0, ufp); flow_deferred_free(flow); return error; } @@ -1838,11 +1817,8 @@ static int compat_del_flow(struct datapath *dp, struct compat_odp_flow __user *u static int compat_query_flows(struct datapath *dp, struct compat_odp_flow *flows, u32 n_flows) { struct tbl *table = rcu_dereference(dp->table); - struct timespec time_offset; u32 i; - time_offset = get_time_offset(); - for (i = 0; i < n_flows; i++) { struct compat_odp_flow __user *ufp = &flows[i]; struct odp_flow uf; @@ -1851,13 +1827,12 @@ static int compat_query_flows(struct datapath *dp, struct compat_odp_flow *flows if (compat_get_flow(&uf, ufp)) return -EFAULT; - memset(uf.key.reserved, 0, sizeof uf.key.reserved); flow_node = tbl_lookup(table, &uf.key, flow_hash(&uf.key), flow_cmp); if (!flow_node) error = put_user(ENOENT, &ufp->stats.error); else - error = compat_answer_query(flow_cast(flow_node), uf.flags, time_offset, ufp); + error = compat_answer_query(flow_cast(flow_node), uf.flags, ufp); if (error) return -EFAULT; } @@ -1868,7 +1843,6 @@ struct compat_list_flows_cbdata { struct compat_odp_flow __user *uflows; u32 n_flows; u32 listed_flows; - struct timespec time_offset; }; static int compat_list_flow(struct tbl_node *node, void *cbdata_) @@ -1880,7 +1854,7 @@ static int compat_list_flow(struct tbl_node *node, void *cbdata_) if (copy_to_user(&ufp->key, &flow->key, sizeof flow->key)) return -EFAULT; - error = compat_answer_query(flow, 0, cbdata->time_offset, ufp); + error = compat_answer_query(flow, 0, ufp); if (error) return error; @@ -1900,7 +1874,6 @@ static int compat_list_flows(struct datapath *dp, struct compat_odp_flow *flows, cbdata.uflows = flows; cbdata.n_flows = n_flows; cbdata.listed_flows = 0; - cbdata.time_offset = get_time_offset(); error = tbl_foreach(rcu_dereference(dp->table), compat_list_flow, &cbdata); return error ? error : cbdata.listed_flows;