Skip to content

Commit a079664

Browse files
sbrivio-rhdavem330
authored andcommitted
geneve: ICMP error lookup handler
Export an encap_err_lookup() operation to match an ICMP error against a valid VNI. Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5828887 commit a079664

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

drivers/net/geneve.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,57 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
387387
return 0;
388388
}
389389

390+
/* Callback from net/ipv{4,6}/udp.c to check that we have a tunnel for errors */
391+
static int geneve_udp_encap_err_lookup(struct sock *sk, struct sk_buff *skb)
392+
{
393+
struct genevehdr *geneveh;
394+
struct geneve_sock *gs;
395+
u8 zero_vni[3] = { 0 };
396+
u8 *vni = zero_vni;
397+
398+
if (skb->len < GENEVE_BASE_HLEN)
399+
return -EINVAL;
400+
401+
geneveh = geneve_hdr(skb);
402+
if (geneveh->ver != GENEVE_VER)
403+
return -EINVAL;
404+
405+
if (geneveh->proto_type != htons(ETH_P_TEB))
406+
return -EINVAL;
407+
408+
gs = rcu_dereference_sk_user_data(sk);
409+
if (!gs)
410+
return -ENOENT;
411+
412+
if (geneve_get_sk_family(gs) == AF_INET) {
413+
struct iphdr *iph = ip_hdr(skb);
414+
__be32 addr4 = 0;
415+
416+
if (!gs->collect_md) {
417+
vni = geneve_hdr(skb)->vni;
418+
addr4 = iph->daddr;
419+
}
420+
421+
return geneve_lookup(gs, addr4, vni) ? 0 : -ENOENT;
422+
}
423+
424+
#if IS_ENABLED(CONFIG_IPV6)
425+
if (geneve_get_sk_family(gs) == AF_INET6) {
426+
struct ipv6hdr *ip6h = ipv6_hdr(skb);
427+
struct in6_addr addr6 = { 0 };
428+
429+
if (!gs->collect_md) {
430+
vni = geneve_hdr(skb)->vni;
431+
addr6 = ip6h->daddr;
432+
}
433+
434+
return geneve6_lookup(gs, addr6, vni) ? 0 : -ENOENT;
435+
}
436+
#endif
437+
438+
return -EPFNOSUPPORT;
439+
}
440+
390441
static struct socket *geneve_create_sock(struct net *net, bool ipv6,
391442
__be16 port, bool ipv6_rx_csum)
392443
{
@@ -544,6 +595,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
544595
tunnel_cfg.gro_receive = geneve_gro_receive;
545596
tunnel_cfg.gro_complete = geneve_gro_complete;
546597
tunnel_cfg.encap_rcv = geneve_udp_encap_recv;
598+
tunnel_cfg.encap_err_lookup = geneve_udp_encap_err_lookup;
547599
tunnel_cfg.encap_destroy = NULL;
548600
setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
549601
list_add(&gs->list, &gn->sock_list);

0 commit comments

Comments
 (0)