nfp: flower: support ipv6 tunnel keep-alive messages from fw
authorJohn Hurley <john.hurley@netronome.com>
Tue, 17 Dec 2019 21:57:23 +0000 (21:57 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Dec 2019 01:37:13 +0000 (17:37 -0800)
FW sends an update of IPv6 tunnels that are active in a given period. Use
this information to update the kernel table so that neighbour entries do
not time out when active on the NIC.

Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/flower/cmsg.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.h
drivers/net/ethernet/netronome/nfp/flower/main.h
drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c

index 00b904e..a595ddb 100644 (file)
@@ -278,6 +278,9 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
        case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
                nfp_tunnel_keep_alive(app, skb);
                break;
+       case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS_V6:
+               nfp_tunnel_keep_alive_v6(app, skb);
+               break;
        case NFP_FLOWER_CMSG_TYPE_QOS_STATS:
                nfp_flower_stats_rlim_reply(app, skb);
                break;
index 5a8ad58..9b50d76 100644 (file)
@@ -574,6 +574,7 @@ enum nfp_flower_cmsg_type_port {
        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,
 };
 
index 7a46032..ddd7b7f 100644 (file)
@@ -425,6 +425,7 @@ 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_v6(struct nfp_app *app, struct sk_buff *skb);
 void nfp_flower_lag_init(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);
index b179b63..2df3dee 100644 (file)
@@ -55,6 +55,25 @@ struct nfp_tun_active_tuns {
 };
 
 /**
+ * struct nfp_tun_active_tuns_v6 - periodic message of active IPv6 tunnels
+ * @seq:               sequence number of the message
+ * @count:             number of tunnels report in message
+ * @flags:             options part of the request
+ * @tun_info.ipv6:             dest IPv6 address of active route
+ * @tun_info.egress_port:      port the encapsulated packet egressed
+ * @tun_info:          tunnels that have sent traffic in reported period
+ */
+struct nfp_tun_active_tuns_v6 {
+       __be32 seq;
+       __be32 count;
+       __be32 flags;
+       struct route_ip_info_v6 {
+               struct in6_addr ipv6;
+               __be32 egress_port;
+       } tun_info[];
+};
+
+/**
  * struct nfp_tun_neigh - neighbour/route entry on the NFP
  * @dst_ipv4:  destination IPv4 address
  * @src_ipv4:  source IPv4 address
@@ -244,6 +263,49 @@ void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb)
        rcu_read_unlock();
 }
 
+void nfp_tunnel_keep_alive_v6(struct nfp_app *app, struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_IPV6)
+       struct nfp_tun_active_tuns_v6 *payload;
+       struct net_device *netdev;
+       int count, i, pay_len;
+       struct neighbour *n;
+       void *ipv6_add;
+       u32 port;
+
+       payload = nfp_flower_cmsg_get_data(skb);
+       count = be32_to_cpu(payload->count);
+       if (count > NFP_FL_IPV6_ADDRS_MAX) {
+               nfp_flower_cmsg_warn(app, "IPv6 tunnel keep-alive request exceeds max routes.\n");
+               return;
+       }
+
+       pay_len = nfp_flower_cmsg_get_data_len(skb);
+       if (pay_len != struct_size(payload, tun_info, count)) {
+               nfp_flower_cmsg_warn(app, "Corruption in tunnel keep-alive message.\n");
+               return;
+       }
+
+       rcu_read_lock();
+       for (i = 0; i < count; i++) {
+               ipv6_add = &payload->tun_info[i].ipv6;
+               port = be32_to_cpu(payload->tun_info[i].egress_port);
+               netdev = nfp_app_dev_get(app, port, NULL);
+               if (!netdev)
+                       continue;
+
+               n = neigh_lookup(&nd_tbl, ipv6_add, netdev);
+               if (!n)
+                       continue;
+
+               /* Update the used timestamp of neighbour */
+               neigh_event_send(n, NULL);
+               neigh_release(n);
+       }
+       rcu_read_unlock();
+#endif
+}
+
 static int
 nfp_flower_xmit_tun_conf(struct nfp_app *app, u8 mtype, u16 plen, void *pdata,
                         gfp_t flag)