@@ -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+
390441static 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