summaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c50
1 files changed, 16 insertions, 34 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 5da2534b140a..50d7782d8d7c 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -251,9 +251,9 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
251 OVS_CB(skb)->flow = flow; 251 OVS_CB(skb)->flow = flow;
252 OVS_CB(skb)->pkt_key = &key; 252 OVS_CB(skb)->pkt_key = &key;
253 253
254 stats_counter = &stats->n_hit; 254 ovs_flow_stats_update(OVS_CB(skb)->flow, skb);
255 ovs_flow_used(OVS_CB(skb)->flow, skb);
256 ovs_execute_actions(dp, skb); 255 ovs_execute_actions(dp, skb);
256 stats_counter = &stats->n_hit;
257 257
258out: 258out:
259 /* Update datapath statistics. */ 259 /* Update datapath statistics. */
@@ -459,14 +459,6 @@ out:
459 return err; 459 return err;
460} 460}
461 461
462static void clear_stats(struct sw_flow *flow)
463{
464 flow->used = 0;
465 flow->tcp_flags = 0;
466 flow->packet_count = 0;
467 flow->byte_count = 0;
468}
469
470static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) 462static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
471{ 463{
472 struct ovs_header *ovs_header = info->userhdr; 464 struct ovs_header *ovs_header = info->userhdr;
@@ -505,7 +497,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
505 packet->protocol = htons(ETH_P_802_2); 497 packet->protocol = htons(ETH_P_802_2);
506 498
507 /* Build an sw_flow for sending this packet. */ 499 /* Build an sw_flow for sending this packet. */
508 flow = ovs_flow_alloc(); 500 flow = ovs_flow_alloc(false);
509 err = PTR_ERR(flow); 501 err = PTR_ERR(flow);
510 if (IS_ERR(flow)) 502 if (IS_ERR(flow))
511 goto err_kfree_skb; 503 goto err_kfree_skb;
@@ -641,10 +633,10 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
641 const int skb_orig_len = skb->len; 633 const int skb_orig_len = skb->len;
642 struct nlattr *start; 634 struct nlattr *start;
643 struct ovs_flow_stats stats; 635 struct ovs_flow_stats stats;
636 __be16 tcp_flags;
637 unsigned long used;
644 struct ovs_header *ovs_header; 638 struct ovs_header *ovs_header;
645 struct nlattr *nla; 639 struct nlattr *nla;
646 unsigned long used;
647 u8 tcp_flags;
648 int err; 640 int err;
649 641
650 ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, cmd); 642 ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, cmd);
@@ -673,24 +665,17 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
673 665
674 nla_nest_end(skb, nla); 666 nla_nest_end(skb, nla);
675 667
676 spin_lock_bh(&flow->lock); 668 ovs_flow_stats_get(flow, &stats, &used, &tcp_flags);
677 used = flow->used;
678 stats.n_packets = flow->packet_count;
679 stats.n_bytes = flow->byte_count;
680 tcp_flags = (u8)ntohs(flow->tcp_flags);
681 spin_unlock_bh(&flow->lock);
682
683 if (used && 669 if (used &&
684 nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used))) 670 nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used)))
685 goto nla_put_failure; 671 goto nla_put_failure;
686 672
687 if (stats.n_packets && 673 if (stats.n_packets &&
688 nla_put(skb, OVS_FLOW_ATTR_STATS, 674 nla_put(skb, OVS_FLOW_ATTR_STATS, sizeof(struct ovs_flow_stats), &stats))
689 sizeof(struct ovs_flow_stats), &stats))
690 goto nla_put_failure; 675 goto nla_put_failure;
691 676
692 if (tcp_flags && 677 if ((u8)ntohs(tcp_flags) &&
693 nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, tcp_flags)) 678 nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, (u8)ntohs(tcp_flags)))
694 goto nla_put_failure; 679 goto nla_put_failure;
695 680
696 /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if 681 /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if
@@ -770,6 +755,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
770 struct datapath *dp; 755 struct datapath *dp;
771 struct sw_flow_actions *acts = NULL; 756 struct sw_flow_actions *acts = NULL;
772 struct sw_flow_match match; 757 struct sw_flow_match match;
758 bool exact_5tuple;
773 int error; 759 int error;
774 760
775 /* Extract key. */ 761 /* Extract key. */
@@ -778,7 +764,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
778 goto error; 764 goto error;
779 765
780 ovs_match_init(&match, &key, &mask); 766 ovs_match_init(&match, &key, &mask);
781 error = ovs_nla_get_match(&match, 767 error = ovs_nla_get_match(&match, &exact_5tuple,
782 a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]); 768 a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]);
783 if (error) 769 if (error)
784 goto error; 770 goto error;
@@ -817,12 +803,11 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
817 goto err_unlock_ovs; 803 goto err_unlock_ovs;
818 804
819 /* Allocate flow. */ 805 /* Allocate flow. */
820 flow = ovs_flow_alloc(); 806 flow = ovs_flow_alloc(!exact_5tuple);
821 if (IS_ERR(flow)) { 807 if (IS_ERR(flow)) {
822 error = PTR_ERR(flow); 808 error = PTR_ERR(flow);
823 goto err_unlock_ovs; 809 goto err_unlock_ovs;
824 } 810 }
825 clear_stats(flow);
826 811
827 flow->key = masked_key; 812 flow->key = masked_key;
828 flow->unmasked_key = key; 813 flow->unmasked_key = key;
@@ -866,11 +851,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
866 reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW); 851 reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
867 852
868 /* Clear stats. */ 853 /* Clear stats. */
869 if (a[OVS_FLOW_ATTR_CLEAR]) { 854 if (a[OVS_FLOW_ATTR_CLEAR])
870 spin_lock_bh(&flow->lock); 855 ovs_flow_stats_clear(flow);
871 clear_stats(flow);
872 spin_unlock_bh(&flow->lock);
873 }
874 } 856 }
875 ovs_unlock(); 857 ovs_unlock();
876 858
@@ -908,7 +890,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
908 } 890 }
909 891
910 ovs_match_init(&match, &key, NULL); 892 ovs_match_init(&match, &key, NULL);
911 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL); 893 err = ovs_nla_get_match(&match, NULL, a[OVS_FLOW_ATTR_KEY], NULL);
912 if (err) 894 if (err)
913 return err; 895 return err;
914 896
@@ -962,7 +944,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
962 } 944 }
963 945
964 ovs_match_init(&match, &key, NULL); 946 ovs_match_init(&match, &key, NULL);
965 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL); 947 err = ovs_nla_get_match(&match, NULL, a[OVS_FLOW_ATTR_KEY], NULL);
966 if (err) 948 if (err)
967 goto unlock; 949 goto unlock;
968 950