Fernando Fernandez Mancera <[email protected]> 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;