提交 39c7caeb 编写于 作者: A Ansis Atteka 提交者: Jesse Gross

openvswitch: add skb mark matching and set action

This patch adds support for skb mark matching and set action.
Signed-off-by: NAnsis Atteka <aatteka@nicira.com>
Signed-off-by: NJesse Gross <jesse@nicira.com>
上级 404f2f10
...@@ -243,6 +243,7 @@ enum ovs_key_attr { ...@@ -243,6 +243,7 @@ enum ovs_key_attr {
OVS_KEY_ATTR_ICMPV6, /* struct ovs_key_icmpv6 */ OVS_KEY_ATTR_ICMPV6, /* struct ovs_key_icmpv6 */
OVS_KEY_ATTR_ARP, /* struct ovs_key_arp */ OVS_KEY_ATTR_ARP, /* struct ovs_key_arp */
OVS_KEY_ATTR_ND, /* struct ovs_key_nd */ OVS_KEY_ATTR_ND, /* struct ovs_key_nd */
OVS_KEY_ATTR_SKB_MARK, /* u32 skb mark */
__OVS_KEY_ATTR_MAX __OVS_KEY_ATTR_MAX
}; };
......
...@@ -428,6 +428,10 @@ static int execute_set_action(struct sk_buff *skb, ...@@ -428,6 +428,10 @@ static int execute_set_action(struct sk_buff *skb,
skb->priority = nla_get_u32(nested_attr); skb->priority = nla_get_u32(nested_attr);
break; break;
case OVS_KEY_ATTR_SKB_MARK:
skb->mark = nla_get_u32(nested_attr);
break;
case OVS_KEY_ATTR_ETHERNET: case OVS_KEY_ATTR_ETHERNET:
err = set_eth_addr(skb, nla_data(nested_attr)); err = set_eth_addr(skb, nla_data(nested_attr));
break; break;
......
...@@ -482,6 +482,7 @@ static int validate_set(const struct nlattr *a, ...@@ -482,6 +482,7 @@ static int validate_set(const struct nlattr *a,
const struct ovs_key_ipv6 *ipv6_key; const struct ovs_key_ipv6 *ipv6_key;
case OVS_KEY_ATTR_PRIORITY: case OVS_KEY_ATTR_PRIORITY:
case OVS_KEY_ATTR_SKB_MARK:
case OVS_KEY_ATTR_ETHERNET: case OVS_KEY_ATTR_ETHERNET:
break; break;
...@@ -695,6 +696,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) ...@@ -695,6 +696,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
goto err_flow_free; goto err_flow_free;
err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority, err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority,
&flow->key.phy.skb_mark,
&flow->key.phy.in_port, &flow->key.phy.in_port,
a[OVS_PACKET_ATTR_KEY]); a[OVS_PACKET_ATTR_KEY]);
if (err) if (err)
...@@ -714,6 +716,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) ...@@ -714,6 +716,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
OVS_CB(packet)->flow = flow; OVS_CB(packet)->flow = flow;
packet->priority = flow->key.phy.priority; packet->priority = flow->key.phy.priority;
packet->mark = flow->key.phy.skb_mark;
rcu_read_lock(); rcu_read_lock();
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
......
...@@ -604,6 +604,7 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, ...@@ -604,6 +604,7 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
key->phy.priority = skb->priority; key->phy.priority = skb->priority;
key->phy.in_port = in_port; key->phy.in_port = in_port;
key->phy.skb_mark = skb->mark;
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
...@@ -803,6 +804,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = { ...@@ -803,6 +804,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
[OVS_KEY_ATTR_ENCAP] = -1, [OVS_KEY_ATTR_ENCAP] = -1,
[OVS_KEY_ATTR_PRIORITY] = sizeof(u32), [OVS_KEY_ATTR_PRIORITY] = sizeof(u32),
[OVS_KEY_ATTR_IN_PORT] = sizeof(u32), [OVS_KEY_ATTR_IN_PORT] = sizeof(u32),
[OVS_KEY_ATTR_SKB_MARK] = sizeof(u32),
[OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet), [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet),
[OVS_KEY_ATTR_VLAN] = sizeof(__be16), [OVS_KEY_ATTR_VLAN] = sizeof(__be16),
[OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16), [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16),
...@@ -988,6 +990,10 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, ...@@ -988,6 +990,10 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
} else { } else {
swkey->phy.in_port = DP_MAX_PORTS; swkey->phy.in_port = DP_MAX_PORTS;
} }
if (attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) {
swkey->phy.skb_mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]);
attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
}
/* Data attributes. */ /* Data attributes. */
if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET))) 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,6 +1121,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
/** /**
* ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key. * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key.
* @priority: receives the skb priority
* @mark: receives the skb mark
* @in_port: receives the extracted input port. * @in_port: receives the extracted input port.
* @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
* sequence. * sequence.
...@@ -1124,7 +1132,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, ...@@ -1124,7 +1132,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
* get the metadata, that is, the parts of the flow key that cannot be * get the metadata, that is, the parts of the flow key that cannot be
* extracted from the packet itself. * extracted from the packet itself.
*/ */
int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
const struct nlattr *attr) const struct nlattr *attr)
{ {
const struct nlattr *nla; const struct nlattr *nla;
...@@ -1132,6 +1140,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, ...@@ -1132,6 +1140,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
*in_port = DP_MAX_PORTS; *in_port = DP_MAX_PORTS;
*priority = 0; *priority = 0;
*mark = 0;
nla_for_each_nested(nla, attr, rem) { nla_for_each_nested(nla, attr, rem) {
int type = nla_type(nla); int type = nla_type(nla);
...@@ -1150,6 +1159,10 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, ...@@ -1150,6 +1159,10 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
return -EINVAL; return -EINVAL;
*in_port = nla_get_u32(nla); *in_port = nla_get_u32(nla);
break; break;
case OVS_KEY_ATTR_SKB_MARK:
*mark = nla_get_u32(nla);
break;
} }
} }
} }
...@@ -1171,6 +1184,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) ...@@ -1171,6 +1184,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port))
goto nla_put_failure; goto nla_put_failure;
if (swkey->phy.skb_mark &&
nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, swkey->phy.skb_mark))
goto nla_put_failure;
nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));
if (!nla) if (!nla)
goto nla_put_failure; goto nla_put_failure;
......
...@@ -43,6 +43,7 @@ struct sw_flow_actions { ...@@ -43,6 +43,7 @@ struct sw_flow_actions {
struct sw_flow_key { struct sw_flow_key {
struct { struct {
u32 priority; /* Packet QoS priority. */ u32 priority; /* Packet QoS priority. */
u32 skb_mark; /* SKB mark. */
u16 in_port; /* Input switch port (or DP_MAX_PORTS). */ u16 in_port; /* Input switch port (or DP_MAX_PORTS). */
} phy; } phy;
struct { struct {
...@@ -144,6 +145,7 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies); ...@@ -144,6 +145,7 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
* ------ --- ------ ----- * ------ --- ------ -----
* OVS_KEY_ATTR_PRIORITY 4 -- 4 8 * OVS_KEY_ATTR_PRIORITY 4 -- 4 8
* OVS_KEY_ATTR_IN_PORT 4 -- 4 8 * OVS_KEY_ATTR_IN_PORT 4 -- 4 8
* OVS_KEY_ATTR_SKB_MARK 4 -- 4 8
* OVS_KEY_ATTR_ETHERNET 12 -- 4 16 * OVS_KEY_ATTR_ETHERNET 12 -- 4 16
* OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype) * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype)
* OVS_KEY_ATTR_8021Q 4 -- 4 8 * OVS_KEY_ATTR_8021Q 4 -- 4 8
...@@ -153,14 +155,14 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies); ...@@ -153,14 +155,14 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
* OVS_KEY_ATTR_ICMPV6 2 2 4 8 * OVS_KEY_ATTR_ICMPV6 2 2 4 8
* OVS_KEY_ATTR_ND 28 -- 4 32 * OVS_KEY_ATTR_ND 28 -- 4 32
* ------------------------------------------------- * -------------------------------------------------
* total 144 * total 152
*/ */
#define FLOW_BUFSIZE 144 #define FLOW_BUFSIZE 152
int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
const struct nlattr *); const struct nlattr *);
int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
const struct nlattr *); const struct nlattr *);
#define MAX_ACTIONS_BUFSIZE (16 * 1024) #define MAX_ACTIONS_BUFSIZE (16 * 1024)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册