diff options
author | Ansis Atteka <aatteka@nicira.com> | 2012-11-26 14:24:11 -0500 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2012-11-26 14:33:18 -0500 |
commit | 39c7caebc94e851f58b84b54659156dd30522e8e (patch) | |
tree | eacef2a7255d4e047c8e5d1a0d69041e4a71cf80 /net/openvswitch | |
parent | 404f2f1019c0293bd91dc1c03c8557ec97d9d104 (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.c | 4 | ||||
-rw-r--r-- | net/openvswitch/datapath.c | 3 | ||||
-rw-r--r-- | net/openvswitch/flow.c | 19 | ||||
-rw-r--r-- | net/openvswitch/flow.h | 8 |
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 | */ |
1127 | int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | 1135 | int 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 { | |||
43 | struct sw_flow_key { | 43 | struct 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 | ||
160 | int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); | 162 | int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); |
161 | int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | 163 | int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, |
162 | const struct nlattr *); | 164 | const struct nlattr *); |
163 | int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | 165 | int 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) |