aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow_netlink.c
diff options
context:
space:
mode:
authorAndy Zhou <azhou@nicira.com>2014-09-15 22:37:25 -0400
committerPravin B Shelar <pshelar@nicira.com>2014-09-16 02:28:14 -0400
commit971427f353f3c42c8dcef62e7124440df68eb809 (patch)
tree7eed9ed50fe70cfc82ce33e12a13147ad0de580c /net/openvswitch/flow_netlink.c
parent32ae87ff795781b7ceffc44b7c694c1bb206a266 (diff)
openvswitch: Add recirc and hash action.
Recirc action allows a packet to reenter openvswitch processing. currently openvswitch lookup flow for packet received and execute set of actions on that packet, with help of recirc action we can process/modify the packet and recirculate it back in openvswitch for another pass. OVS hash action calculates 5-tupple hash and set hash in flow-key hash. This can be used along with recirculation for distributing packets among different ports for bond devices. For example: OVS bonding can use following actions: Match on: bond flow; Action: hash, recirc(id) Match on: recirc-id == id and hash lower bits == a; Action: output port_bond_a Signed-off-by: Andy Zhou <azhou@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r--net/openvswitch/flow_netlink.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 630b320fbf3e..f4c8daa73965 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2013 Nicira, Inc. 2 * Copyright (c) 2007-2014 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public 5 * modify it under the terms of version 2 of the GNU General Public
@@ -251,6 +251,8 @@ static const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
251 [OVS_KEY_ATTR_ICMPV6] = sizeof(struct ovs_key_icmpv6), 251 [OVS_KEY_ATTR_ICMPV6] = sizeof(struct ovs_key_icmpv6),
252 [OVS_KEY_ATTR_ARP] = sizeof(struct ovs_key_arp), 252 [OVS_KEY_ATTR_ARP] = sizeof(struct ovs_key_arp),
253 [OVS_KEY_ATTR_ND] = sizeof(struct ovs_key_nd), 253 [OVS_KEY_ATTR_ND] = sizeof(struct ovs_key_nd),
254 [OVS_KEY_ATTR_RECIRC_ID] = sizeof(u32),
255 [OVS_KEY_ATTR_DP_HASH] = sizeof(u32),
254 [OVS_KEY_ATTR_TUNNEL] = -1, 256 [OVS_KEY_ATTR_TUNNEL] = -1,
255}; 257};
256 258
@@ -454,6 +456,20 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
454static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, 456static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs,
455 const struct nlattr **a, bool is_mask) 457 const struct nlattr **a, bool is_mask)
456{ 458{
459 if (*attrs & (1 << OVS_KEY_ATTR_DP_HASH)) {
460 u32 hash_val = nla_get_u32(a[OVS_KEY_ATTR_DP_HASH]);
461
462 SW_FLOW_KEY_PUT(match, ovs_flow_hash, hash_val, is_mask);
463 *attrs &= ~(1 << OVS_KEY_ATTR_DP_HASH);
464 }
465
466 if (*attrs & (1 << OVS_KEY_ATTR_RECIRC_ID)) {
467 u32 recirc_id = nla_get_u32(a[OVS_KEY_ATTR_RECIRC_ID]);
468
469 SW_FLOW_KEY_PUT(match, recirc_id, recirc_id, is_mask);
470 *attrs &= ~(1 << OVS_KEY_ATTR_RECIRC_ID);
471 }
472
457 if (*attrs & (1 << OVS_KEY_ATTR_PRIORITY)) { 473 if (*attrs & (1 << OVS_KEY_ATTR_PRIORITY)) {
458 SW_FLOW_KEY_PUT(match, phy.priority, 474 SW_FLOW_KEY_PUT(match, phy.priority,
459 nla_get_u32(a[OVS_KEY_ATTR_PRIORITY]), is_mask); 475 nla_get_u32(a[OVS_KEY_ATTR_PRIORITY]), is_mask);
@@ -873,6 +889,12 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey,
873 struct nlattr *nla, *encap; 889 struct nlattr *nla, *encap;
874 bool is_mask = (swkey != output); 890 bool is_mask = (swkey != output);
875 891
892 if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id))
893 goto nla_put_failure;
894
895 if (nla_put_u32(skb, OVS_KEY_ATTR_DP_HASH, output->ovs_flow_hash))
896 goto nla_put_failure;
897
876 if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority)) 898 if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority))
877 goto nla_put_failure; 899 goto nla_put_failure;
878 900
@@ -1401,11 +1423,13 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
1401 /* Expected argument lengths, (u32)-1 for variable length. */ 1423 /* Expected argument lengths, (u32)-1 for variable length. */
1402 static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = { 1424 static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = {
1403 [OVS_ACTION_ATTR_OUTPUT] = sizeof(u32), 1425 [OVS_ACTION_ATTR_OUTPUT] = sizeof(u32),
1426 [OVS_ACTION_ATTR_RECIRC] = sizeof(u32),
1404 [OVS_ACTION_ATTR_USERSPACE] = (u32)-1, 1427 [OVS_ACTION_ATTR_USERSPACE] = (u32)-1,
1405 [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan), 1428 [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan),
1406 [OVS_ACTION_ATTR_POP_VLAN] = 0, 1429 [OVS_ACTION_ATTR_POP_VLAN] = 0,
1407 [OVS_ACTION_ATTR_SET] = (u32)-1, 1430 [OVS_ACTION_ATTR_SET] = (u32)-1,
1408 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1 1431 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
1432 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash)
1409 }; 1433 };
1410 const struct ovs_action_push_vlan *vlan; 1434 const struct ovs_action_push_vlan *vlan;
1411 int type = nla_type(a); 1435 int type = nla_type(a);
@@ -1432,6 +1456,18 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
1432 return -EINVAL; 1456 return -EINVAL;
1433 break; 1457 break;
1434 1458
1459 case OVS_ACTION_ATTR_HASH: {
1460 const struct ovs_action_hash *act_hash = nla_data(a);
1461
1462 switch (act_hash->hash_alg) {
1463 case OVS_HASH_ALG_L4:
1464 break;
1465 default:
1466 return -EINVAL;
1467 }
1468
1469 break;
1470 }
1435 1471
1436 case OVS_ACTION_ATTR_POP_VLAN: 1472 case OVS_ACTION_ATTR_POP_VLAN:
1437 break; 1473 break;
@@ -1444,6 +1480,9 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
1444 return -EINVAL; 1480 return -EINVAL;
1445 break; 1481 break;
1446 1482
1483 case OVS_ACTION_ATTR_RECIRC:
1484 break;
1485
1447 case OVS_ACTION_ATTR_SET: 1486 case OVS_ACTION_ATTR_SET:
1448 err = validate_set(a, key, sfa, &skip_copy); 1487 err = validate_set(a, key, sfa, &skip_copy);
1449 if (err) 1488 if (err)