--- zzzz-none-000/linux-5.4.213/net/ipv6/netfilter/nf_reject_ipv6.c 2022-09-15 10:04:56.000000000 +0000 +++ alder-5690pro-762/linux-5.4.213/net/ipv6/netfilter/nf_reject_ipv6.c 2024-08-14 09:02:13.000000000 +0000 @@ -132,7 +132,7 @@ struct sk_buff *nskb; struct tcphdr _otcph; const struct tcphdr *otcph; - unsigned int otcplen, hh_len; + unsigned int otcplen; const struct ipv6hdr *oip6h = ipv6_hdr(oldskb); struct ipv6hdr *ip6h; struct dst_entry *dst = NULL; @@ -154,7 +154,16 @@ fl6.daddr = oip6h->saddr; fl6.fl6_sport = otcph->dest; fl6.fl6_dport = otcph->source; - fl6.flowi6_oif = l3mdev_master_ifindex(skb_dst(oldskb)->dev); + + /* For forwarding packet, the skb->skb_iif is the incoming device's + * ifindex, but it is 0 for local out skb, use dst->dev's ifindex + * instead. + */ + if (oldskb->skb_iif != 0) + fl6.flowi6_oif = oldskb->skb_iif; + else + fl6.flowi6_oif = l3mdev_master_ifindex(skb_dst(oldskb)->dev); + fl6.flowi6_mark = IP6_REPLY_MARK(net, oldskb->mark); security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6)); dst = ip6_route_output(net, NULL, &fl6); @@ -166,8 +175,7 @@ if (IS_ERR(dst)) return; - hh_len = (dst->dev->hard_header_len + 15)&~15; - nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr) + nskb = alloc_skb(LL_MAX_HEADER + sizeof(struct ipv6hdr) + sizeof(struct tcphdr) + dst->trailer_len, GFP_ATOMIC); @@ -181,7 +189,7 @@ nskb->mark = fl6.flowi6_mark; - skb_reserve(nskb, hh_len + dst->header_len); + skb_reserve(nskb, LL_MAX_HEADER); ip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, ip6_dst_hoplimit(dst)); nf_reject_ip6_tcphdr_put(nskb, oldskb, otcph, otcplen);