Commit 957dc80a authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NETFILTER]: x_tables: add SCTP/DCCP support where missing

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3e72b2fe
...@@ -241,25 +241,17 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config) ...@@ -241,25 +241,17 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
struct iphdr *iph = skb->nh.iph; struct iphdr *iph = skb->nh.iph;
unsigned long hashval; unsigned long hashval;
u_int16_t sport, dport; u_int16_t sport, dport;
struct tcphdr *th; u_int16_t *ports;
struct udphdr *uh;
struct icmphdr *ih;
switch (iph->protocol) { switch (iph->protocol) {
case IPPROTO_TCP: case IPPROTO_TCP:
th = (void *)iph+iph->ihl*4;
sport = ntohs(th->source);
dport = ntohs(th->dest);
break;
case IPPROTO_UDP: case IPPROTO_UDP:
uh = (void *)iph+iph->ihl*4; case IPPROTO_SCTP:
sport = ntohs(uh->source); case IPPROTO_DCCP:
dport = ntohs(uh->dest);
break;
case IPPROTO_ICMP: case IPPROTO_ICMP:
ih = (void *)iph+iph->ihl*4; ports = (void *)iph+iph->ihl*4;
sport = ntohs(ih->un.echo.id); sport = ports[0];
dport = (ih->type<<8)|ih->code; dport = ports[1];
break; break;
default: default:
if (net_ratelimit()) { if (net_ratelimit()) {
......
...@@ -28,9 +28,6 @@ ...@@ -28,9 +28,6 @@
#include <linux/jhash.h> #include <linux/jhash.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/sctp.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/list.h> #include <linux/list.h>
...@@ -381,49 +378,6 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now) ...@@ -381,49 +378,6 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
dh->rateinfo.credit = dh->rateinfo.credit_cap; dh->rateinfo.credit = dh->rateinfo.credit_cap;
} }
static inline int get_ports(const struct sk_buff *skb, int offset,
u16 ports[2])
{
union {
struct tcphdr th;
struct udphdr uh;
sctp_sctphdr_t sctph;
} hdr_u, *ptr_u;
/* Must not be a fragment. */
if (offset)
return 1;
/* Must be big enough to read ports (both UDP and TCP have
them at the start). */
ptr_u = skb_header_pointer(skb, skb->nh.iph->ihl*4, 8, &hdr_u);
if (!ptr_u)
return 1;
switch (skb->nh.iph->protocol) {
case IPPROTO_TCP:
ports[0] = ptr_u->th.source;
ports[1] = ptr_u->th.dest;
break;
case IPPROTO_UDP:
ports[0] = ptr_u->uh.source;
ports[1] = ptr_u->uh.dest;
break;
case IPPROTO_SCTP:
ports[0] = ptr_u->sctph.source;
ports[1] = ptr_u->sctph.dest;
break;
default:
/* all other protocols don't supprot per-port hash
* buckets */
ports[0] = ports[1] = 0;
break;
}
return 0;
}
static int static int
hashlimit_match(const struct sk_buff *skb, hashlimit_match(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *in,
...@@ -449,8 +403,22 @@ hashlimit_match(const struct sk_buff *skb, ...@@ -449,8 +403,22 @@ hashlimit_match(const struct sk_buff *skb,
dst.src_ip = skb->nh.iph->saddr; dst.src_ip = skb->nh.iph->saddr;
if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT
||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) { ||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) {
u_int16_t ports[2]; u_int16_t _ports[2], *ports;
if (get_ports(skb, offset, ports)) {
switch (skb->nh.iph->protocol) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
ports = skb_header_pointer(skb, skb->nh.iph->ihl*4,
sizeof(_ports), &_ports);
break;
default:
_ports[0] = _ports[1] = 0;
ports = _ports;
break;
}
if (!ports) {
/* We've been asked to examine this packet, and we /* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */ can't. Hence, no choice but to drop. */
*hotdrop = 1; *hotdrop = 1;
......
/* Kernel module to match one of a list of TCP/UDP ports: ports are in /* Kernel module to match one of a list of TCP/UDP/SCTP/DCCP ports: ports are in
the same place so we can treat them as equal. */ the same place so we can treat them as equal. */
/* (C) 1999-2001 Paul `Rusty' Russell /* (C) 1999-2001 Paul `Rusty' Russell
...@@ -160,8 +160,9 @@ check(u_int16_t proto, ...@@ -160,8 +160,9 @@ check(u_int16_t proto,
u_int8_t match_flags, u_int8_t match_flags,
u_int8_t count) u_int8_t count)
{ {
/* Must specify proto == TCP/UDP, no unknown flags or bad count */ /* Must specify supported protocol, no unknown flags or bad count */
return (proto == IPPROTO_TCP || proto == IPPROTO_UDP) return (proto == IPPROTO_TCP || proto == IPPROTO_UDP
|| proto == IPPROTO_SCTP || proto == IPPROTO_DCCP)
&& !(ip_invflags & XT_INV_PROTO) && !(ip_invflags & XT_INV_PROTO)
&& (match_flags == XT_MULTIPORT_SOURCE && (match_flags == XT_MULTIPORT_SOURCE
|| match_flags == XT_MULTIPORT_DESTINATION || match_flags == XT_MULTIPORT_DESTINATION
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment