Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx> wrote: > +static void > +synproxy_send_tcp_ipv6(struct net *net, > + const struct sk_buff *skb, struct sk_buff *nskb, > + struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, > + struct ipv6hdr *niph, struct tcphdr *nth, > + unsigned int tcp_hdr_size) > +{ > + struct dst_entry *dst; > + struct flowi6 fl6; > + > + nth->check = ~tcp_v6_check(tcp_hdr_size, &niph->saddr, &niph->daddr, 0); > + nskb->ip_summed = CHECKSUM_PARTIAL; > + nskb->csum_start = (unsigned char *)nth - nskb->head; > + nskb->csum_offset = offsetof(struct tcphdr, check); > + > + memset(&fl6, 0, sizeof(fl6)); > + fl6.flowi6_proto = IPPROTO_TCP; > + fl6.saddr = niph->saddr; > + fl6.daddr = niph->daddr; > + fl6.fl6_sport = nth->source; > + fl6.fl6_dport = nth->dest; > + security_skb_classify_flow((struct sk_buff *)skb, > + flowi6_to_flowi(&fl6)); > + dst = ip6_route_output(net, NULL, &fl6); All good, BUT the above function call also pulls in ipv6.ko. You can fold this patch to avoid it, it coverts it to use the nf_ip6_route() wrapper which internally uses the v6ops pointer for ip6_route_output if needed. diff --git a/net/netfilter/nf_synproxy.c b/net/netfilter/nf_synproxy.c --- a/net/netfilter/nf_synproxy.c +++ b/net/netfilter/nf_synproxy.c @@ -434,6 +434,7 @@ synproxy_send_tcp_ipv6(struct net *net, { struct dst_entry *dst; struct flowi6 fl6; + int err; nth->check = ~tcp_v6_check(tcp_hdr_size, &niph->saddr, &niph->daddr, 0); nskb->ip_summed = CHECKSUM_PARTIAL; @@ -448,11 +449,10 @@ synproxy_send_tcp_ipv6(struct net *net, fl6.fl6_dport = nth->dest; security_skb_classify_flow((struct sk_buff *)skb, flowi6_to_flowi(&fl6)); - dst = ip6_route_output(net, NULL, &fl6); - if (dst->error) { - dst_release(dst); + err = nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false); + if (err) goto free_nskb; - } + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); if (IS_ERR(dst)) goto free_nskb;