netfilter: nat: remove csum_update hook

We can now use direct calls.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Florian Westphal 2019-02-19 17:38:24 +01:00 committed by Pablo Neira Ayuso
parent 2e666b229d
commit 03fe5efc4c
2 changed files with 36 additions and 38 deletions

View File

@ -5,11 +5,6 @@
struct nf_nat_l3proto { struct nf_nat_l3proto {
u8 l3proto; u8 l3proto;
void (*csum_update)(struct sk_buff *skb, unsigned int iphdroff,
__sum16 *check,
const struct nf_conntrack_tuple *t,
enum nf_nat_manip_type maniptype);
void (*csum_recalc)(struct sk_buff *skb, u8 proto, void (*csum_recalc)(struct sk_buff *skb, u8 proto,
void *data, __sum16 *check, void *data, __sum16 *check,
int datalen, int oldlen); int datalen, int oldlen);

View File

@ -40,9 +40,13 @@ static const struct nf_nat_l3proto nf_nat_l3proto_ipv4;
static const struct nf_nat_l3proto nf_nat_l3proto_ipv6; static const struct nf_nat_l3proto nf_nat_l3proto_ipv6;
#endif #endif
static void nf_csum_update(struct sk_buff *skb,
unsigned int iphdroff, __sum16 *check,
const struct nf_conntrack_tuple *t,
enum nf_nat_manip_type maniptype);
static void static void
__udp_manip_pkt(struct sk_buff *skb, __udp_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, struct udphdr *hdr, unsigned int iphdroff, struct udphdr *hdr,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype, bool do_csum) enum nf_nat_manip_type maniptype, bool do_csum)
@ -59,8 +63,7 @@ __udp_manip_pkt(struct sk_buff *skb,
portptr = &hdr->dest; portptr = &hdr->dest;
} }
if (do_csum) { if (do_csum) {
l3proto->csum_update(skb, iphdroff, &hdr->check, nf_csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
tuple, maniptype);
inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport,
false); false);
if (!hdr->check) if (!hdr->check)
@ -70,7 +73,6 @@ __udp_manip_pkt(struct sk_buff *skb,
} }
static bool udp_manip_pkt(struct sk_buff *skb, static bool udp_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -84,12 +86,11 @@ static bool udp_manip_pkt(struct sk_buff *skb,
hdr = (struct udphdr *)(skb->data + hdroff); hdr = (struct udphdr *)(skb->data + hdroff);
do_csum = hdr->check || skb->ip_summed == CHECKSUM_PARTIAL; do_csum = hdr->check || skb->ip_summed == CHECKSUM_PARTIAL;
__udp_manip_pkt(skb, l3proto, iphdroff, hdr, tuple, maniptype, do_csum); __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, do_csum);
return true; return true;
} }
static bool udplite_manip_pkt(struct sk_buff *skb, static bool udplite_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -101,14 +102,13 @@ static bool udplite_manip_pkt(struct sk_buff *skb,
return false; return false;
hdr = (struct udphdr *)(skb->data + hdroff); hdr = (struct udphdr *)(skb->data + hdroff);
__udp_manip_pkt(skb, l3proto, iphdroff, hdr, tuple, maniptype, true); __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, true);
#endif #endif
return true; return true;
} }
static bool static bool
sctp_manip_pkt(struct sk_buff *skb, sctp_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -151,7 +151,6 @@ sctp_manip_pkt(struct sk_buff *skb,
static bool static bool
tcp_manip_pkt(struct sk_buff *skb, tcp_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -187,14 +186,13 @@ tcp_manip_pkt(struct sk_buff *skb,
if (hdrsize < sizeof(*hdr)) if (hdrsize < sizeof(*hdr))
return true; return true;
l3proto->csum_update(skb, iphdroff, &hdr->check, tuple, maniptype); nf_csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, false); inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, false);
return true; return true;
} }
static bool static bool
dccp_manip_pkt(struct sk_buff *skb, dccp_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -226,8 +224,7 @@ dccp_manip_pkt(struct sk_buff *skb,
if (hdrsize < sizeof(*hdr)) if (hdrsize < sizeof(*hdr))
return true; return true;
l3proto->csum_update(skb, iphdroff, &hdr->dccph_checksum, nf_csum_update(skb, iphdroff, &hdr->dccph_checksum, tuple, maniptype);
tuple, maniptype);
inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport, inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport,
false); false);
#endif #endif
@ -236,7 +233,6 @@ dccp_manip_pkt(struct sk_buff *skb,
static bool static bool
icmp_manip_pkt(struct sk_buff *skb, icmp_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -255,7 +251,6 @@ icmp_manip_pkt(struct sk_buff *skb,
static bool static bool
icmpv6_manip_pkt(struct sk_buff *skb, icmpv6_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -266,8 +261,7 @@ icmpv6_manip_pkt(struct sk_buff *skb,
return false; return false;
hdr = (struct icmp6hdr *)(skb->data + hdroff); hdr = (struct icmp6hdr *)(skb->data + hdroff);
l3proto->csum_update(skb, iphdroff, &hdr->icmp6_cksum, nf_csum_update(skb, iphdroff, &hdr->icmp6_cksum, tuple, maniptype);
tuple, maniptype);
if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST || if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST ||
hdr->icmp6_type == ICMPV6_ECHO_REPLY) { hdr->icmp6_type == ICMPV6_ECHO_REPLY) {
inet_proto_csum_replace2(&hdr->icmp6_cksum, skb, inet_proto_csum_replace2(&hdr->icmp6_cksum, skb,
@ -281,7 +275,6 @@ icmpv6_manip_pkt(struct sk_buff *skb,
/* manipulate a GRE packet according to maniptype */ /* manipulate a GRE packet according to maniptype */
static bool static bool
gre_manip_pkt(struct sk_buff *skb, gre_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
@ -321,35 +314,34 @@ gre_manip_pkt(struct sk_buff *skb,
} }
static bool l4proto_manip_pkt(struct sk_buff *skb, static bool l4proto_manip_pkt(struct sk_buff *skb,
const struct nf_nat_l3proto *l3proto,
unsigned int iphdroff, unsigned int hdroff, unsigned int iphdroff, unsigned int hdroff,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype) enum nf_nat_manip_type maniptype)
{ {
switch (tuple->dst.protonum) { switch (tuple->dst.protonum) {
case IPPROTO_TCP: case IPPROTO_TCP:
return tcp_manip_pkt(skb, l3proto, iphdroff, hdroff, return tcp_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
case IPPROTO_UDP: case IPPROTO_UDP:
return udp_manip_pkt(skb, l3proto, iphdroff, hdroff, return udp_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
case IPPROTO_UDPLITE: case IPPROTO_UDPLITE:
return udplite_manip_pkt(skb, l3proto, iphdroff, hdroff, return udplite_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
case IPPROTO_SCTP: case IPPROTO_SCTP:
return sctp_manip_pkt(skb, l3proto, iphdroff, hdroff, return sctp_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
case IPPROTO_ICMP: case IPPROTO_ICMP:
return icmp_manip_pkt(skb, l3proto, iphdroff, hdroff, return icmp_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
case IPPROTO_ICMPV6: case IPPROTO_ICMPV6:
return icmpv6_manip_pkt(skb, l3proto, iphdroff, hdroff, return icmpv6_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
case IPPROTO_DCCP: case IPPROTO_DCCP:
return dccp_manip_pkt(skb, l3proto, iphdroff, hdroff, return dccp_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
case IPPROTO_GRE: case IPPROTO_GRE:
return gre_manip_pkt(skb, l3proto, iphdroff, hdroff, return gre_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype); tuple, maniptype);
} }
@ -371,8 +363,7 @@ static bool nf_nat_ipv4_manip_pkt(struct sk_buff *skb,
iph = (void *)skb->data + iphdroff; iph = (void *)skb->data + iphdroff;
hdroff = iphdroff + iph->ihl * 4; hdroff = iphdroff + iph->ihl * 4;
if (!l4proto_manip_pkt(skb, &nf_nat_l3proto_ipv4, iphdroff, if (!l4proto_manip_pkt(skb, iphdroff, hdroff, target, maniptype))
hdroff, target, maniptype))
return false; return false;
iph = (void *)skb->data + iphdroff; iph = (void *)skb->data + iphdroff;
@ -408,8 +399,7 @@ static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb,
goto manip_addr; goto manip_addr;
if ((frag_off & htons(~0x7)) == 0 && if ((frag_off & htons(~0x7)) == 0 &&
!l4proto_manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff, !l4proto_manip_pkt(skb, iphdroff, hdroff, target, maniptype))
target, maniptype))
return false; return false;
/* must reload, offset might have changed */ /* must reload, offset might have changed */
@ -490,6 +480,21 @@ static void nf_nat_ipv6_csum_update(struct sk_buff *skb,
#endif #endif
} }
static void nf_csum_update(struct sk_buff *skb,
unsigned int iphdroff, __sum16 *check,
const struct nf_conntrack_tuple *t,
enum nf_nat_manip_type maniptype)
{
switch (t->src.l3num) {
case NFPROTO_IPV4:
nf_nat_ipv4_csum_update(skb, iphdroff, check, t, maniptype);
return;
case NFPROTO_IPV6:
nf_nat_ipv6_csum_update(skb, iphdroff, check, t, maniptype);
return;
}
}
static void nf_nat_ipv4_csum_recalc(struct sk_buff *skb, static void nf_nat_ipv4_csum_recalc(struct sk_buff *skb,
u8 proto, void *data, __sum16 *check, u8 proto, void *data, __sum16 *check,
int datalen, int oldlen) int datalen, int oldlen)
@ -532,7 +537,6 @@ static void nf_nat_ipv6_csum_recalc(struct sk_buff *skb,
static const struct nf_nat_l3proto nf_nat_l3proto_ipv4 = { static const struct nf_nat_l3proto nf_nat_l3proto_ipv4 = {
.l3proto = NFPROTO_IPV4, .l3proto = NFPROTO_IPV4,
.csum_update = nf_nat_ipv4_csum_update,
.csum_recalc = nf_nat_ipv4_csum_recalc, .csum_recalc = nf_nat_ipv4_csum_recalc,
}; };
@ -784,7 +788,6 @@ void nf_nat_l3proto_exit(void)
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
static const struct nf_nat_l3proto nf_nat_l3proto_ipv6 = { static const struct nf_nat_l3proto nf_nat_l3proto_ipv6 = {
.l3proto = NFPROTO_IPV6, .l3proto = NFPROTO_IPV6,
.csum_update = nf_nat_ipv6_csum_update,
.csum_recalc = nf_nat_ipv6_csum_recalc, .csum_recalc = nf_nat_ipv6_csum_recalc,
}; };