3030#include <net/seg6_local.h>
3131#include <linux/etherdevice.h>
3232#include <linux/bpf.h>
33+ #include <net/lwtunnel.h>
34+ #include <linux/netfilter.h>
3335
3436#define SEG6_F_ATTR (i ) BIT(i)
3537
@@ -413,12 +415,33 @@ static int input_action_end_dx2(struct sk_buff *skb,
413415 return - EINVAL ;
414416}
415417
418+ static int input_action_end_dx6_finish (struct net * net , struct sock * sk ,
419+ struct sk_buff * skb )
420+ {
421+ struct dst_entry * orig_dst = skb_dst (skb );
422+ struct in6_addr * nhaddr = NULL ;
423+ struct seg6_local_lwt * slwt ;
424+
425+ slwt = seg6_local_lwtunnel (orig_dst -> lwtstate );
426+
427+ /* The inner packet is not associated to any local interface,
428+ * so we do not call netif_rx().
429+ *
430+ * If slwt->nh6 is set to ::, then lookup the nexthop for the
431+ * inner packet's DA. Otherwise, use the specified nexthop.
432+ */
433+ if (!ipv6_addr_any (& slwt -> nh6 ))
434+ nhaddr = & slwt -> nh6 ;
435+
436+ seg6_lookup_nexthop (skb , nhaddr , 0 );
437+
438+ return dst_input (skb );
439+ }
440+
416441/* decapsulate and forward to specified nexthop */
417442static int input_action_end_dx6 (struct sk_buff * skb ,
418443 struct seg6_local_lwt * slwt )
419444{
420- struct in6_addr * nhaddr = NULL ;
421-
422445 /* this function accepts IPv6 encapsulated packets, with either
423446 * an SRH with SL=0, or no SRH.
424447 */
@@ -429,55 +452,65 @@ static int input_action_end_dx6(struct sk_buff *skb,
429452 if (!pskb_may_pull (skb , sizeof (struct ipv6hdr )))
430453 goto drop ;
431454
432- /* The inner packet is not associated to any local interface,
433- * so we do not call netif_rx().
434- *
435- * If slwt->nh6 is set to ::, then lookup the nexthop for the
436- * inner packet's DA. Otherwise, use the specified nexthop.
437- */
438-
439- if (!ipv6_addr_any (& slwt -> nh6 ))
440- nhaddr = & slwt -> nh6 ;
441-
442455 skb_set_transport_header (skb , sizeof (struct ipv6hdr ));
456+ nf_reset_ct (skb );
443457
444- seg6_lookup_nexthop (skb , nhaddr , 0 );
458+ if (static_branch_unlikely (& nf_hooks_lwtunnel_enabled ))
459+ return NF_HOOK (NFPROTO_IPV6 , NF_INET_PRE_ROUTING ,
460+ dev_net (skb -> dev ), NULL , skb , NULL ,
461+ skb_dst (skb )-> dev , input_action_end_dx6_finish );
445462
446- return dst_input ( skb );
463+ return input_action_end_dx6_finish ( dev_net ( skb -> dev ), NULL , skb );
447464drop :
448465 kfree_skb (skb );
449466 return - EINVAL ;
450467}
451468
452- static int input_action_end_dx4 (struct sk_buff * skb ,
453- struct seg6_local_lwt * slwt )
469+ static int input_action_end_dx4_finish (struct net * net , struct sock * sk ,
470+ struct sk_buff * skb )
454471{
472+ struct dst_entry * orig_dst = skb_dst (skb );
473+ struct seg6_local_lwt * slwt ;
455474 struct iphdr * iph ;
456475 __be32 nhaddr ;
457476 int err ;
458477
459- if (!decap_and_validate (skb , IPPROTO_IPIP ))
460- goto drop ;
461-
462- if (!pskb_may_pull (skb , sizeof (struct iphdr )))
463- goto drop ;
464-
465- skb -> protocol = htons (ETH_P_IP );
478+ slwt = seg6_local_lwtunnel (orig_dst -> lwtstate );
466479
467480 iph = ip_hdr (skb );
468481
469482 nhaddr = slwt -> nh4 .s_addr ?: iph -> daddr ;
470483
471484 skb_dst_drop (skb );
472485
473- skb_set_transport_header (skb , sizeof (struct iphdr ));
474-
475486 err = ip_route_input (skb , nhaddr , iph -> saddr , 0 , skb -> dev );
476- if (err )
477- goto drop ;
487+ if (err ) {
488+ kfree_skb (skb );
489+ return - EINVAL ;
490+ }
478491
479492 return dst_input (skb );
493+ }
494+
495+ static int input_action_end_dx4 (struct sk_buff * skb ,
496+ struct seg6_local_lwt * slwt )
497+ {
498+ if (!decap_and_validate (skb , IPPROTO_IPIP ))
499+ goto drop ;
500+
501+ if (!pskb_may_pull (skb , sizeof (struct iphdr )))
502+ goto drop ;
503+
504+ skb -> protocol = htons (ETH_P_IP );
505+ skb_set_transport_header (skb , sizeof (struct iphdr ));
506+ nf_reset_ct (skb );
507+
508+ if (static_branch_unlikely (& nf_hooks_lwtunnel_enabled ))
509+ return NF_HOOK (NFPROTO_IPV4 , NF_INET_PRE_ROUTING ,
510+ dev_net (skb -> dev ), NULL , skb , NULL ,
511+ skb_dst (skb )-> dev , input_action_end_dx4_finish );
480512
513+ return input_action_end_dx4_finish (dev_net (skb -> dev ), NULL , skb );
481514drop :
482515 kfree_skb (skb );
483516 return - EINVAL ;
@@ -645,6 +678,7 @@ static struct sk_buff *end_dt_vrf_core(struct sk_buff *skb,
645678 skb_dst_drop (skb );
646679
647680 skb_set_transport_header (skb , hdrlen );
681+ nf_reset_ct (skb );
648682
649683 return end_dt_vrf_rcv (skb , family , vrf );
650684
@@ -1078,19 +1112,15 @@ static void seg6_local_update_counters(struct seg6_local_lwt *slwt,
10781112 u64_stats_update_end (& pcounters -> syncp );
10791113}
10801114
1081- static int seg6_local_input (struct sk_buff * skb )
1115+ static int seg6_local_input_core (struct net * net , struct sock * sk ,
1116+ struct sk_buff * skb )
10821117{
10831118 struct dst_entry * orig_dst = skb_dst (skb );
10841119 struct seg6_action_desc * desc ;
10851120 struct seg6_local_lwt * slwt ;
10861121 unsigned int len = skb -> len ;
10871122 int rc ;
10881123
1089- if (skb -> protocol != htons (ETH_P_IPV6 )) {
1090- kfree_skb (skb );
1091- return - EINVAL ;
1092- }
1093-
10941124 slwt = seg6_local_lwtunnel (orig_dst -> lwtstate );
10951125 desc = slwt -> desc ;
10961126
@@ -1104,6 +1134,21 @@ static int seg6_local_input(struct sk_buff *skb)
11041134 return rc ;
11051135}
11061136
1137+ static int seg6_local_input (struct sk_buff * skb )
1138+ {
1139+ if (skb -> protocol != htons (ETH_P_IPV6 )) {
1140+ kfree_skb (skb );
1141+ return - EINVAL ;
1142+ }
1143+
1144+ if (static_branch_unlikely (& nf_hooks_lwtunnel_enabled ))
1145+ return NF_HOOK (NFPROTO_IPV6 , NF_INET_LOCAL_IN ,
1146+ dev_net (skb -> dev ), NULL , skb , skb -> dev , NULL ,
1147+ seg6_local_input_core );
1148+
1149+ return seg6_local_input_core (dev_net (skb -> dev ), NULL , skb );
1150+ }
1151+
11071152static const struct nla_policy seg6_local_policy [SEG6_LOCAL_MAX + 1 ] = {
11081153 [SEG6_LOCAL_ACTION ] = { .type = NLA_U32 },
11091154 [SEG6_LOCAL_SRH ] = { .type = NLA_BINARY },
0 commit comments