diff options
author | Patrick McHardy <kaber@trash.net> | 2006-05-29 21:19:56 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-18 00:28:47 -0400 |
commit | 957dc80ac30f3c4d53259fa936df807663ba54fa (patch) | |
tree | 4815a3d43700d79868f50c83b4850502a12a7dd4 | |
parent | 3e72b2fe5b31791f976350b023b7a37ef59c02c1 (diff) |
[NETFILTER]: x_tables: add SCTP/DCCP support where missing
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/netfilter/ipt_CLUSTERIP.c | 20 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_hashlimit.c | 64 | ||||
-rw-r--r-- | net/netfilter/xt_multiport.c | 7 |
3 files changed, 26 insertions, 65 deletions
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index aad9d28c8d71..dbc83c5d7aa6 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -241,25 +241,17 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config) | |||
241 | struct iphdr *iph = skb->nh.iph; | 241 | struct iphdr *iph = skb->nh.iph; |
242 | unsigned long hashval; | 242 | unsigned long hashval; |
243 | u_int16_t sport, dport; | 243 | u_int16_t sport, dport; |
244 | struct tcphdr *th; | 244 | u_int16_t *ports; |
245 | struct udphdr *uh; | ||
246 | struct icmphdr *ih; | ||
247 | 245 | ||
248 | switch (iph->protocol) { | 246 | switch (iph->protocol) { |
249 | case IPPROTO_TCP: | 247 | case IPPROTO_TCP: |
250 | th = (void *)iph+iph->ihl*4; | ||
251 | sport = ntohs(th->source); | ||
252 | dport = ntohs(th->dest); | ||
253 | break; | ||
254 | case IPPROTO_UDP: | 248 | case IPPROTO_UDP: |
255 | uh = (void *)iph+iph->ihl*4; | 249 | case IPPROTO_SCTP: |
256 | sport = ntohs(uh->source); | 250 | case IPPROTO_DCCP: |
257 | dport = ntohs(uh->dest); | ||
258 | break; | ||
259 | case IPPROTO_ICMP: | 251 | case IPPROTO_ICMP: |
260 | ih = (void *)iph+iph->ihl*4; | 252 | ports = (void *)iph+iph->ihl*4; |
261 | sport = ntohs(ih->un.echo.id); | 253 | sport = ports[0]; |
262 | dport = (ih->type<<8)|ih->code; | 254 | dport = ports[1]; |
263 | break; | 255 | break; |
264 | default: | 256 | default: |
265 | if (net_ratelimit()) { | 257 | if (net_ratelimit()) { |
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c index b88adc7f4b47..85edfb79469a 100644 --- a/net/ipv4/netfilter/ipt_hashlimit.c +++ b/net/ipv4/netfilter/ipt_hashlimit.c | |||
@@ -28,9 +28,6 @@ | |||
28 | #include <linux/jhash.h> | 28 | #include <linux/jhash.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
31 | #include <linux/tcp.h> | ||
32 | #include <linux/udp.h> | ||
33 | #include <linux/sctp.h> | ||
34 | #include <linux/proc_fs.h> | 31 | #include <linux/proc_fs.h> |
35 | #include <linux/seq_file.h> | 32 | #include <linux/seq_file.h> |
36 | #include <linux/list.h> | 33 | #include <linux/list.h> |
@@ -381,49 +378,6 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now) | |||
381 | dh->rateinfo.credit = dh->rateinfo.credit_cap; | 378 | dh->rateinfo.credit = dh->rateinfo.credit_cap; |
382 | } | 379 | } |
383 | 380 | ||
384 | static inline int get_ports(const struct sk_buff *skb, int offset, | ||
385 | u16 ports[2]) | ||
386 | { | ||
387 | union { | ||
388 | struct tcphdr th; | ||
389 | struct udphdr uh; | ||
390 | sctp_sctphdr_t sctph; | ||
391 | } hdr_u, *ptr_u; | ||
392 | |||
393 | /* Must not be a fragment. */ | ||
394 | if (offset) | ||
395 | return 1; | ||
396 | |||
397 | /* Must be big enough to read ports (both UDP and TCP have | ||
398 | them at the start). */ | ||
399 | ptr_u = skb_header_pointer(skb, skb->nh.iph->ihl*4, 8, &hdr_u); | ||
400 | if (!ptr_u) | ||
401 | return 1; | ||
402 | |||
403 | switch (skb->nh.iph->protocol) { | ||
404 | case IPPROTO_TCP: | ||
405 | ports[0] = ptr_u->th.source; | ||
406 | ports[1] = ptr_u->th.dest; | ||
407 | break; | ||
408 | case IPPROTO_UDP: | ||
409 | ports[0] = ptr_u->uh.source; | ||
410 | ports[1] = ptr_u->uh.dest; | ||
411 | break; | ||
412 | case IPPROTO_SCTP: | ||
413 | ports[0] = ptr_u->sctph.source; | ||
414 | ports[1] = ptr_u->sctph.dest; | ||
415 | break; | ||
416 | default: | ||
417 | /* all other protocols don't supprot per-port hash | ||
418 | * buckets */ | ||
419 | ports[0] = ports[1] = 0; | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | |||
427 | static int | 381 | static int |
428 | hashlimit_match(const struct sk_buff *skb, | 382 | hashlimit_match(const struct sk_buff *skb, |
429 | const struct net_device *in, | 383 | const struct net_device *in, |
@@ -449,8 +403,22 @@ hashlimit_match(const struct sk_buff *skb, | |||
449 | dst.src_ip = skb->nh.iph->saddr; | 403 | dst.src_ip = skb->nh.iph->saddr; |
450 | if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT | 404 | if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT |
451 | ||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) { | 405 | ||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) { |
452 | u_int16_t ports[2]; | 406 | u_int16_t _ports[2], *ports; |
453 | if (get_ports(skb, offset, ports)) { | 407 | |
408 | switch (skb->nh.iph->protocol) { | ||
409 | case IPPROTO_TCP: | ||
410 | case IPPROTO_UDP: | ||
411 | case IPPROTO_SCTP: | ||
412 | case IPPROTO_DCCP: | ||
413 | ports = skb_header_pointer(skb, skb->nh.iph->ihl*4, | ||
414 | sizeof(_ports), &_ports); | ||
415 | break; | ||
416 | default: | ||
417 | _ports[0] = _ports[1] = 0; | ||
418 | ports = _ports; | ||
419 | break; | ||
420 | } | ||
421 | if (!ports) { | ||
454 | /* We've been asked to examine this packet, and we | 422 | /* We've been asked to examine this packet, and we |
455 | can't. Hence, no choice but to drop. */ | 423 | can't. Hence, no choice but to drop. */ |
456 | *hotdrop = 1; | 424 | *hotdrop = 1; |
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c index b56cd2baaac2..1ff0a25396e7 100644 --- a/net/netfilter/xt_multiport.c +++ b/net/netfilter/xt_multiport.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Kernel module to match one of a list of TCP/UDP ports: ports are in | 1 | /* Kernel module to match one of a list of TCP/UDP/SCTP/DCCP ports: ports are in |
2 | the same place so we can treat them as equal. */ | 2 | the same place so we can treat them as equal. */ |
3 | 3 | ||
4 | /* (C) 1999-2001 Paul `Rusty' Russell | 4 | /* (C) 1999-2001 Paul `Rusty' Russell |
@@ -160,8 +160,9 @@ check(u_int16_t proto, | |||
160 | u_int8_t match_flags, | 160 | u_int8_t match_flags, |
161 | u_int8_t count) | 161 | u_int8_t count) |
162 | { | 162 | { |
163 | /* Must specify proto == TCP/UDP, no unknown flags or bad count */ | 163 | /* Must specify supported protocol, no unknown flags or bad count */ |
164 | return (proto == IPPROTO_TCP || proto == IPPROTO_UDP) | 164 | return (proto == IPPROTO_TCP || proto == IPPROTO_UDP |
165 | || proto == IPPROTO_SCTP || proto == IPPROTO_DCCP) | ||
165 | && !(ip_invflags & XT_INV_PROTO) | 166 | && !(ip_invflags & XT_INV_PROTO) |
166 | && (match_flags == XT_MULTIPORT_SOURCE | 167 | && (match_flags == XT_MULTIPORT_SOURCE |
167 | || match_flags == XT_MULTIPORT_DESTINATION | 168 | || match_flags == XT_MULTIPORT_DESTINATION |