[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>
This commit is contained in:
committed by
David S. Miller
parent
3e72b2fe5b
commit
957dc80ac3
@@ -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 @@
|
|||||||
#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)
|
|||||||
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,
|
|||||||
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;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* 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,
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user