aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c27
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
284err: 284err:
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);