aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
authorJoe Stringer <joestringer@nicira.com>2015-08-26 14:31:52 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-27 14:40:43 -0400
commitc2ac667358708d7cce64c78f58af6adf4c1e848b (patch)
treef24ccd3b0e54fe0ba09ecadb837eef3ecaa014c8 /net/openvswitch/datapath.c
parent86ca02e77408bb58ba596c1a411ec7f631733690 (diff)
openvswitch: Allow matching on conntrack label
Allow matching and setting the ct_label field. As with ct_mark, this is populated by executing the CT action. The label field may be modified by specifying a label and mask nested under the CT action. It is stored as metadata attached to the connection. Label modification occurs after lookup, and will only persist when the conntrack entry is committed by providing the COMMIT flag to the CT action. Labels are currently fixed to 128 bits in size. Signed-off-by: Joe Stringer <joestringer@nicira.com> Acked-by: Thomas Graf <tgraf@suug.ch> Acked-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 72e63726efa0..ec0f8d9cee73 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -599,8 +599,8 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
599 if (IS_ERR(flow)) 599 if (IS_ERR(flow))
600 goto err_kfree_skb; 600 goto err_kfree_skb;
601 601
602 err = ovs_flow_key_extract_userspace(a[OVS_PACKET_ATTR_KEY], packet, 602 err = ovs_flow_key_extract_userspace(net, a[OVS_PACKET_ATTR_KEY],
603 &flow->key, log); 603 packet, &flow->key, log);
604 if (err) 604 if (err)
605 goto err_flow_free; 605 goto err_flow_free;
606 606
@@ -947,7 +947,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
947 947
948 /* Extract key. */ 948 /* Extract key. */
949 ovs_match_init(&match, &key, &mask); 949 ovs_match_init(&match, &key, &mask);
950 error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], 950 error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
951 a[OVS_FLOW_ATTR_MASK], log); 951 a[OVS_FLOW_ATTR_MASK], log);
952 if (error) 952 if (error)
953 goto err_kfree_flow; 953 goto err_kfree_flow;
@@ -1118,7 +1118,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1118 1118
1119 ufid_present = ovs_nla_get_ufid(&sfid, a[OVS_FLOW_ATTR_UFID], log); 1119 ufid_present = ovs_nla_get_ufid(&sfid, a[OVS_FLOW_ATTR_UFID], log);
1120 ovs_match_init(&match, &key, &mask); 1120 ovs_match_init(&match, &key, &mask);
1121 error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], 1121 error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
1122 a[OVS_FLOW_ATTR_MASK], log); 1122 a[OVS_FLOW_ATTR_MASK], log);
1123 if (error) 1123 if (error)
1124 goto error; 1124 goto error;
@@ -1208,6 +1208,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
1208{ 1208{
1209 struct nlattr **a = info->attrs; 1209 struct nlattr **a = info->attrs;
1210 struct ovs_header *ovs_header = info->userhdr; 1210 struct ovs_header *ovs_header = info->userhdr;
1211 struct net *net = sock_net(skb->sk);
1211 struct sw_flow_key key; 1212 struct sw_flow_key key;
1212 struct sk_buff *reply; 1213 struct sk_buff *reply;
1213 struct sw_flow *flow; 1214 struct sw_flow *flow;
@@ -1222,7 +1223,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
1222 ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log); 1223 ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
1223 if (a[OVS_FLOW_ATTR_KEY]) { 1224 if (a[OVS_FLOW_ATTR_KEY]) {
1224 ovs_match_init(&match, &key, NULL); 1225 ovs_match_init(&match, &key, NULL);
1225 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, 1226 err = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY], NULL,
1226 log); 1227 log);
1227 } else if (!ufid_present) { 1228 } else if (!ufid_present) {
1228 OVS_NLERR(log, 1229 OVS_NLERR(log,
@@ -1266,6 +1267,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
1266{ 1267{
1267 struct nlattr **a = info->attrs; 1268 struct nlattr **a = info->attrs;
1268 struct ovs_header *ovs_header = info->userhdr; 1269 struct ovs_header *ovs_header = info->userhdr;
1270 struct net *net = sock_net(skb->sk);
1269 struct sw_flow_key key; 1271 struct sw_flow_key key;
1270 struct sk_buff *reply; 1272 struct sk_buff *reply;
1271 struct sw_flow *flow = NULL; 1273 struct sw_flow *flow = NULL;
@@ -1280,8 +1282,8 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
1280 ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log); 1282 ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
1281 if (a[OVS_FLOW_ATTR_KEY]) { 1283 if (a[OVS_FLOW_ATTR_KEY]) {
1282 ovs_match_init(&match, &key, NULL); 1284 ovs_match_init(&match, &key, NULL);
1283 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, 1285 err = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
1284 log); 1286 NULL, log);
1285 if (unlikely(err)) 1287 if (unlikely(err))
1286 return err; 1288 return err;
1287 } 1289 }
@@ -2237,6 +2239,7 @@ static int __net_init ovs_init_net(struct net *net)
2237 2239
2238 INIT_LIST_HEAD(&ovs_net->dps); 2240 INIT_LIST_HEAD(&ovs_net->dps);
2239 INIT_WORK(&ovs_net->dp_notify_work, ovs_dp_notify_wq); 2241 INIT_WORK(&ovs_net->dp_notify_work, ovs_dp_notify_wq);
2242 ovs_ct_init(net);
2240 return 0; 2243 return 0;
2241} 2244}
2242 2245
@@ -2271,6 +2274,7 @@ static void __net_exit ovs_exit_net(struct net *dnet)
2271 struct net *net; 2274 struct net *net;
2272 LIST_HEAD(head); 2275 LIST_HEAD(head);
2273 2276
2277 ovs_ct_exit(dnet);
2274 ovs_lock(); 2278 ovs_lock();
2275 list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node) 2279 list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
2276 __dp_destroy(dp); 2280 __dp_destroy(dp);