aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
authorAnsis Atteka <aatteka@nicira.com>2012-11-26 14:24:11 -0500
committerJesse Gross <jesse@nicira.com>2012-11-26 14:33:18 -0500
commit39c7caebc94e851f58b84b54659156dd30522e8e (patch)
treeeacef2a7255d4e047c8e5d1a0d69041e4a71cf80 /net/openvswitch
parent404f2f1019c0293bd91dc1c03c8557ec97d9d104 (diff)
openvswitch: add skb mark matching and set action
This patch adds support for skb mark matching and set action. Signed-off-by: Ansis Atteka <aatteka@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/actions.c4
-rw-r--r--net/openvswitch/datapath.c3
-rw-r--r--net/openvswitch/flow.c19
-rw-r--r--net/openvswitch/flow.h8
4 files changed, 30 insertions, 4 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index a58ed276f70d..ac2defeeba83 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -428,6 +428,10 @@ static int execute_set_action(struct sk_buff *skb,
428 skb->priority = nla_get_u32(nested_attr); 428 skb->priority = nla_get_u32(nested_attr);
429 break; 429 break;
430 430
431 case OVS_KEY_ATTR_SKB_MARK:
432 skb->mark = nla_get_u32(nested_attr);
433 break;
434
431 case OVS_KEY_ATTR_ETHERNET: 435 case OVS_KEY_ATTR_ETHERNET:
432 err = set_eth_addr(skb, nla_data(nested_attr)); 436 err = set_eth_addr(skb, nla_data(nested_attr));
433 break; 437 break;
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 7b1d6d2b0c1a..f996db343247 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -482,6 +482,7 @@ static int validate_set(const struct nlattr *a,
482 const struct ovs_key_ipv6 *ipv6_key; 482 const struct ovs_key_ipv6 *ipv6_key;
483 483
484 case OVS_KEY_ATTR_PRIORITY: 484 case OVS_KEY_ATTR_PRIORITY:
485 case OVS_KEY_ATTR_SKB_MARK:
485 case OVS_KEY_ATTR_ETHERNET: 486 case OVS_KEY_ATTR_ETHERNET:
486 break; 487 break;
487 488
@@ -695,6 +696,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
695 goto err_flow_free; 696 goto err_flow_free;
696 697
697 err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority, 698 err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority,
699 &flow->key.phy.skb_mark,
698 &flow->key.phy.in_port, 700 &flow->key.phy.in_port,
699 a[OVS_PACKET_ATTR_KEY]); 701 a[OVS_PACKET_ATTR_KEY]);
700 if (err) 702 if (err)
@@ -714,6 +716,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
714 716
715 OVS_CB(packet)->flow = flow; 717 OVS_CB(packet)->flow = flow;
716 packet->priority = flow->key.phy.priority; 718 packet->priority = flow->key.phy.priority;
719 packet->mark = flow->key.phy.skb_mark;
717 720
718 rcu_read_lock(); 721 rcu_read_lock();
719 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); 722 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index e6ce902e92e5..c3294cebc4f2 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -604,6 +604,7 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
604 604
605 key->phy.priority = skb->priority; 605 key->phy.priority = skb->priority;
606 key->phy.in_port = in_port; 606 key->phy.in_port = in_port;
607 key->phy.skb_mark = skb->mark;
607 608
608 skb_reset_mac_header(skb); 609 skb_reset_mac_header(skb);
609 610
@@ -803,6 +804,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
803 [OVS_KEY_ATTR_ENCAP] = -1, 804 [OVS_KEY_ATTR_ENCAP] = -1,
804 [OVS_KEY_ATTR_PRIORITY] = sizeof(u32), 805 [OVS_KEY_ATTR_PRIORITY] = sizeof(u32),
805 [OVS_KEY_ATTR_IN_PORT] = sizeof(u32), 806 [OVS_KEY_ATTR_IN_PORT] = sizeof(u32),
807 [OVS_KEY_ATTR_SKB_MARK] = sizeof(u32),
806 [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet), 808 [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet),
807 [OVS_KEY_ATTR_VLAN] = sizeof(__be16), 809 [OVS_KEY_ATTR_VLAN] = sizeof(__be16),
808 [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16), 810 [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16),
@@ -988,6 +990,10 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
988 } else { 990 } else {
989 swkey->phy.in_port = DP_MAX_PORTS; 991 swkey->phy.in_port = DP_MAX_PORTS;
990 } 992 }
993 if (attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) {
994 swkey->phy.skb_mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]);
995 attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
996 }
991 997
992 /* Data attributes. */ 998 /* Data attributes. */
993 if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET))) 999 if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET)))
@@ -1115,6 +1121,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
1115 1121
1116/** 1122/**
1117 * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key. 1123 * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key.
1124 * @priority: receives the skb priority
1125 * @mark: receives the skb mark
1118 * @in_port: receives the extracted input port. 1126 * @in_port: receives the extracted input port.
1119 * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute 1127 * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
1120 * sequence. 1128 * sequence.
@@ -1124,7 +1132,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
1124 * get the metadata, that is, the parts of the flow key that cannot be 1132 * get the metadata, that is, the parts of the flow key that cannot be
1125 * extracted from the packet itself. 1133 * extracted from the packet itself.
1126 */ 1134 */
1127int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, 1135int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
1128 const struct nlattr *attr) 1136 const struct nlattr *attr)
1129{ 1137{
1130 const struct nlattr *nla; 1138 const struct nlattr *nla;
@@ -1132,6 +1140,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
1132 1140
1133 *in_port = DP_MAX_PORTS; 1141 *in_port = DP_MAX_PORTS;
1134 *priority = 0; 1142 *priority = 0;
1143 *mark = 0;
1135 1144
1136 nla_for_each_nested(nla, attr, rem) { 1145 nla_for_each_nested(nla, attr, rem) {
1137 int type = nla_type(nla); 1146 int type = nla_type(nla);
@@ -1150,6 +1159,10 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
1150 return -EINVAL; 1159 return -EINVAL;
1151 *in_port = nla_get_u32(nla); 1160 *in_port = nla_get_u32(nla);
1152 break; 1161 break;
1162
1163 case OVS_KEY_ATTR_SKB_MARK:
1164 *mark = nla_get_u32(nla);
1165 break;
1153 } 1166 }
1154 } 1167 }
1155 } 1168 }
@@ -1171,6 +1184,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
1171 nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) 1184 nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port))
1172 goto nla_put_failure; 1185 goto nla_put_failure;
1173 1186
1187 if (swkey->phy.skb_mark &&
1188 nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, swkey->phy.skb_mark))
1189 goto nla_put_failure;
1190
1174 nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); 1191 nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));
1175 if (!nla) 1192 if (!nla)
1176 goto nla_put_failure; 1193 goto nla_put_failure;
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 14a324eb017b..a7bb60ff3b5b 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -43,6 +43,7 @@ struct sw_flow_actions {
43struct sw_flow_key { 43struct sw_flow_key {
44 struct { 44 struct {
45 u32 priority; /* Packet QoS priority. */ 45 u32 priority; /* Packet QoS priority. */
46 u32 skb_mark; /* SKB mark. */
46 u16 in_port; /* Input switch port (or DP_MAX_PORTS). */ 47 u16 in_port; /* Input switch port (or DP_MAX_PORTS). */
47 } phy; 48 } phy;
48 struct { 49 struct {
@@ -144,6 +145,7 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
144 * ------ --- ------ ----- 145 * ------ --- ------ -----
145 * OVS_KEY_ATTR_PRIORITY 4 -- 4 8 146 * OVS_KEY_ATTR_PRIORITY 4 -- 4 8
146 * OVS_KEY_ATTR_IN_PORT 4 -- 4 8 147 * OVS_KEY_ATTR_IN_PORT 4 -- 4 8
148 * OVS_KEY_ATTR_SKB_MARK 4 -- 4 8
147 * OVS_KEY_ATTR_ETHERNET 12 -- 4 16 149 * OVS_KEY_ATTR_ETHERNET 12 -- 4 16
148 * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype) 150 * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype)
149 * OVS_KEY_ATTR_8021Q 4 -- 4 8 151 * OVS_KEY_ATTR_8021Q 4 -- 4 8
@@ -153,14 +155,14 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
153 * OVS_KEY_ATTR_ICMPV6 2 2 4 8 155 * OVS_KEY_ATTR_ICMPV6 2 2 4 8
154 * OVS_KEY_ATTR_ND 28 -- 4 32 156 * OVS_KEY_ATTR_ND 28 -- 4 32
155 * ------------------------------------------------- 157 * -------------------------------------------------
156 * total 144 158 * total 152
157 */ 159 */
158#define FLOW_BUFSIZE 144 160#define FLOW_BUFSIZE 152
159 161
160int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); 162int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
161int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, 163int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
162 const struct nlattr *); 164 const struct nlattr *);
163int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, 165int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
164 const struct nlattr *); 166 const struct nlattr *);
165 167
166#define MAX_ACTIONS_BUFSIZE (16 * 1024) 168#define MAX_ACTIONS_BUFSIZE (16 * 1024)