diff options
| author | Joe Stringer <joestringer@nicira.com> | 2014-09-08 16:09:37 -0400 |
|---|---|---|
| committer | Pravin B Shelar <pshelar@nicira.com> | 2014-11-06 02:52:34 -0500 |
| commit | ca7105f278b3f7bd2c6f2b336c928f679054de4d (patch) | |
| tree | 2ebb11ba2d8890820e4e66d1ae6d25cf5a5bf3f3 /net/openvswitch | |
| parent | 738967b8bf57e582db1a23ce773c36fefd4b7d37 (diff) | |
openvswitch: Refactor ovs_flow_cmd_fill_info().
Split up ovs_flow_cmd_fill_info() to make it easier to cache parts of a
dump reply. This will be used to streamline flow_dump in a future patch.
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Thomas Graf <tgraf@noironetworks.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'net/openvswitch')
| -rw-r--r-- | net/openvswitch/datapath.c | 93 |
1 files changed, 66 insertions, 27 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 04a26ae4a4f6..bbb920bf48da 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -674,58 +674,67 @@ static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts) | |||
| 674 | } | 674 | } |
| 675 | 675 | ||
| 676 | /* Called with ovs_mutex or RCU read lock. */ | 676 | /* Called with ovs_mutex or RCU read lock. */ |
| 677 | static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex, | 677 | static int ovs_flow_cmd_fill_match(const struct sw_flow *flow, |
| 678 | struct sk_buff *skb, u32 portid, | 678 | struct sk_buff *skb) |
| 679 | u32 seq, u32 flags, u8 cmd) | ||
| 680 | { | 679 | { |
| 681 | const int skb_orig_len = skb->len; | ||
| 682 | struct nlattr *start; | ||
| 683 | struct ovs_flow_stats stats; | ||
| 684 | __be16 tcp_flags; | ||
| 685 | unsigned long used; | ||
| 686 | struct ovs_header *ovs_header; | ||
| 687 | struct nlattr *nla; | 680 | struct nlattr *nla; |
| 688 | int err; | 681 | int err; |
| 689 | 682 | ||
| 690 | ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, cmd); | ||
| 691 | if (!ovs_header) | ||
| 692 | return -EMSGSIZE; | ||
| 693 | |||
| 694 | ovs_header->dp_ifindex = dp_ifindex; | ||
| 695 | |||
| 696 | /* Fill flow key. */ | 683 | /* Fill flow key. */ |
| 697 | nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY); | 684 | nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY); |
| 698 | if (!nla) | 685 | if (!nla) |
| 699 | goto nla_put_failure; | 686 | return -EMSGSIZE; |
| 700 | 687 | ||
| 701 | err = ovs_nla_put_flow(&flow->unmasked_key, &flow->unmasked_key, skb); | 688 | err = ovs_nla_put_flow(&flow->unmasked_key, &flow->unmasked_key, skb); |
| 702 | if (err) | 689 | if (err) |
| 703 | goto error; | 690 | return err; |
| 691 | |||
| 704 | nla_nest_end(skb, nla); | 692 | nla_nest_end(skb, nla); |
| 705 | 693 | ||
| 694 | /* Fill flow mask. */ | ||
| 706 | nla = nla_nest_start(skb, OVS_FLOW_ATTR_MASK); | 695 | nla = nla_nest_start(skb, OVS_FLOW_ATTR_MASK); |
| 707 | if (!nla) | 696 | if (!nla) |
| 708 | goto nla_put_failure; | 697 | return -EMSGSIZE; |
| 709 | 698 | ||
| 710 | err = ovs_nla_put_flow(&flow->key, &flow->mask->key, skb); | 699 | err = ovs_nla_put_flow(&flow->key, &flow->mask->key, skb); |
| 711 | if (err) | 700 | if (err) |
| 712 | goto error; | 701 | return err; |
| 713 | 702 | ||
| 714 | nla_nest_end(skb, nla); | 703 | nla_nest_end(skb, nla); |
| 704 | return 0; | ||
| 705 | } | ||
| 706 | |||
| 707 | /* Called with ovs_mutex or RCU read lock. */ | ||
| 708 | static int ovs_flow_cmd_fill_stats(const struct sw_flow *flow, | ||
| 709 | struct sk_buff *skb) | ||
| 710 | { | ||
| 711 | struct ovs_flow_stats stats; | ||
| 712 | __be16 tcp_flags; | ||
| 713 | unsigned long used; | ||
| 715 | 714 | ||
| 716 | ovs_flow_stats_get(flow, &stats, &used, &tcp_flags); | 715 | ovs_flow_stats_get(flow, &stats, &used, &tcp_flags); |
| 717 | 716 | ||
| 718 | if (used && | 717 | if (used && |
| 719 | nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used))) | 718 | nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used))) |
| 720 | goto nla_put_failure; | 719 | return -EMSGSIZE; |
| 721 | 720 | ||
| 722 | if (stats.n_packets && | 721 | if (stats.n_packets && |
| 723 | nla_put(skb, OVS_FLOW_ATTR_STATS, sizeof(struct ovs_flow_stats), &stats)) | 722 | nla_put(skb, OVS_FLOW_ATTR_STATS, sizeof(struct ovs_flow_stats), &stats)) |
| 724 | goto nla_put_failure; | 723 | return -EMSGSIZE; |
| 725 | 724 | ||
| 726 | if ((u8)ntohs(tcp_flags) && | 725 | if ((u8)ntohs(tcp_flags) && |
| 727 | nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, (u8)ntohs(tcp_flags))) | 726 | nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, (u8)ntohs(tcp_flags))) |
| 728 | goto nla_put_failure; | 727 | return -EMSGSIZE; |
| 728 | |||
| 729 | return 0; | ||
| 730 | } | ||
| 731 | |||
| 732 | /* Called with ovs_mutex or RCU read lock. */ | ||
| 733 | static int ovs_flow_cmd_fill_actions(const struct sw_flow *flow, | ||
| 734 | struct sk_buff *skb, int skb_orig_len) | ||
| 735 | { | ||
| 736 | struct nlattr *start; | ||
| 737 | int err; | ||
| 729 | 738 | ||
| 730 | /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if | 739 | /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if |
| 731 | * this is the first flow to be dumped into 'skb'. This is unusual for | 740 | * this is the first flow to be dumped into 'skb'. This is unusual for |
| @@ -749,17 +758,47 @@ static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex, | |||
| 749 | nla_nest_end(skb, start); | 758 | nla_nest_end(skb, start); |
| 750 | else { | 759 | else { |
| 751 | if (skb_orig_len) | 760 | if (skb_orig_len) |
| 752 | goto error; | 761 | return err; |
| 753 | 762 | ||
| 754 | nla_nest_cancel(skb, start); | 763 | nla_nest_cancel(skb, start); |
| 755 | } | 764 | } |
| 756 | } else if (skb_orig_len) | 765 | } else if (skb_orig_len) { |
| 757 | goto nla_put_failure; | 766 | return -EMSGSIZE; |
| 767 | } | ||
| 768 | |||
| 769 | return 0; | ||
| 770 | } | ||
| 771 | |||
| 772 | /* Called with ovs_mutex or RCU read lock. */ | ||
| 773 | static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex, | ||
| 774 | struct sk_buff *skb, u32 portid, | ||
| 775 | u32 seq, u32 flags, u8 cmd) | ||
| 776 | { | ||
| 777 | const int skb_orig_len = skb->len; | ||
| 778 | struct ovs_header *ovs_header; | ||
| 779 | int err; | ||
| 780 | |||
| 781 | ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, | ||
| 782 | flags, cmd); | ||
| 783 | if (!ovs_header) | ||
| 784 | return -EMSGSIZE; | ||
| 785 | |||
| 786 | ovs_header->dp_ifindex = dp_ifindex; | ||
| 787 | |||
| 788 | err = ovs_flow_cmd_fill_match(flow, skb); | ||
| 789 | if (err) | ||
| 790 | goto error; | ||
| 791 | |||
| 792 | err = ovs_flow_cmd_fill_stats(flow, skb); | ||
| 793 | if (err) | ||
| 794 | goto error; | ||
| 795 | |||
| 796 | err = ovs_flow_cmd_fill_actions(flow, skb, skb_orig_len); | ||
| 797 | if (err) | ||
| 798 | goto error; | ||
| 758 | 799 | ||
| 759 | return genlmsg_end(skb, ovs_header); | 800 | return genlmsg_end(skb, ovs_header); |
| 760 | 801 | ||
| 761 | nla_put_failure: | ||
| 762 | err = -EMSGSIZE; | ||
| 763 | error: | 802 | error: |
| 764 | genlmsg_cancel(skb, ovs_header); | 803 | genlmsg_cancel(skb, ovs_header); |
| 765 | return err; | 804 | return err; |
