aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Stringer <joestringer@nicira.com>2015-01-21 19:42:48 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-26 18:45:49 -0500
commit5b4237bbc93b1b54d35b037cfc0ece71cd8e358d (patch)
treea4a7e22a7f0c77b44f48fce7eef3903cf9e5fae1
parent707d79e5cdcf7833d31fea9712f11b185ce25822 (diff)
openvswitch: Refactor ovs_nla_fill_match().
Refactor the ovs_nla_fill_match() function into separate netlink serialization functions ovs_nla_put_{unmasked_key,mask}(). Modify ovs_nla_put_flow() to handle attribute nesting and expose the 'is_mask' parameter - all callers need to nest the flow, and callers have better knowledge about whether it is serializing a mask or not. Signed-off-by: Joe Stringer <joestringer@nicira.com> Acked-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/openvswitch/datapath.c41
-rw-r--r--net/openvswitch/flow_netlink.c38
-rw-r--r--net/openvswitch/flow_netlink.h7
3 files changed, 46 insertions, 40 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index f45f1bf4422c..257b97546b33 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -461,10 +461,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
461 0, upcall_info->cmd); 461 0, upcall_info->cmd);
462 upcall->dp_ifindex = dp_ifindex; 462 upcall->dp_ifindex = dp_ifindex;
463 463
464 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); 464 err = ovs_nla_put_key(key, key, OVS_PACKET_ATTR_KEY, false, user_skb);
465 err = ovs_nla_put_flow(key, key, user_skb);
466 BUG_ON(err); 465 BUG_ON(err);
467 nla_nest_end(user_skb, nla);
468 466
469 if (upcall_info->userdata) 467 if (upcall_info->userdata)
470 __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA, 468 __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA,
@@ -676,37 +674,6 @@ static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts)
676} 674}
677 675
678/* Called with ovs_mutex or RCU read lock. */ 676/* Called with ovs_mutex or RCU read lock. */
679static int ovs_flow_cmd_fill_match(const struct sw_flow *flow,
680 struct sk_buff *skb)
681{
682 struct nlattr *nla;
683 int err;
684
685 /* Fill flow key. */
686 nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY);
687 if (!nla)
688 return -EMSGSIZE;
689
690 err = ovs_nla_put_flow(&flow->unmasked_key, &flow->unmasked_key, skb);
691 if (err)
692 return err;
693
694 nla_nest_end(skb, nla);
695
696 /* Fill flow mask. */
697 nla = nla_nest_start(skb, OVS_FLOW_ATTR_MASK);
698 if (!nla)
699 return -EMSGSIZE;
700
701 err = ovs_nla_put_flow(&flow->key, &flow->mask->key, skb);
702 if (err)
703 return err;
704
705 nla_nest_end(skb, nla);
706 return 0;
707}
708
709/* Called with ovs_mutex or RCU read lock. */
710static int ovs_flow_cmd_fill_stats(const struct sw_flow *flow, 677static int ovs_flow_cmd_fill_stats(const struct sw_flow *flow,
711 struct sk_buff *skb) 678 struct sk_buff *skb)
712{ 679{
@@ -787,7 +754,11 @@ static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex,
787 754
788 ovs_header->dp_ifindex = dp_ifindex; 755 ovs_header->dp_ifindex = dp_ifindex;
789 756
790 err = ovs_flow_cmd_fill_match(flow, skb); 757 err = ovs_nla_put_unmasked_key(flow, skb);
758 if (err)
759 goto error;
760
761 err = ovs_nla_put_mask(flow, skb);
791 if (err) 762 if (err)
792 goto error; 763 goto error;
793 764
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index d210d1be3470..33751f81bfcb 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1216,12 +1216,12 @@ int ovs_nla_get_flow_metadata(const struct nlattr *attr,
1216 return metadata_from_nlattrs(&match, &attrs, a, false, log); 1216 return metadata_from_nlattrs(&match, &attrs, a, false, log);
1217} 1217}
1218 1218
1219int ovs_nla_put_flow(const struct sw_flow_key *swkey, 1219static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1220 const struct sw_flow_key *output, struct sk_buff *skb) 1220 const struct sw_flow_key *output, bool is_mask,
1221 struct sk_buff *skb)
1221{ 1222{
1222 struct ovs_key_ethernet *eth_key; 1223 struct ovs_key_ethernet *eth_key;
1223 struct nlattr *nla, *encap; 1224 struct nlattr *nla, *encap;
1224 bool is_mask = (swkey != output);
1225 1225
1226 if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id)) 1226 if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id))
1227 goto nla_put_failure; 1227 goto nla_put_failure;
@@ -1431,6 +1431,38 @@ nla_put_failure:
1431 return -EMSGSIZE; 1431 return -EMSGSIZE;
1432} 1432}
1433 1433
1434int ovs_nla_put_key(const struct sw_flow_key *swkey,
1435 const struct sw_flow_key *output, int attr, bool is_mask,
1436 struct sk_buff *skb)
1437{
1438 int err;
1439 struct nlattr *nla;
1440
1441 nla = nla_nest_start(skb, attr);
1442 if (!nla)
1443 return -EMSGSIZE;
1444 err = __ovs_nla_put_key(swkey, output, is_mask, skb);
1445 if (err)
1446 return err;
1447 nla_nest_end(skb, nla);
1448
1449 return 0;
1450}
1451
1452/* Called with ovs_mutex or RCU read lock. */
1453int ovs_nla_put_unmasked_key(const struct sw_flow *flow, struct sk_buff *skb)
1454{
1455 return ovs_nla_put_key(&flow->unmasked_key, &flow->unmasked_key,
1456 OVS_FLOW_ATTR_KEY, false, skb);
1457}
1458
1459/* Called with ovs_mutex or RCU read lock. */
1460int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb)
1461{
1462 return ovs_nla_put_key(&flow->key, &flow->mask->key,
1463 OVS_FLOW_ATTR_MASK, true, skb);
1464}
1465
1434#define MAX_ACTIONS_BUFSIZE (32 * 1024) 1466#define MAX_ACTIONS_BUFSIZE (32 * 1024)
1435 1467
1436static struct sw_flow_actions *nla_alloc_flow_actions(int size, bool log) 1468static struct sw_flow_actions *nla_alloc_flow_actions(int size, bool log)
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index 577f12be3459..9ed09e66876a 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -43,11 +43,14 @@ size_t ovs_key_attr_size(void);
43void ovs_match_init(struct sw_flow_match *match, 43void ovs_match_init(struct sw_flow_match *match,
44 struct sw_flow_key *key, struct sw_flow_mask *mask); 44 struct sw_flow_key *key, struct sw_flow_mask *mask);
45 45
46int ovs_nla_put_flow(const struct sw_flow_key *, 46int ovs_nla_put_key(const struct sw_flow_key *, const struct sw_flow_key *,
47 const struct sw_flow_key *, struct sk_buff *); 47 int attr, bool is_mask, struct sk_buff *);
48int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *, 48int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *,
49 bool log); 49 bool log);
50 50
51int ovs_nla_put_unmasked_key(const struct sw_flow *flow, struct sk_buff *skb);
52int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb);
53
51int ovs_nla_get_match(struct sw_flow_match *, const struct nlattr *key, 54int ovs_nla_get_match(struct sw_flow_match *, const struct nlattr *key,
52 const struct nlattr *mask, bool log); 55 const struct nlattr *mask, bool log);
53int ovs_nla_put_egress_tunnel_key(struct sk_buff *, 56int ovs_nla_put_egress_tunnel_key(struct sk_buff *,