diff options
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r-- | net/openvswitch/datapath.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 4c4b62ccc7d7..f996db343247 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -208,7 +208,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb) | |||
208 | int error; | 208 | int error; |
209 | int key_len; | 209 | int key_len; |
210 | 210 | ||
211 | stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id()); | 211 | stats = this_cpu_ptr(dp->stats_percpu); |
212 | 212 | ||
213 | /* Extract flow from 'skb' into 'key'. */ | 213 | /* Extract flow from 'skb' into 'key'. */ |
214 | error = ovs_flow_extract(skb, p->port_no, &key, &key_len); | 214 | error = ovs_flow_extract(skb, p->port_no, &key, &key_len); |
@@ -282,7 +282,7 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb, | |||
282 | return 0; | 282 | return 0; |
283 | 283 | ||
284 | err: | 284 | err: |
285 | stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id()); | 285 | stats = this_cpu_ptr(dp->stats_percpu); |
286 | 286 | ||
287 | u64_stats_update_begin(&stats->sync); | 287 | u64_stats_update_begin(&stats->sync); |
288 | stats->n_lost++; | 288 | stats->n_lost++; |
@@ -479,8 +479,10 @@ static int validate_set(const struct nlattr *a, | |||
479 | 479 | ||
480 | switch (key_type) { | 480 | switch (key_type) { |
481 | const struct ovs_key_ipv4 *ipv4_key; | 481 | const struct ovs_key_ipv4 *ipv4_key; |
482 | const struct ovs_key_ipv6 *ipv6_key; | ||
482 | 483 | ||
483 | case OVS_KEY_ATTR_PRIORITY: | 484 | case OVS_KEY_ATTR_PRIORITY: |
485 | case OVS_KEY_ATTR_SKB_MARK: | ||
484 | case OVS_KEY_ATTR_ETHERNET: | 486 | case OVS_KEY_ATTR_ETHERNET: |
485 | break; | 487 | break; |
486 | 488 | ||
@@ -500,6 +502,25 @@ static int validate_set(const struct nlattr *a, | |||
500 | 502 | ||
501 | break; | 503 | break; |
502 | 504 | ||
505 | case OVS_KEY_ATTR_IPV6: | ||
506 | if (flow_key->eth.type != htons(ETH_P_IPV6)) | ||
507 | return -EINVAL; | ||
508 | |||
509 | if (!flow_key->ip.proto) | ||
510 | return -EINVAL; | ||
511 | |||
512 | ipv6_key = nla_data(ovs_key); | ||
513 | if (ipv6_key->ipv6_proto != flow_key->ip.proto) | ||
514 | return -EINVAL; | ||
515 | |||
516 | if (ipv6_key->ipv6_frag != flow_key->ip.frag) | ||
517 | return -EINVAL; | ||
518 | |||
519 | if (ntohl(ipv6_key->ipv6_label) & 0xFFF00000) | ||
520 | return -EINVAL; | ||
521 | |||
522 | break; | ||
523 | |||
503 | case OVS_KEY_ATTR_TCP: | 524 | case OVS_KEY_ATTR_TCP: |
504 | if (flow_key->ip.proto != IPPROTO_TCP) | 525 | if (flow_key->ip.proto != IPPROTO_TCP) |
505 | return -EINVAL; | 526 | return -EINVAL; |
@@ -675,6 +696,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) | |||
675 | goto err_flow_free; | 696 | goto err_flow_free; |
676 | 697 | ||
677 | err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority, | 698 | err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority, |
699 | &flow->key.phy.skb_mark, | ||
678 | &flow->key.phy.in_port, | 700 | &flow->key.phy.in_port, |
679 | a[OVS_PACKET_ATTR_KEY]); | 701 | a[OVS_PACKET_ATTR_KEY]); |
680 | if (err) | 702 | if (err) |
@@ -694,6 +716,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) | |||
694 | 716 | ||
695 | OVS_CB(packet)->flow = flow; | 717 | OVS_CB(packet)->flow = flow; |
696 | packet->priority = flow->key.phy.priority; | 718 | packet->priority = flow->key.phy.priority; |
719 | packet->mark = flow->key.phy.skb_mark; | ||
697 | 720 | ||
698 | rcu_read_lock(); | 721 | rcu_read_lock(); |
699 | dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); | 722 | dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); |