Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nat: remove l4proto->manip_pkt

This removes the last l4proto indirection, the two callers, the l3proto
packet mangling helpers for ipv4 and ipv6, now call the
nf_nat_l4proto_manip_pkt() helper.

nf_nat_proto_{dccp,tcp,sctp,gre,icmp,icmpv6} are left behind, even though
they contain no functionality anymore to not clutter this patch.

Next patch will remove the empty files and the nf_nat_l4proto
struct.

nf_nat_proto_udp.c is renamed to nf_nat_proto.c, as it now contains the
other nat manip functionality as well, not just udp and udplite.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
faec18db 76b90019

+365 -357
+7 -8
include/net/netfilter/nf_nat_l4proto.h
··· 12 12 /* Protocol number. */ 13 13 u8 l4proto; 14 14 15 - /* Translate a packet to the target according to manip type. 16 - * Return true if succeeded. 17 - */ 18 - bool (*manip_pkt)(struct sk_buff *skb, 19 - const struct nf_nat_l3proto *l3proto, 20 - unsigned int iphdroff, unsigned int hdroff, 21 - const struct nf_conntrack_tuple *tuple, 22 - enum nf_nat_manip_type maniptype); 23 15 }; 24 16 25 17 /* Protocol registration. */ ··· 20 28 const struct nf_nat_l4proto *l4proto); 21 29 22 30 const struct nf_nat_l4proto *__nf_nat_l4proto_find(u8 l3proto, u8 l4proto); 31 + 32 + /* Translate a packet to the target according to manip type. Return on success. */ 33 + bool nf_nat_l4proto_manip_pkt(struct sk_buff *skb, 34 + const struct nf_nat_l3proto *l3proto, 35 + unsigned int iphdroff, unsigned int hdroff, 36 + const struct nf_conntrack_tuple *tuple, 37 + enum nf_nat_manip_type maniptype); 23 38 24 39 /* Built-in protocols. */ 25 40 extern const struct nf_nat_l4proto nf_nat_l4proto_tcp;
-5
net/ipv4/netfilter/Kconfig
··· 156 156 157 157 To compile it as a module, choose M here. If unsure, say N. 158 158 159 - config NF_NAT_PROTO_GRE 160 - tristate 161 - depends on NF_CT_PROTO_GRE 162 - 163 159 config NF_NAT_PPTP 164 160 tristate 165 161 depends on NF_CONNTRACK 166 162 default NF_CONNTRACK_PPTP 167 - select NF_NAT_PROTO_GRE 168 163 169 164 config NF_NAT_H323 170 165 tristate
+2 -2
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
··· 77 77 iph = (void *)skb->data + iphdroff; 78 78 hdroff = iphdroff + iph->ihl * 4; 79 79 80 - if (!l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv4, iphdroff, hdroff, 81 - target, maniptype)) 80 + if (!nf_nat_l4proto_manip_pkt(skb, &nf_nat_l3proto_ipv4, iphdroff, 81 + hdroff, target, maniptype)) 82 82 return false; 83 83 iph = (void *)skb->data + iphdroff; 84 84
-2
net/ipv4/netfilter/nf_nat_pptp.c
··· 299 299 300 300 static int __init nf_nat_helper_pptp_init(void) 301 301 { 302 - nf_nat_need_gre(); 303 - 304 302 BUG_ON(nf_nat_pptp_hook_outbound != NULL); 305 303 RCU_INIT_POINTER(nf_nat_pptp_hook_outbound, pptp_outbound_pkt); 306 304
-41
net/ipv4/netfilter/nf_nat_proto_gre.c
··· 37 37 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); 38 38 MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); 39 39 40 - /* manipulate a GRE packet according to maniptype */ 41 - static bool 42 - gre_manip_pkt(struct sk_buff *skb, 43 - const struct nf_nat_l3proto *l3proto, 44 - unsigned int iphdroff, unsigned int hdroff, 45 - const struct nf_conntrack_tuple *tuple, 46 - enum nf_nat_manip_type maniptype) 47 - { 48 - const struct gre_base_hdr *greh; 49 - struct pptp_gre_header *pgreh; 50 - 51 - /* pgreh includes two optional 32bit fields which are not required 52 - * to be there. That's where the magic '8' comes from */ 53 - if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8)) 54 - return false; 55 - 56 - greh = (void *)skb->data + hdroff; 57 - pgreh = (struct pptp_gre_header *)greh; 58 - 59 - /* we only have destination manip of a packet, since 'source key' 60 - * is not present in the packet itself */ 61 - if (maniptype != NF_NAT_MANIP_DST) 62 - return true; 63 - 64 - switch (greh->flags & GRE_VERSION) { 65 - case GRE_VERSION_0: 66 - /* We do not currently NAT any GREv0 packets. 67 - * Try to behave like "nf_nat_proto_unknown" */ 68 - break; 69 - case GRE_VERSION_1: 70 - pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); 71 - pgreh->call_id = tuple->dst.u.gre.key; 72 - break; 73 - default: 74 - pr_debug("can't nat unknown GRE version\n"); 75 - return false; 76 - } 77 - return true; 78 - } 79 - 80 40 static const struct nf_nat_l4proto gre = { 81 41 .l4proto = IPPROTO_GRE, 82 - .manip_pkt = gre_manip_pkt, 83 42 }; 84 43 85 44 static int __init nf_nat_proto_gre_init(void)
-21
net/ipv4/netfilter/nf_nat_proto_icmp.c
··· 10 10 #include <linux/init.h> 11 11 #include <linux/export.h> 12 12 #include <linux/ip.h> 13 - #include <linux/icmp.h> 14 13 15 14 #include <linux/netfilter.h> 16 15 #include <net/netfilter/nf_nat.h> 17 16 #include <net/netfilter/nf_nat_core.h> 18 17 #include <net/netfilter/nf_nat_l4proto.h> 19 18 20 - static bool 21 - icmp_manip_pkt(struct sk_buff *skb, 22 - const struct nf_nat_l3proto *l3proto, 23 - unsigned int iphdroff, unsigned int hdroff, 24 - const struct nf_conntrack_tuple *tuple, 25 - enum nf_nat_manip_type maniptype) 26 - { 27 - struct icmphdr *hdr; 28 - 29 - if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 30 - return false; 31 - 32 - hdr = (struct icmphdr *)(skb->data + hdroff); 33 - inet_proto_csum_replace2(&hdr->checksum, skb, 34 - hdr->un.echo.id, tuple->src.u.icmp.id, false); 35 - hdr->un.echo.id = tuple->src.u.icmp.id; 36 - return true; 37 - } 38 - 39 19 const struct nf_nat_l4proto nf_nat_l4proto_icmp = { 40 20 .l4proto = IPPROTO_ICMP, 41 - .manip_pkt = icmp_manip_pkt, 42 21 };
+2 -2
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
··· 83 83 goto manip_addr; 84 84 85 85 if ((frag_off & htons(~0x7)) == 0 && 86 - !l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff, 87 - target, maniptype)) 86 + !nf_nat_l4proto_manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff, 87 + target, maniptype)) 88 88 return false; 89 89 90 90 /* must reload, offset might have changed */
-26
net/ipv6/netfilter/nf_nat_proto_icmpv6.c
··· 19 19 #include <net/netfilter/nf_nat_l3proto.h> 20 20 #include <net/netfilter/nf_nat_l4proto.h> 21 21 22 - static bool 23 - icmpv6_manip_pkt(struct sk_buff *skb, 24 - const struct nf_nat_l3proto *l3proto, 25 - unsigned int iphdroff, unsigned int hdroff, 26 - const struct nf_conntrack_tuple *tuple, 27 - enum nf_nat_manip_type maniptype) 28 - { 29 - struct icmp6hdr *hdr; 30 - 31 - if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 32 - return false; 33 - 34 - hdr = (struct icmp6hdr *)(skb->data + hdroff); 35 - l3proto->csum_update(skb, iphdroff, &hdr->icmp6_cksum, 36 - tuple, maniptype); 37 - if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST || 38 - hdr->icmp6_type == ICMPV6_ECHO_REPLY) { 39 - inet_proto_csum_replace2(&hdr->icmp6_cksum, skb, 40 - hdr->icmp6_identifier, 41 - tuple->src.u.icmp.id, false); 42 - hdr->icmp6_identifier = tuple->src.u.icmp.id; 43 - } 44 - return true; 45 - } 46 - 47 22 const struct nf_nat_l4proto nf_nat_l4proto_icmpv6 = { 48 23 .l4proto = IPPROTO_ICMPV6, 49 - .manip_pkt = icmpv6_manip_pkt, 50 24 };
-15
net/netfilter/Kconfig
··· 403 403 depends on NF_NAT 404 404 default y 405 405 406 - config NF_NAT_PROTO_DCCP 407 - bool 408 - depends on NF_NAT && NF_CT_PROTO_DCCP 409 - default NF_NAT && NF_CT_PROTO_DCCP 410 - 411 - config NF_NAT_PROTO_UDPLITE 412 - bool 413 - depends on NF_NAT && NF_CT_PROTO_UDPLITE 414 - default NF_NAT && NF_CT_PROTO_UDPLITE 415 - 416 - config NF_NAT_PROTO_SCTP 417 - bool 418 - default NF_NAT && NF_CT_PROTO_SCTP 419 - depends on NF_NAT && NF_CT_PROTO_SCTP 420 - 421 406 config NF_NAT_AMANDA 422 407 tristate 423 408 depends on NF_CONNTRACK && NF_NAT
+1 -1
net/netfilter/Makefile
··· 48 48 obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o 49 49 50 50 nf_nat-y := nf_nat_core.o nf_nat_proto_unknown.o \ 51 - nf_nat_proto_udp.o nf_nat_proto_tcp.o nf_nat_helper.o 51 + nf_nat_proto.o nf_nat_proto_tcp.o nf_nat_helper.o 52 52 53 53 # NAT protocols (nf_nat) 54 54 nf_nat-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o
+353
net/netfilter/nf_nat_proto.c
··· 1 + /* (C) 1999-2001 Paul `Rusty' Russell 2 + * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #include <linux/types.h> 10 + #include <linux/export.h> 11 + #include <linux/init.h> 12 + #include <linux/udp.h> 13 + #include <linux/tcp.h> 14 + #include <linux/icmp.h> 15 + #include <linux/icmpv6.h> 16 + 17 + #include <linux/dccp.h> 18 + #include <linux/sctp.h> 19 + #include <net/sctp/checksum.h> 20 + 21 + #include <linux/netfilter.h> 22 + #include <net/netfilter/nf_nat.h> 23 + #include <net/netfilter/nf_nat_core.h> 24 + #include <net/netfilter/nf_nat_l3proto.h> 25 + #include <net/netfilter/nf_nat_l4proto.h> 26 + 27 + static void 28 + __udp_manip_pkt(struct sk_buff *skb, 29 + const struct nf_nat_l3proto *l3proto, 30 + unsigned int iphdroff, struct udphdr *hdr, 31 + const struct nf_conntrack_tuple *tuple, 32 + enum nf_nat_manip_type maniptype, bool do_csum) 33 + { 34 + __be16 *portptr, newport; 35 + 36 + if (maniptype == NF_NAT_MANIP_SRC) { 37 + /* Get rid of src port */ 38 + newport = tuple->src.u.udp.port; 39 + portptr = &hdr->source; 40 + } else { 41 + /* Get rid of dst port */ 42 + newport = tuple->dst.u.udp.port; 43 + portptr = &hdr->dest; 44 + } 45 + if (do_csum) { 46 + l3proto->csum_update(skb, iphdroff, &hdr->check, 47 + tuple, maniptype); 48 + inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, 49 + false); 50 + if (!hdr->check) 51 + hdr->check = CSUM_MANGLED_0; 52 + } 53 + *portptr = newport; 54 + } 55 + 56 + static bool udp_manip_pkt(struct sk_buff *skb, 57 + const struct nf_nat_l3proto *l3proto, 58 + unsigned int iphdroff, unsigned int hdroff, 59 + const struct nf_conntrack_tuple *tuple, 60 + enum nf_nat_manip_type maniptype) 61 + { 62 + struct udphdr *hdr; 63 + bool do_csum; 64 + 65 + if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 66 + return false; 67 + 68 + hdr = (struct udphdr *)(skb->data + hdroff); 69 + do_csum = hdr->check || skb->ip_summed == CHECKSUM_PARTIAL; 70 + 71 + __udp_manip_pkt(skb, l3proto, iphdroff, hdr, tuple, maniptype, do_csum); 72 + return true; 73 + } 74 + 75 + static bool udplite_manip_pkt(struct sk_buff *skb, 76 + const struct nf_nat_l3proto *l3proto, 77 + unsigned int iphdroff, unsigned int hdroff, 78 + const struct nf_conntrack_tuple *tuple, 79 + enum nf_nat_manip_type maniptype) 80 + { 81 + #ifdef CONFIG_NF_CT_PROTO_UDPLITE 82 + struct udphdr *hdr; 83 + 84 + if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 85 + return false; 86 + 87 + hdr = (struct udphdr *)(skb->data + hdroff); 88 + __udp_manip_pkt(skb, l3proto, iphdroff, hdr, tuple, maniptype, true); 89 + #endif 90 + return true; 91 + } 92 + 93 + static bool 94 + sctp_manip_pkt(struct sk_buff *skb, 95 + const struct nf_nat_l3proto *l3proto, 96 + unsigned int iphdroff, unsigned int hdroff, 97 + const struct nf_conntrack_tuple *tuple, 98 + enum nf_nat_manip_type maniptype) 99 + { 100 + #ifdef CONFIG_NF_CT_PROTO_SCTP 101 + struct sctphdr *hdr; 102 + int hdrsize = 8; 103 + 104 + /* This could be an inner header returned in imcp packet; in such 105 + * cases we cannot update the checksum field since it is outside 106 + * of the 8 bytes of transport layer headers we are guaranteed. 107 + */ 108 + if (skb->len >= hdroff + sizeof(*hdr)) 109 + hdrsize = sizeof(*hdr); 110 + 111 + if (!skb_make_writable(skb, hdroff + hdrsize)) 112 + return false; 113 + 114 + hdr = (struct sctphdr *)(skb->data + hdroff); 115 + 116 + if (maniptype == NF_NAT_MANIP_SRC) { 117 + /* Get rid of src port */ 118 + hdr->source = tuple->src.u.sctp.port; 119 + } else { 120 + /* Get rid of dst port */ 121 + hdr->dest = tuple->dst.u.sctp.port; 122 + } 123 + 124 + if (hdrsize < sizeof(*hdr)) 125 + return true; 126 + 127 + if (skb->ip_summed != CHECKSUM_PARTIAL) { 128 + hdr->checksum = sctp_compute_cksum(skb, hdroff); 129 + skb->ip_summed = CHECKSUM_NONE; 130 + } 131 + 132 + #endif 133 + return true; 134 + } 135 + 136 + static bool 137 + tcp_manip_pkt(struct sk_buff *skb, 138 + const struct nf_nat_l3proto *l3proto, 139 + unsigned int iphdroff, unsigned int hdroff, 140 + const struct nf_conntrack_tuple *tuple, 141 + enum nf_nat_manip_type maniptype) 142 + { 143 + struct tcphdr *hdr; 144 + __be16 *portptr, newport, oldport; 145 + int hdrsize = 8; /* TCP connection tracking guarantees this much */ 146 + 147 + /* this could be a inner header returned in icmp packet; in such 148 + cases we cannot update the checksum field since it is outside of 149 + the 8 bytes of transport layer headers we are guaranteed */ 150 + if (skb->len >= hdroff + sizeof(struct tcphdr)) 151 + hdrsize = sizeof(struct tcphdr); 152 + 153 + if (!skb_make_writable(skb, hdroff + hdrsize)) 154 + return false; 155 + 156 + hdr = (struct tcphdr *)(skb->data + hdroff); 157 + 158 + if (maniptype == NF_NAT_MANIP_SRC) { 159 + /* Get rid of src port */ 160 + newport = tuple->src.u.tcp.port; 161 + portptr = &hdr->source; 162 + } else { 163 + /* Get rid of dst port */ 164 + newport = tuple->dst.u.tcp.port; 165 + portptr = &hdr->dest; 166 + } 167 + 168 + oldport = *portptr; 169 + *portptr = newport; 170 + 171 + if (hdrsize < sizeof(*hdr)) 172 + return true; 173 + 174 + l3proto->csum_update(skb, iphdroff, &hdr->check, tuple, maniptype); 175 + inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, false); 176 + return true; 177 + } 178 + 179 + static bool 180 + dccp_manip_pkt(struct sk_buff *skb, 181 + const struct nf_nat_l3proto *l3proto, 182 + unsigned int iphdroff, unsigned int hdroff, 183 + const struct nf_conntrack_tuple *tuple, 184 + enum nf_nat_manip_type maniptype) 185 + { 186 + #ifdef CONFIG_NF_CT_PROTO_DCCP 187 + struct dccp_hdr *hdr; 188 + __be16 *portptr, oldport, newport; 189 + int hdrsize = 8; /* DCCP connection tracking guarantees this much */ 190 + 191 + if (skb->len >= hdroff + sizeof(struct dccp_hdr)) 192 + hdrsize = sizeof(struct dccp_hdr); 193 + 194 + if (!skb_make_writable(skb, hdroff + hdrsize)) 195 + return false; 196 + 197 + hdr = (struct dccp_hdr *)(skb->data + hdroff); 198 + 199 + if (maniptype == NF_NAT_MANIP_SRC) { 200 + newport = tuple->src.u.dccp.port; 201 + portptr = &hdr->dccph_sport; 202 + } else { 203 + newport = tuple->dst.u.dccp.port; 204 + portptr = &hdr->dccph_dport; 205 + } 206 + 207 + oldport = *portptr; 208 + *portptr = newport; 209 + 210 + if (hdrsize < sizeof(*hdr)) 211 + return true; 212 + 213 + l3proto->csum_update(skb, iphdroff, &hdr->dccph_checksum, 214 + tuple, maniptype); 215 + inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport, 216 + false); 217 + #endif 218 + return true; 219 + } 220 + 221 + static bool 222 + icmp_manip_pkt(struct sk_buff *skb, 223 + const struct nf_nat_l3proto *l3proto, 224 + unsigned int iphdroff, unsigned int hdroff, 225 + const struct nf_conntrack_tuple *tuple, 226 + enum nf_nat_manip_type maniptype) 227 + { 228 + struct icmphdr *hdr; 229 + 230 + if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 231 + return false; 232 + 233 + hdr = (struct icmphdr *)(skb->data + hdroff); 234 + inet_proto_csum_replace2(&hdr->checksum, skb, 235 + hdr->un.echo.id, tuple->src.u.icmp.id, false); 236 + hdr->un.echo.id = tuple->src.u.icmp.id; 237 + return true; 238 + } 239 + 240 + static bool 241 + icmpv6_manip_pkt(struct sk_buff *skb, 242 + const struct nf_nat_l3proto *l3proto, 243 + unsigned int iphdroff, unsigned int hdroff, 244 + const struct nf_conntrack_tuple *tuple, 245 + enum nf_nat_manip_type maniptype) 246 + { 247 + struct icmp6hdr *hdr; 248 + 249 + if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 250 + return false; 251 + 252 + hdr = (struct icmp6hdr *)(skb->data + hdroff); 253 + l3proto->csum_update(skb, iphdroff, &hdr->icmp6_cksum, 254 + tuple, maniptype); 255 + if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST || 256 + hdr->icmp6_type == ICMPV6_ECHO_REPLY) { 257 + inet_proto_csum_replace2(&hdr->icmp6_cksum, skb, 258 + hdr->icmp6_identifier, 259 + tuple->src.u.icmp.id, false); 260 + hdr->icmp6_identifier = tuple->src.u.icmp.id; 261 + } 262 + return true; 263 + } 264 + 265 + /* manipulate a GRE packet according to maniptype */ 266 + static bool 267 + gre_manip_pkt(struct sk_buff *skb, 268 + const struct nf_nat_l3proto *l3proto, 269 + unsigned int iphdroff, unsigned int hdroff, 270 + const struct nf_conntrack_tuple *tuple, 271 + enum nf_nat_manip_type maniptype) 272 + { 273 + #if IS_ENABLED(CONFIG_NF_CT_PROTO_GRE) 274 + const struct gre_base_hdr *greh; 275 + struct pptp_gre_header *pgreh; 276 + 277 + /* pgreh includes two optional 32bit fields which are not required 278 + * to be there. That's where the magic '8' comes from */ 279 + if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8)) 280 + return false; 281 + 282 + greh = (void *)skb->data + hdroff; 283 + pgreh = (struct pptp_gre_header *)greh; 284 + 285 + /* we only have destination manip of a packet, since 'source key' 286 + * is not present in the packet itself */ 287 + if (maniptype != NF_NAT_MANIP_DST) 288 + return true; 289 + 290 + switch (greh->flags & GRE_VERSION) { 291 + case GRE_VERSION_0: 292 + /* We do not currently NAT any GREv0 packets. 293 + * Try to behave like "nf_nat_proto_unknown" */ 294 + break; 295 + case GRE_VERSION_1: 296 + pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); 297 + pgreh->call_id = tuple->dst.u.gre.key; 298 + break; 299 + default: 300 + pr_debug("can't nat unknown GRE version\n"); 301 + return false; 302 + } 303 + #endif 304 + return true; 305 + } 306 + 307 + bool nf_nat_l4proto_manip_pkt(struct sk_buff *skb, 308 + const struct nf_nat_l3proto *l3proto, 309 + unsigned int iphdroff, unsigned int hdroff, 310 + const struct nf_conntrack_tuple *tuple, 311 + enum nf_nat_manip_type maniptype) 312 + { 313 + switch (tuple->dst.protonum) { 314 + case IPPROTO_TCP: 315 + return tcp_manip_pkt(skb, l3proto, iphdroff, hdroff, 316 + tuple, maniptype); 317 + case IPPROTO_UDP: 318 + return udp_manip_pkt(skb, l3proto, iphdroff, hdroff, 319 + tuple, maniptype); 320 + case IPPROTO_UDPLITE: 321 + return udplite_manip_pkt(skb, l3proto, iphdroff, hdroff, 322 + tuple, maniptype); 323 + case IPPROTO_SCTP: 324 + return sctp_manip_pkt(skb, l3proto, iphdroff, hdroff, 325 + tuple, maniptype); 326 + case IPPROTO_ICMP: 327 + return icmp_manip_pkt(skb, l3proto, iphdroff, hdroff, 328 + tuple, maniptype); 329 + case IPPROTO_ICMPV6: 330 + return icmpv6_manip_pkt(skb, l3proto, iphdroff, hdroff, 331 + tuple, maniptype); 332 + case IPPROTO_DCCP: 333 + return dccp_manip_pkt(skb, l3proto, iphdroff, hdroff, 334 + tuple, maniptype); 335 + case IPPROTO_GRE: 336 + return gre_manip_pkt(skb, l3proto, iphdroff, hdroff, 337 + tuple, maniptype); 338 + } 339 + 340 + /* If we don't know protocol -- no error, pass it unmodified. */ 341 + return true; 342 + } 343 + EXPORT_SYMBOL_GPL(nf_nat_l4proto_manip_pkt); 344 + 345 + #ifdef CONFIG_NF_NAT_PROTO_UDPLITE 346 + const struct nf_nat_l4proto nf_nat_l4proto_udplite = { 347 + .l4proto = IPPROTO_UDPLITE, 348 + }; 349 + #endif /* CONFIG_NF_NAT_PROTO_UDPLITE */ 350 + 351 + const struct nf_nat_l4proto nf_nat_l4proto_udp = { 352 + .l4proto = IPPROTO_UDP, 353 + };
-42
net/netfilter/nf_nat_proto_dccp.c
··· 11 11 12 12 #include <linux/kernel.h> 13 13 #include <linux/skbuff.h> 14 - #include <linux/dccp.h> 15 14 16 15 #include <net/netfilter/nf_conntrack.h> 17 16 #include <net/netfilter/nf_nat.h> 18 17 #include <net/netfilter/nf_nat_l3proto.h> 19 18 #include <net/netfilter/nf_nat_l4proto.h> 20 19 21 - static bool 22 - dccp_manip_pkt(struct sk_buff *skb, 23 - const struct nf_nat_l3proto *l3proto, 24 - unsigned int iphdroff, unsigned int hdroff, 25 - const struct nf_conntrack_tuple *tuple, 26 - enum nf_nat_manip_type maniptype) 27 - { 28 - struct dccp_hdr *hdr; 29 - __be16 *portptr, oldport, newport; 30 - int hdrsize = 8; /* DCCP connection tracking guarantees this much */ 31 - 32 - if (skb->len >= hdroff + sizeof(struct dccp_hdr)) 33 - hdrsize = sizeof(struct dccp_hdr); 34 - 35 - if (!skb_make_writable(skb, hdroff + hdrsize)) 36 - return false; 37 - 38 - hdr = (struct dccp_hdr *)(skb->data + hdroff); 39 - 40 - if (maniptype == NF_NAT_MANIP_SRC) { 41 - newport = tuple->src.u.dccp.port; 42 - portptr = &hdr->dccph_sport; 43 - } else { 44 - newport = tuple->dst.u.dccp.port; 45 - portptr = &hdr->dccph_dport; 46 - } 47 - 48 - oldport = *portptr; 49 - *portptr = newport; 50 - 51 - if (hdrsize < sizeof(*hdr)) 52 - return true; 53 - 54 - l3proto->csum_update(skb, iphdroff, &hdr->dccph_checksum, 55 - tuple, maniptype); 56 - inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport, 57 - false); 58 - return true; 59 - } 60 - 61 20 const struct nf_nat_l4proto nf_nat_l4proto_dccp = { 62 21 .l4proto = IPPROTO_DCCP, 63 - .manip_pkt = dccp_manip_pkt, 64 22 };
-43
net/netfilter/nf_nat_proto_sctp.c
··· 7 7 */ 8 8 9 9 #include <linux/types.h> 10 - #include <linux/sctp.h> 11 - #include <net/sctp/checksum.h> 12 10 13 11 #include <net/netfilter/nf_nat_l4proto.h> 14 12 15 - static bool 16 - sctp_manip_pkt(struct sk_buff *skb, 17 - const struct nf_nat_l3proto *l3proto, 18 - unsigned int iphdroff, unsigned int hdroff, 19 - const struct nf_conntrack_tuple *tuple, 20 - enum nf_nat_manip_type maniptype) 21 - { 22 - struct sctphdr *hdr; 23 - int hdrsize = 8; 24 - 25 - /* This could be an inner header returned in imcp packet; in such 26 - * cases we cannot update the checksum field since it is outside 27 - * of the 8 bytes of transport layer headers we are guaranteed. 28 - */ 29 - if (skb->len >= hdroff + sizeof(*hdr)) 30 - hdrsize = sizeof(*hdr); 31 - 32 - if (!skb_make_writable(skb, hdroff + hdrsize)) 33 - return false; 34 - 35 - hdr = (struct sctphdr *)(skb->data + hdroff); 36 - 37 - if (maniptype == NF_NAT_MANIP_SRC) { 38 - /* Get rid of src port */ 39 - hdr->source = tuple->src.u.sctp.port; 40 - } else { 41 - /* Get rid of dst port */ 42 - hdr->dest = tuple->dst.u.sctp.port; 43 - } 44 - 45 - if (hdrsize < sizeof(*hdr)) 46 - return true; 47 - 48 - if (skb->ip_summed != CHECKSUM_PARTIAL) { 49 - hdr->checksum = sctp_compute_cksum(skb, hdroff); 50 - skb->ip_summed = CHECKSUM_NONE; 51 - } 52 - 53 - return true; 54 - } 55 13 56 14 const struct nf_nat_l4proto nf_nat_l4proto_sctp = { 57 15 .l4proto = IPPROTO_SCTP, 58 - .manip_pkt = sctp_manip_pkt, 59 16 };
-44
net/netfilter/nf_nat_proto_tcp.c
··· 18 18 #include <net/netfilter/nf_nat_l4proto.h> 19 19 #include <net/netfilter/nf_nat_core.h> 20 20 21 - static bool 22 - tcp_manip_pkt(struct sk_buff *skb, 23 - const struct nf_nat_l3proto *l3proto, 24 - unsigned int iphdroff, unsigned int hdroff, 25 - const struct nf_conntrack_tuple *tuple, 26 - enum nf_nat_manip_type maniptype) 27 - { 28 - struct tcphdr *hdr; 29 - __be16 *portptr, newport, oldport; 30 - int hdrsize = 8; /* TCP connection tracking guarantees this much */ 31 - 32 - /* this could be a inner header returned in icmp packet; in such 33 - cases we cannot update the checksum field since it is outside of 34 - the 8 bytes of transport layer headers we are guaranteed */ 35 - if (skb->len >= hdroff + sizeof(struct tcphdr)) 36 - hdrsize = sizeof(struct tcphdr); 37 - 38 - if (!skb_make_writable(skb, hdroff + hdrsize)) 39 - return false; 40 - 41 - hdr = (struct tcphdr *)(skb->data + hdroff); 42 - 43 - if (maniptype == NF_NAT_MANIP_SRC) { 44 - /* Get rid of src port */ 45 - newport = tuple->src.u.tcp.port; 46 - portptr = &hdr->source; 47 - } else { 48 - /* Get rid of dst port */ 49 - newport = tuple->dst.u.tcp.port; 50 - portptr = &hdr->dest; 51 - } 52 - 53 - oldport = *portptr; 54 - *portptr = newport; 55 - 56 - if (hdrsize < sizeof(*hdr)) 57 - return true; 58 - 59 - l3proto->csum_update(skb, iphdroff, &hdr->check, tuple, maniptype); 60 - inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, false); 61 - return true; 62 - } 63 - 64 21 const struct nf_nat_l4proto nf_nat_l4proto_tcp = { 65 22 .l4proto = IPPROTO_TCP, 66 - .manip_pkt = tcp_manip_pkt, 67 23 };
-94
net/netfilter/nf_nat_proto_udp.c
··· 1 - /* (C) 1999-2001 Paul `Rusty' Russell 2 - * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 as 6 - * published by the Free Software Foundation. 7 - */ 8 - 9 - #include <linux/types.h> 10 - #include <linux/export.h> 11 - #include <linux/init.h> 12 - #include <linux/udp.h> 13 - 14 - #include <linux/netfilter.h> 15 - #include <net/netfilter/nf_nat.h> 16 - #include <net/netfilter/nf_nat_core.h> 17 - #include <net/netfilter/nf_nat_l3proto.h> 18 - #include <net/netfilter/nf_nat_l4proto.h> 19 - 20 - static void 21 - __udp_manip_pkt(struct sk_buff *skb, 22 - const struct nf_nat_l3proto *l3proto, 23 - unsigned int iphdroff, struct udphdr *hdr, 24 - const struct nf_conntrack_tuple *tuple, 25 - enum nf_nat_manip_type maniptype, bool do_csum) 26 - { 27 - __be16 *portptr, newport; 28 - 29 - if (maniptype == NF_NAT_MANIP_SRC) { 30 - /* Get rid of src port */ 31 - newport = tuple->src.u.udp.port; 32 - portptr = &hdr->source; 33 - } else { 34 - /* Get rid of dst port */ 35 - newport = tuple->dst.u.udp.port; 36 - portptr = &hdr->dest; 37 - } 38 - if (do_csum) { 39 - l3proto->csum_update(skb, iphdroff, &hdr->check, 40 - tuple, maniptype); 41 - inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, 42 - false); 43 - if (!hdr->check) 44 - hdr->check = CSUM_MANGLED_0; 45 - } 46 - *portptr = newport; 47 - } 48 - 49 - static bool udp_manip_pkt(struct sk_buff *skb, 50 - const struct nf_nat_l3proto *l3proto, 51 - unsigned int iphdroff, unsigned int hdroff, 52 - const struct nf_conntrack_tuple *tuple, 53 - enum nf_nat_manip_type maniptype) 54 - { 55 - struct udphdr *hdr; 56 - bool do_csum; 57 - 58 - if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 59 - return false; 60 - 61 - hdr = (struct udphdr *)(skb->data + hdroff); 62 - do_csum = hdr->check || skb->ip_summed == CHECKSUM_PARTIAL; 63 - 64 - __udp_manip_pkt(skb, l3proto, iphdroff, hdr, tuple, maniptype, do_csum); 65 - return true; 66 - } 67 - 68 - #ifdef CONFIG_NF_NAT_PROTO_UDPLITE 69 - static bool udplite_manip_pkt(struct sk_buff *skb, 70 - const struct nf_nat_l3proto *l3proto, 71 - unsigned int iphdroff, unsigned int hdroff, 72 - const struct nf_conntrack_tuple *tuple, 73 - enum nf_nat_manip_type maniptype) 74 - { 75 - struct udphdr *hdr; 76 - 77 - if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 78 - return false; 79 - 80 - hdr = (struct udphdr *)(skb->data + hdroff); 81 - __udp_manip_pkt(skb, l3proto, iphdroff, hdr, tuple, maniptype, true); 82 - return true; 83 - } 84 - 85 - const struct nf_nat_l4proto nf_nat_l4proto_udplite = { 86 - .l4proto = IPPROTO_UDPLITE, 87 - .manip_pkt = udplite_manip_pkt, 88 - }; 89 - #endif /* CONFIG_NF_NAT_PROTO_UDPLITE */ 90 - 91 - const struct nf_nat_l4proto nf_nat_l4proto_udp = { 92 - .l4proto = IPPROTO_UDP, 93 - .manip_pkt = udp_manip_pkt, 94 - };
-11
net/netfilter/nf_nat_proto_unknown.c
··· 17 17 #include <net/netfilter/nf_nat.h> 18 18 #include <net/netfilter/nf_nat_l4proto.h> 19 19 20 - static bool 21 - unknown_manip_pkt(struct sk_buff *skb, 22 - const struct nf_nat_l3proto *l3proto, 23 - unsigned int iphdroff, unsigned int hdroff, 24 - const struct nf_conntrack_tuple *tuple, 25 - enum nf_nat_manip_type maniptype) 26 - { 27 - return true; 28 - } 29 - 30 20 const struct nf_nat_l4proto nf_nat_l4proto_unknown = { 31 - .manip_pkt = unknown_manip_pkt, 32 21 };