2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 22:35:15 +00:00

netdev-offload-tc: Allow installing arp rules to TC dp.

This patch allows to install arp rules to tc dp.
In the future, arp will be offloaded to hardware to
be processed. So OvS enable this now.

$ ovs-appctl dpctl/add-flow 'recirc_id(0),in_port(3),eth(),\
  eth_type(0x0806),arp(op=2,tha=00:50:56:e1:4b:ab,tip=10.255.1.116)' 2

$ ovs-appctl dpctl/dump-flows
  ... arp(tip=10.255.1.116,op=2,tha=00:50:56:e1:4b:ab) ...

$ tc filter show dev <ethx> ingress
  ...
  eth_type arp
  arp_tip 10.255.1.116
  arp_op reply
  arp_tha 00:50:56:e1:4b:ab
  not_in_hw
    action order 1: mirred (Egress Redirect to device <ethy>) stolen
    ...

Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
This commit is contained in:
Tonghao Zhang
2020-06-05 21:17:29 +08:00
committed by Simon Horman
parent 5db012c4ac
commit a3db6e473d
6 changed files with 146 additions and 1 deletions

View File

@@ -197,6 +197,8 @@ void match_set_tp_dst_masked(struct match *, ovs_be16 port, ovs_be16 mask);
void match_set_tcp_flags(struct match *, ovs_be16);
void match_set_tcp_flags_masked(struct match *, ovs_be16 flags, ovs_be16 mask);
void match_set_nw_proto(struct match *, uint8_t);
void match_set_nw_proto_masked(struct match *match,
const uint8_t nw_proto, const uint8_t mask);
void match_set_nw_src(struct match *, ovs_be32);
void match_set_nw_src_masked(struct match *, ovs_be32 ip, ovs_be32 mask);
void match_set_nw_dst(struct match *, ovs_be32);
@@ -210,6 +212,9 @@ void match_set_nw_frag(struct match *, uint8_t nw_frag);
void match_set_nw_frag_masked(struct match *, uint8_t nw_frag, uint8_t mask);
void match_set_icmp_type(struct match *, uint8_t);
void match_set_icmp_code(struct match *, uint8_t);
void match_set_arp_opcode_masked(struct match *match,
const uint8_t opcode,
const uint8_t mask);
void match_set_arp_sha(struct match *, const struct eth_addr);
void match_set_arp_sha_masked(struct match *,
const struct eth_addr arp_sha,
@@ -218,6 +223,12 @@ void match_set_arp_tha(struct match *, const struct eth_addr);
void match_set_arp_tha_masked(struct match *,
const struct eth_addr arp_tha,
const struct eth_addr mask);
void match_set_arp_spa_masked(struct match *match,
const ovs_be32 arp_spa,
const ovs_be32 mask);
void match_set_arp_tpa_masked(struct match *match,
const ovs_be32 arp_tpa,
const ovs_be32 mask);
void match_set_ipv6_src(struct match *, const struct in6_addr *);
void match_set_ipv6_src_masked(struct match *, const struct in6_addr *,
const struct in6_addr *);

View File

@@ -940,6 +940,14 @@ match_set_nw_proto(struct match *match, uint8_t nw_proto)
match->wc.masks.nw_proto = UINT8_MAX;
}
void
match_set_nw_proto_masked(struct match *match,
const uint8_t nw_proto, const uint8_t mask)
{
match->flow.nw_proto = nw_proto;
match->wc.masks.nw_proto = mask;
}
void
match_set_nw_src(struct match *match, ovs_be32 nw_src)
{
@@ -1033,6 +1041,30 @@ match_set_icmp_code(struct match *match, uint8_t icmp_code)
match_set_tp_dst(match, htons(icmp_code));
}
void
match_set_arp_opcode_masked(struct match *match,
const uint8_t opcode,
const uint8_t mask)
{
match_set_nw_proto_masked(match, opcode, mask);
}
void
match_set_arp_spa_masked(struct match *match,
const ovs_be32 arp_spa,
const ovs_be32 mask)
{
match_set_nw_src_masked(match, arp_spa, mask);
}
void
match_set_arp_tpa_masked(struct match *match,
const ovs_be32 arp_tpa,
const ovs_be32 mask)
{
match_set_nw_dst_masked(match, arp_tpa, mask);
}
void
match_set_arp_sha(struct match *match, const struct eth_addr sha)
{

View File

@@ -589,6 +589,14 @@ parse_tc_flower_to_match(struct tc_flower *flower,
match->flow.mpls_lse[0] = key->mpls_lse & mask->mpls_lse;
match->wc.masks.mpls_lse[0] = mask->mpls_lse;
match_set_dl_type(match, key->encap_eth_type[0]);
} else if (key->eth_type == htons(ETH_TYPE_ARP)) {
match_set_arp_sha_masked(match, key->arp.sha, mask->arp.sha);
match_set_arp_tha_masked(match, key->arp.tha, mask->arp.tha);
match_set_arp_spa_masked(match, key->arp.spa, mask->arp.spa);
match_set_arp_tpa_masked(match, key->arp.tpa, mask->arp.tpa);
match_set_arp_opcode_masked(match, key->arp.opcode,
mask->arp.opcode);
match_set_dl_type(match, key->eth_type);
} else {
match_set_dl_type(match, key->eth_type);
}
@@ -1558,6 +1566,25 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
mask->dl_type = 0;
mask->in_port.odp_port = 0;
if (key->dl_type == htons(ETH_P_ARP)) {
flower.key.arp.spa = key->nw_src;
flower.key.arp.tpa = key->nw_dst;
flower.key.arp.sha = key->arp_sha;
flower.key.arp.tha = key->arp_tha;
flower.key.arp.opcode = key->nw_proto;
flower.mask.arp.spa = mask->nw_src;
flower.mask.arp.tpa = mask->nw_dst;
flower.mask.arp.sha = mask->arp_sha;
flower.mask.arp.tha = mask->arp_tha;
flower.mask.arp.opcode = mask->nw_proto;
mask->nw_src = 0;
mask->nw_dst = 0;
mask->nw_proto = 0;
memset(&mask->arp_sha, 0, sizeof mask->arp_sha);
memset(&mask->arp_tha, 0, sizeof mask->arp_tha);
}
if (is_ip_any(key)) {
flower.key.ip_proto = key->nw_proto;
flower.mask.ip_proto = mask->nw_proto;

View File

@@ -7993,7 +7993,8 @@ get_arp_key(const struct flow *flow, struct ovs_key_arp *arp)
arp->arp_sip = flow->nw_src;
arp->arp_tip = flow->nw_dst;
arp->arp_op = htons(flow->nw_proto);
arp->arp_op = flow->nw_proto == UINT8_MAX ?
OVS_BE16_MAX : htons(flow->nw_proto);
arp->arp_sha = flow->arp_sha;
arp->arp_tha = flow->arp_tha;
}

View File

@@ -318,6 +318,24 @@ static const struct nl_policy tca_flower_policy[] = {
.min_len = ETH_ALEN,
.optional = true, },
[TCA_FLOWER_KEY_ETH_TYPE] = { .type = NL_A_U16, .optional = false, },
[TCA_FLOWER_KEY_ARP_SIP] = { .type = NL_A_U32, .optional = true, },
[TCA_FLOWER_KEY_ARP_TIP] = { .type = NL_A_U32, .optional = true, },
[TCA_FLOWER_KEY_ARP_SHA] = { .type = NL_A_UNSPEC,
.min_len = ETH_ALEN,
.optional = true, },
[TCA_FLOWER_KEY_ARP_THA] = { .type = NL_A_UNSPEC,
.min_len = ETH_ALEN,
.optional = true, },
[TCA_FLOWER_KEY_ARP_OP] = { .type = NL_A_U8, .optional = true, },
[TCA_FLOWER_KEY_ARP_SIP_MASK] = { .type = NL_A_U32, .optional = true, },
[TCA_FLOWER_KEY_ARP_TIP_MASK] = { .type = NL_A_U32, .optional = true, },
[TCA_FLOWER_KEY_ARP_SHA_MASK] = { .type = NL_A_UNSPEC,
.min_len = ETH_ALEN,
.optional = true, },
[TCA_FLOWER_KEY_ARP_THA_MASK] = { .type = NL_A_UNSPEC,
.min_len = ETH_ALEN,
.optional = true, },
[TCA_FLOWER_KEY_ARP_OP_MASK] = { .type = NL_A_U8, .optional = true, },
[TCA_FLOWER_FLAGS] = { .type = NL_A_U32, .optional = false, },
[TCA_FLOWER_ACT] = { .type = NL_A_NESTED, .optional = false, },
[TCA_FLOWER_KEY_IP_PROTO] = { .type = NL_A_U8, .optional = true, },
@@ -427,6 +445,45 @@ static const struct nl_policy tca_flower_terse_policy[] = {
[TCA_FLOWER_ACT] = { .type = NL_A_NESTED, .optional = false, },
};
static void
nl_parse_flower_arp(struct nlattr **attrs, struct tc_flower *flower)
{
const struct eth_addr *eth;
if (attrs[TCA_FLOWER_KEY_ARP_SIP_MASK]) {
flower->key.arp.spa =
nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ARP_SIP]);
flower->mask.arp.spa =
nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ARP_SIP_MASK]);
}
if (attrs[TCA_FLOWER_KEY_ARP_TIP_MASK]) {
flower->key.arp.tpa =
nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ARP_TIP]);
flower->mask.arp.tpa =
nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ARP_TIP_MASK]);
}
if (attrs[TCA_FLOWER_KEY_ARP_SHA_MASK]) {
eth = nl_attr_get_unspec(attrs[TCA_FLOWER_KEY_ARP_SHA], ETH_ALEN);
memcpy(&flower->key.arp.sha, eth, sizeof flower->key.arp.sha);
eth = nl_attr_get_unspec(attrs[TCA_FLOWER_KEY_ARP_SHA_MASK], ETH_ALEN);
memcpy(&flower->mask.arp.sha, eth, sizeof flower->mask.arp.sha);
}
if (attrs[TCA_FLOWER_KEY_ARP_THA_MASK]) {
eth = nl_attr_get_unspec(attrs[TCA_FLOWER_KEY_ARP_THA], ETH_ALEN);
memcpy(&flower->key.arp.tha, eth, sizeof flower->key.arp.tha);
eth = nl_attr_get_unspec(attrs[TCA_FLOWER_KEY_ARP_THA_MASK], ETH_ALEN);
memcpy(&flower->mask.arp.tha, eth, sizeof flower->mask.arp.tha);
}
if (attrs[TCA_FLOWER_KEY_ARP_OP_MASK]) {
flower->key.arp.opcode =
nl_attr_get_u8(attrs[TCA_FLOWER_KEY_ARP_OP]);
flower->mask.arp.opcode =
nl_attr_get_u8(attrs[TCA_FLOWER_KEY_ARP_OP_MASK]);
}
}
static void
nl_parse_flower_eth(struct nlattr **attrs, struct tc_flower *flower)
{
@@ -1760,6 +1817,7 @@ nl_parse_flower_options(struct nlattr *nl_options, struct tc_flower *flower,
}
nl_parse_flower_eth(attrs, flower);
nl_parse_flower_arp(attrs, flower);
nl_parse_flower_mpls(attrs, flower);
nl_parse_flower_vlan(attrs, flower);
nl_parse_flower_ip(attrs, flower);
@@ -2745,6 +2803,14 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
FLOWER_PUT_MASKED_VALUE(dst_mac, TCA_FLOWER_KEY_ETH_DST);
FLOWER_PUT_MASKED_VALUE(src_mac, TCA_FLOWER_KEY_ETH_SRC);
if (host_eth_type == ETH_P_ARP) {
FLOWER_PUT_MASKED_VALUE(arp.spa, TCA_FLOWER_KEY_ARP_SIP);
FLOWER_PUT_MASKED_VALUE(arp.tpa, TCA_FLOWER_KEY_ARP_TIP);
FLOWER_PUT_MASKED_VALUE(arp.sha, TCA_FLOWER_KEY_ARP_SHA);
FLOWER_PUT_MASKED_VALUE(arp.tha, TCA_FLOWER_KEY_ARP_THA);
FLOWER_PUT_MASKED_VALUE(arp.opcode, TCA_FLOWER_KEY_ARP_OP);
}
if (host_eth_type == ETH_P_IP || host_eth_type == ETH_P_IPV6) {
FLOWER_PUT_MASKED_VALUE(ip_ttl, TCA_FLOWER_KEY_IP_TTL);
FLOWER_PUT_MASKED_VALUE(ip_tos, TCA_FLOWER_KEY_IP_TOS);

View File

@@ -121,6 +121,14 @@ struct tc_flower_key {
uint32_t ct_mark;
ovs_u128 ct_label;
struct {
ovs_be32 spa;
ovs_be32 tpa;
struct eth_addr sha;
struct eth_addr tha;
uint8_t opcode;
} arp;
struct {
ovs_be32 ipv4_src;
ovs_be32 ipv4_dst;