Commit 8fb0d2ce authored by David S. Miller's avatar David S. Miller

Merge branch 'nfp-ipv6-tunnel'

John Hurley says:

====================
Add ipv6 tunnel support to NFP

The following patches add support for IPv6 tunnel offload to the NFP
driver.

Patches 1-2 do some code tidy up and prepare existing code for reuse in
IPv6 tunnels.
Patches 3-4 handle IPv6 tunnel decap (match) rules.
Patches 5-8 handle encap (action) rules.
Patch 9 adds IPv6 support to the merge and pre-tunnel rule functions.

v1->v2:
- fix compiler warning when building without CONFIG_IPV6 set -
  Jakub Kicinski (patch 7)
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a886ca6f 78346160
...@@ -22,8 +22,9 @@ ...@@ -22,8 +22,9 @@
#define NFP_FL_TUNNEL_CSUM cpu_to_be16(0x01) #define NFP_FL_TUNNEL_CSUM cpu_to_be16(0x01)
#define NFP_FL_TUNNEL_KEY cpu_to_be16(0x04) #define NFP_FL_TUNNEL_KEY cpu_to_be16(0x04)
#define NFP_FL_TUNNEL_GENEVE_OPT cpu_to_be16(0x0800) #define NFP_FL_TUNNEL_GENEVE_OPT cpu_to_be16(0x0800)
#define NFP_FL_SUPPORTED_TUNNEL_INFO_FLAGS IP_TUNNEL_INFO_TX #define NFP_FL_SUPPORTED_TUNNEL_INFO_FLAGS (IP_TUNNEL_INFO_TX | \
#define NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS (NFP_FL_TUNNEL_CSUM | \ IP_TUNNEL_INFO_IPV6)
#define NFP_FL_SUPPORTED_UDP_TUN_FLAGS (NFP_FL_TUNNEL_CSUM | \
NFP_FL_TUNNEL_KEY | \ NFP_FL_TUNNEL_KEY | \
NFP_FL_TUNNEL_GENEVE_OPT) NFP_FL_TUNNEL_GENEVE_OPT)
...@@ -394,19 +395,26 @@ nfp_fl_push_geneve_options(struct nfp_fl_payload *nfp_fl, int *list_len, ...@@ -394,19 +395,26 @@ nfp_fl_push_geneve_options(struct nfp_fl_payload *nfp_fl, int *list_len,
} }
static int static int
nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun, nfp_fl_set_tun(struct nfp_app *app, struct nfp_fl_set_tun *set_tun,
const struct flow_action_entry *act, const struct flow_action_entry *act,
struct nfp_fl_pre_tunnel *pre_tun, struct nfp_fl_pre_tunnel *pre_tun,
enum nfp_flower_tun_type tun_type, enum nfp_flower_tun_type tun_type,
struct net_device *netdev, struct netlink_ext_ack *extack) struct net_device *netdev, struct netlink_ext_ack *extack)
{ {
size_t act_size = sizeof(struct nfp_fl_set_ipv4_tun);
const struct ip_tunnel_info *ip_tun = act->tunnel; const struct ip_tunnel_info *ip_tun = act->tunnel;
bool ipv6 = ip_tunnel_info_af(ip_tun) == AF_INET6;
size_t act_size = sizeof(struct nfp_fl_set_tun);
struct nfp_flower_priv *priv = app->priv; struct nfp_flower_priv *priv = app->priv;
u32 tmp_set_ip_tun_type_index = 0; u32 tmp_set_ip_tun_type_index = 0;
/* Currently support one pre-tunnel so index is always 0. */ /* Currently support one pre-tunnel so index is always 0. */
int pretun_idx = 0; int pretun_idx = 0;
if (!IS_ENABLED(CONFIG_IPV6) && ipv6)
return -EOPNOTSUPP;
if (ipv6 && !(priv->flower_ext_feats & NFP_FL_FEATS_IPV6_TUN))
return -EOPNOTSUPP;
BUILD_BUG_ON(NFP_FL_TUNNEL_CSUM != TUNNEL_CSUM || BUILD_BUG_ON(NFP_FL_TUNNEL_CSUM != TUNNEL_CSUM ||
NFP_FL_TUNNEL_KEY != TUNNEL_KEY || NFP_FL_TUNNEL_KEY != TUNNEL_KEY ||
NFP_FL_TUNNEL_GENEVE_OPT != TUNNEL_GENEVE_OPT); NFP_FL_TUNNEL_GENEVE_OPT != TUNNEL_GENEVE_OPT);
...@@ -417,19 +425,35 @@ nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun, ...@@ -417,19 +425,35 @@ nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_TUNNEL;
set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ; set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ;
/* Set tunnel type and pre-tunnel index. */ /* Set tunnel type and pre-tunnel index. */
tmp_set_ip_tun_type_index |= tmp_set_ip_tun_type_index |=
FIELD_PREP(NFP_FL_IPV4_TUNNEL_TYPE, tun_type) | FIELD_PREP(NFP_FL_TUNNEL_TYPE, tun_type) |
FIELD_PREP(NFP_FL_IPV4_PRE_TUN_INDEX, pretun_idx); FIELD_PREP(NFP_FL_PRE_TUN_INDEX, pretun_idx);
set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index); set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index);
set_tun->tun_id = ip_tun->key.tun_id; set_tun->tun_id = ip_tun->key.tun_id;
if (ip_tun->key.ttl) { if (ip_tun->key.ttl) {
set_tun->ttl = ip_tun->key.ttl; set_tun->ttl = ip_tun->key.ttl;
#ifdef CONFIG_IPV6
} else if (ipv6) {
struct net *net = dev_net(netdev);
struct flowi6 flow = {};
struct dst_entry *dst;
flow.daddr = ip_tun->key.u.ipv6.dst;
flow.flowi4_proto = IPPROTO_UDP;
dst = ipv6_stub->ipv6_dst_lookup_flow(net, NULL, &flow, NULL);
if (!IS_ERR(dst)) {
set_tun->ttl = ip6_dst_hoplimit(dst);
dst_release(dst);
} else {
set_tun->ttl = net->ipv6.devconf_all->hop_limit;
}
#endif
} else { } else {
struct net *net = dev_net(netdev); struct net *net = dev_net(netdev);
struct flowi4 flow = {}; struct flowi4 flow = {};
...@@ -455,7 +479,7 @@ nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun, ...@@ -455,7 +479,7 @@ nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun,
set_tun->tos = ip_tun->key.tos; set_tun->tos = ip_tun->key.tos;
if (!(ip_tun->key.tun_flags & NFP_FL_TUNNEL_KEY) || if (!(ip_tun->key.tun_flags & NFP_FL_TUNNEL_KEY) ||
ip_tun->key.tun_flags & ~NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS) { ip_tun->key.tun_flags & ~NFP_FL_SUPPORTED_UDP_TUN_FLAGS) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: loaded firmware does not support tunnel flag offload"); NL_SET_ERR_MSG_MOD(extack, "unsupported offload: loaded firmware does not support tunnel flag offload");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -467,7 +491,12 @@ nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun, ...@@ -467,7 +491,12 @@ nfp_fl_set_ipv4_tun(struct nfp_app *app, struct nfp_fl_set_ipv4_tun *set_tun,
} }
/* Complete pre_tunnel action. */ /* Complete pre_tunnel action. */
if (ipv6) {
pre_tun->flags |= cpu_to_be16(NFP_FL_PRE_TUN_IPV6);
pre_tun->ipv6_dst = ip_tun->key.u.ipv6.dst;
} else {
pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst; pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst;
}
return 0; return 0;
} }
...@@ -956,8 +985,8 @@ nfp_flower_loop_action(struct nfp_app *app, const struct flow_action_entry *act, ...@@ -956,8 +985,8 @@ nfp_flower_loop_action(struct nfp_app *app, const struct flow_action_entry *act,
struct nfp_flower_pedit_acts *set_act, bool *pkt_host, struct nfp_flower_pedit_acts *set_act, bool *pkt_host,
struct netlink_ext_ack *extack, int act_idx) struct netlink_ext_ack *extack, int act_idx)
{ {
struct nfp_fl_set_ipv4_tun *set_tun;
struct nfp_fl_pre_tunnel *pre_tun; struct nfp_fl_pre_tunnel *pre_tun;
struct nfp_fl_set_tun *set_tun;
struct nfp_fl_push_vlan *psh_v; struct nfp_fl_push_vlan *psh_v;
struct nfp_fl_push_mpls *psh_m; struct nfp_fl_push_mpls *psh_m;
struct nfp_fl_pop_vlan *pop_v; struct nfp_fl_pop_vlan *pop_v;
...@@ -1032,7 +1061,7 @@ nfp_flower_loop_action(struct nfp_app *app, const struct flow_action_entry *act, ...@@ -1032,7 +1061,7 @@ nfp_flower_loop_action(struct nfp_app *app, const struct flow_action_entry *act,
* If none, the packet falls back before applying other actions. * If none, the packet falls back before applying other actions.
*/ */
if (*a_len + sizeof(struct nfp_fl_pre_tunnel) + if (*a_len + sizeof(struct nfp_fl_pre_tunnel) +
sizeof(struct nfp_fl_set_ipv4_tun) > NFP_FL_MAX_A_SIZ) { sizeof(struct nfp_fl_set_tun) > NFP_FL_MAX_A_SIZ) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: maximum allowed action list size exceeded at tunnel encap"); NL_SET_ERR_MSG_MOD(extack, "unsupported offload: maximum allowed action list size exceeded at tunnel encap");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -1046,11 +1075,11 @@ nfp_flower_loop_action(struct nfp_app *app, const struct flow_action_entry *act, ...@@ -1046,11 +1075,11 @@ nfp_flower_loop_action(struct nfp_app *app, const struct flow_action_entry *act,
return err; return err;
set_tun = (void *)&nfp_fl->action_data[*a_len]; set_tun = (void *)&nfp_fl->action_data[*a_len];
err = nfp_fl_set_ipv4_tun(app, set_tun, act, pre_tun, err = nfp_fl_set_tun(app, set_tun, act, pre_tun, *tun_type,
*tun_type, netdev, extack); netdev, extack);
if (err) if (err)
return err; return err;
*a_len += sizeof(struct nfp_fl_set_ipv4_tun); *a_len += sizeof(struct nfp_fl_set_tun);
} }
break; break;
case FLOW_ACTION_TUNNEL_DECAP: case FLOW_ACTION_TUNNEL_DECAP:
......
...@@ -270,11 +270,17 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) ...@@ -270,11 +270,17 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
} }
goto err_default; goto err_default;
case NFP_FLOWER_CMSG_TYPE_NO_NEIGH: case NFP_FLOWER_CMSG_TYPE_NO_NEIGH:
nfp_tunnel_request_route(app, skb); nfp_tunnel_request_route_v4(app, skb);
break;
case NFP_FLOWER_CMSG_TYPE_NO_NEIGH_V6:
nfp_tunnel_request_route_v6(app, skb);
break; break;
case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS: case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
nfp_tunnel_keep_alive(app, skb); nfp_tunnel_keep_alive(app, skb);
break; break;
case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS_V6:
nfp_tunnel_keep_alive_v6(app, skb);
break;
case NFP_FLOWER_CMSG_TYPE_QOS_STATS: case NFP_FLOWER_CMSG_TYPE_QOS_STATS:
nfp_flower_stats_rlim_reply(app, skb); nfp_flower_stats_rlim_reply(app, skb);
break; break;
...@@ -361,7 +367,8 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb) ...@@ -361,7 +367,8 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
nfp_flower_process_mtu_ack(app, skb)) { nfp_flower_process_mtu_ack(app, skb)) {
/* Handle MTU acks outside wq to prevent RTNL conflict. */ /* Handle MTU acks outside wq to prevent RTNL conflict. */
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH) { } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH ||
cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6) {
/* Acks from the NFP that the route is added - ignore. */ /* Acks from the NFP that the route is added - ignore. */
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY) { } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY) {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define NFP_FLOWER_LAYER2_GRE BIT(0) #define NFP_FLOWER_LAYER2_GRE BIT(0)
#define NFP_FLOWER_LAYER2_GENEVE BIT(5) #define NFP_FLOWER_LAYER2_GENEVE BIT(5)
#define NFP_FLOWER_LAYER2_GENEVE_OP BIT(6) #define NFP_FLOWER_LAYER2_GENEVE_OP BIT(6)
#define NFP_FLOWER_LAYER2_TUN_IPV6 BIT(7)
#define NFP_FLOWER_MASK_VLAN_PRIO GENMASK(15, 13) #define NFP_FLOWER_MASK_VLAN_PRIO GENMASK(15, 13)
#define NFP_FLOWER_MASK_VLAN_PRESENT BIT(12) #define NFP_FLOWER_MASK_VLAN_PRESENT BIT(12)
...@@ -63,6 +64,7 @@ ...@@ -63,6 +64,7 @@
#define NFP_FL_MAX_GENEVE_OPT_ACT 32 #define NFP_FL_MAX_GENEVE_OPT_ACT 32
#define NFP_FL_MAX_GENEVE_OPT_CNT 64 #define NFP_FL_MAX_GENEVE_OPT_CNT 64
#define NFP_FL_MAX_GENEVE_OPT_KEY 32 #define NFP_FL_MAX_GENEVE_OPT_KEY 32
#define NFP_FL_MAX_GENEVE_OPT_KEY_V6 8
/* Action opcodes */ /* Action opcodes */
#define NFP_FL_ACTION_OPCODE_OUTPUT 0 #define NFP_FL_ACTION_OPCODE_OUTPUT 0
...@@ -70,7 +72,7 @@ ...@@ -70,7 +72,7 @@
#define NFP_FL_ACTION_OPCODE_POP_VLAN 2 #define NFP_FL_ACTION_OPCODE_POP_VLAN 2
#define NFP_FL_ACTION_OPCODE_PUSH_MPLS 3 #define NFP_FL_ACTION_OPCODE_PUSH_MPLS 3
#define NFP_FL_ACTION_OPCODE_POP_MPLS 4 #define NFP_FL_ACTION_OPCODE_POP_MPLS 4
#define NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL 6 #define NFP_FL_ACTION_OPCODE_SET_TUNNEL 6
#define NFP_FL_ACTION_OPCODE_SET_ETHERNET 7 #define NFP_FL_ACTION_OPCODE_SET_ETHERNET 7
#define NFP_FL_ACTION_OPCODE_SET_MPLS 8 #define NFP_FL_ACTION_OPCODE_SET_MPLS 8
#define NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS 9 #define NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS 9
...@@ -99,8 +101,8 @@ ...@@ -99,8 +101,8 @@
/* Tunnel ports */ /* Tunnel ports */
#define NFP_FL_PORT_TYPE_TUN 0x50000000 #define NFP_FL_PORT_TYPE_TUN 0x50000000
#define NFP_FL_IPV4_TUNNEL_TYPE GENMASK(7, 4) #define NFP_FL_TUNNEL_TYPE GENMASK(7, 4)
#define NFP_FL_IPV4_PRE_TUN_INDEX GENMASK(2, 0) #define NFP_FL_PRE_TUN_INDEX GENMASK(2, 0)
#define NFP_FLOWER_WORKQ_MAX_SKBS 30000 #define NFP_FLOWER_WORKQ_MAX_SKBS 30000
...@@ -206,13 +208,16 @@ struct nfp_fl_pre_lag { ...@@ -206,13 +208,16 @@ struct nfp_fl_pre_lag {
struct nfp_fl_pre_tunnel { struct nfp_fl_pre_tunnel {
struct nfp_fl_act_head head; struct nfp_fl_act_head head;
__be16 reserved; __be16 flags;
union {
__be32 ipv4_dst; __be32 ipv4_dst;
/* reserved for use with IPv6 addresses */ struct in6_addr ipv6_dst;
__be32 extra[3]; };
}; };
struct nfp_fl_set_ipv4_tun { #define NFP_FL_PRE_TUN_IPV6 BIT(0)
struct nfp_fl_set_tun {
struct nfp_fl_act_head head; struct nfp_fl_act_head head;
__be16 reserved; __be16 reserved;
__be64 tun_id __packed; __be64 tun_id __packed;
...@@ -387,6 +392,11 @@ struct nfp_flower_tun_ipv4 { ...@@ -387,6 +392,11 @@ struct nfp_flower_tun_ipv4 {
__be32 dst; __be32 dst;
}; };
struct nfp_flower_tun_ipv6 {
struct in6_addr src;
struct in6_addr dst;
};
struct nfp_flower_tun_ip_ext { struct nfp_flower_tun_ip_ext {
u8 tos; u8 tos;
u8 ttl; u8 ttl;
...@@ -416,6 +426,42 @@ struct nfp_flower_ipv4_udp_tun { ...@@ -416,6 +426,42 @@ struct nfp_flower_ipv4_udp_tun {
__be32 tun_id; __be32 tun_id;
}; };
/* Flow Frame IPv6 UDP TUNNEL --> Tunnel details (11W/44B)
* -----------------------------------------------------------------
* 3 2 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 31 - 0 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 63 - 32 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 95 - 64 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 127 - 96 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 31 - 0 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 63 - 32 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 95 - 64 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 127 - 96 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved | tos | ttl |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VNI | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct nfp_flower_ipv6_udp_tun {
struct nfp_flower_tun_ipv6 ipv6;
__be16 reserved1;
struct nfp_flower_tun_ip_ext ip_ext;
__be32 reserved2;
__be32 tun_id;
};
/* Flow Frame GRE TUNNEL --> Tunnel details (6W/24B) /* Flow Frame GRE TUNNEL --> Tunnel details (6W/24B)
* ----------------------------------------------------------------- * -----------------------------------------------------------------
* 3 2 1 * 3 2 1
...@@ -445,6 +491,46 @@ struct nfp_flower_ipv4_gre_tun { ...@@ -445,6 +491,46 @@ struct nfp_flower_ipv4_gre_tun {
__be32 reserved2; __be32 reserved2;
}; };
/* Flow Frame GRE TUNNEL V6 --> Tunnel details (12W/48B)
* -----------------------------------------------------------------
* 3 2 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 31 - 0 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 63 - 32 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 95 - 64 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_src, 127 - 96 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 31 - 0 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 63 - 32 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 95 - 64 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv6_addr_dst, 127 - 96 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | tun_flags | tos | ttl |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved | Ethertype |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Key |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct nfp_flower_ipv6_gre_tun {
struct nfp_flower_tun_ipv6 ipv6;
__be16 tun_flags;
struct nfp_flower_tun_ip_ext ip_ext;
__be16 reserved1;
__be16 ethertype;
__be32 tun_key;
__be32 reserved2;
};
struct nfp_flower_geneve_options { struct nfp_flower_geneve_options {
u8 data[NFP_FL_MAX_GENEVE_OPT_KEY]; u8 data[NFP_FL_MAX_GENEVE_OPT_KEY];
}; };
...@@ -485,6 +571,10 @@ enum nfp_flower_cmsg_type_port { ...@@ -485,6 +571,10 @@ enum nfp_flower_cmsg_type_port {
NFP_FLOWER_CMSG_TYPE_QOS_DEL = 19, NFP_FLOWER_CMSG_TYPE_QOS_DEL = 19,
NFP_FLOWER_CMSG_TYPE_QOS_STATS = 20, NFP_FLOWER_CMSG_TYPE_QOS_STATS = 20,
NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE = 21, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE = 21,
NFP_FLOWER_CMSG_TYPE_TUN_IPS_V6 = 22,
NFP_FLOWER_CMSG_TYPE_NO_NEIGH_V6 = 23,
NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 = 24,
NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS_V6 = 25,
NFP_FLOWER_CMSG_TYPE_MAX = 32, NFP_FLOWER_CMSG_TYPE_MAX = 32,
}; };
......
...@@ -43,6 +43,7 @@ struct nfp_app; ...@@ -43,6 +43,7 @@ struct nfp_app;
#define NFP_FL_FEATS_VF_RLIM BIT(4) #define NFP_FL_FEATS_VF_RLIM BIT(4)
#define NFP_FL_FEATS_FLOW_MOD BIT(5) #define NFP_FL_FEATS_FLOW_MOD BIT(5)
#define NFP_FL_FEATS_PRE_TUN_RULES BIT(6) #define NFP_FL_FEATS_PRE_TUN_RULES BIT(6)
#define NFP_FL_FEATS_IPV6_TUN BIT(7)
#define NFP_FL_FEATS_FLOW_MERGE BIT(30) #define NFP_FL_FEATS_FLOW_MERGE BIT(30)
#define NFP_FL_FEATS_LAG BIT(31) #define NFP_FL_FEATS_LAG BIT(31)
...@@ -62,18 +63,26 @@ struct nfp_fl_stats_id { ...@@ -62,18 +63,26 @@ struct nfp_fl_stats_id {
* struct nfp_fl_tunnel_offloads - priv data for tunnel offloads * struct nfp_fl_tunnel_offloads - priv data for tunnel offloads
* @offloaded_macs: Hashtable of the offloaded MAC addresses * @offloaded_macs: Hashtable of the offloaded MAC addresses
* @ipv4_off_list: List of IPv4 addresses to offload * @ipv4_off_list: List of IPv4 addresses to offload
* @neigh_off_list: List of neighbour offloads * @ipv6_off_list: List of IPv6 addresses to offload
* @neigh_off_list_v4: List of IPv4 neighbour offloads
* @neigh_off_list_v6: List of IPv6 neighbour offloads
* @ipv4_off_lock: Lock for the IPv4 address list * @ipv4_off_lock: Lock for the IPv4 address list
* @neigh_off_lock: Lock for the neighbour address list * @ipv6_off_lock: Lock for the IPv6 address list
* @neigh_off_lock_v4: Lock for the IPv4 neighbour address list
* @neigh_off_lock_v6: Lock for the IPv6 neighbour address list
* @mac_off_ids: IDA to manage id assignment for offloaded MACs * @mac_off_ids: IDA to manage id assignment for offloaded MACs
* @neigh_nb: Notifier to monitor neighbour state * @neigh_nb: Notifier to monitor neighbour state
*/ */
struct nfp_fl_tunnel_offloads { struct nfp_fl_tunnel_offloads {
struct rhashtable offloaded_macs; struct rhashtable offloaded_macs;
struct list_head ipv4_off_list; struct list_head ipv4_off_list;
struct list_head neigh_off_list; struct list_head ipv6_off_list;
struct list_head neigh_off_list_v4;
struct list_head neigh_off_list_v6;
struct mutex ipv4_off_lock; struct mutex ipv4_off_lock;
spinlock_t neigh_off_lock; struct mutex ipv6_off_lock;
spinlock_t neigh_off_lock_v4;
spinlock_t neigh_off_lock_v6;
struct ida mac_off_ids; struct ida mac_off_ids;
struct notifier_block neigh_nb; struct notifier_block neigh_nb;
}; };
...@@ -273,12 +282,25 @@ struct nfp_fl_stats { ...@@ -273,12 +282,25 @@ struct nfp_fl_stats {
u64 used; u64 used;
}; };
/**
* struct nfp_ipv6_addr_entry - cached IPv6 addresses
* @ipv6_addr: IP address
* @ref_count: number of rules currently using this IP
* @list: list pointer
*/
struct nfp_ipv6_addr_entry {
struct in6_addr ipv6_addr;
int ref_count;
struct list_head list;
};
struct nfp_fl_payload { struct nfp_fl_payload {
struct nfp_fl_rule_metadata meta; struct nfp_fl_rule_metadata meta;
unsigned long tc_flower_cookie; unsigned long tc_flower_cookie;
struct rhash_head fl_node; struct rhash_head fl_node;
struct rcu_head rcu; struct rcu_head rcu;
__be32 nfp_tun_ipv4_addr; __be32 nfp_tun_ipv4_addr;
struct nfp_ipv6_addr_entry *nfp_tun_ipv6;
struct net_device *ingress_dev; struct net_device *ingress_dev;
char *unmasked_data; char *unmasked_data;
char *mask_data; char *mask_data;
...@@ -396,8 +418,14 @@ int nfp_tunnel_mac_event_handler(struct nfp_app *app, ...@@ -396,8 +418,14 @@ int nfp_tunnel_mac_event_handler(struct nfp_app *app,
unsigned long event, void *ptr); unsigned long event, void *ptr);
void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4); void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4);
void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4); void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4);
void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb); void
nfp_tunnel_put_ipv6_off(struct nfp_app *app, struct nfp_ipv6_addr_entry *entry);
struct nfp_ipv6_addr_entry *
nfp_tunnel_add_ipv6_off(struct nfp_app *app, struct in6_addr *ipv6);
void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb);
void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb);
void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb); void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb);
void nfp_tunnel_keep_alive_v6(struct nfp_app *app, struct sk_buff *skb);
void nfp_flower_lag_init(struct nfp_fl_lag *lag); void nfp_flower_lag_init(struct nfp_fl_lag *lag);
void nfp_flower_lag_cleanup(struct nfp_fl_lag *lag); void nfp_flower_lag_cleanup(struct nfp_fl_lag *lag);
int nfp_flower_lag_reset(struct nfp_fl_lag *lag); int nfp_flower_lag_reset(struct nfp_fl_lag *lag);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment