Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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

parent 3e72b2fe
Loading
Loading
Loading
Loading
+6 −14
Original line number Diff line number Diff line
@@ -241,25 +241,17 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
	struct iphdr *iph = skb->nh.iph;
	unsigned long hashval;
	u_int16_t sport, dport;
	struct tcphdr *th;
	struct udphdr *uh;
	struct icmphdr *ih;
	u_int16_t *ports;

	switch (iph->protocol) {
	case IPPROTO_TCP:
		th = (void *)iph+iph->ihl*4;
		sport = ntohs(th->source);
		dport = ntohs(th->dest);
		break;
	case IPPROTO_UDP:
		uh = (void *)iph+iph->ihl*4;
		sport = ntohs(uh->source);
		dport = ntohs(uh->dest);
		break;
	case IPPROTO_SCTP:
	case IPPROTO_DCCP:
	case IPPROTO_ICMP:
		ih = (void *)iph+iph->ihl*4;
		sport = ntohs(ih->un.echo.id);
		dport = (ih->type<<8)|ih->code;
		ports = (void *)iph+iph->ihl*4;
		sport = ports[0];
		dport = ports[1];
		break;
	default:
		if (net_ratelimit()) {
+16 −48
Original line number Diff line number Diff line
@@ -28,9 +28,6 @@
#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/sctp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.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;
}

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
hashlimit_match(const struct sk_buff *skb,
		const struct net_device *in,
@@ -449,8 +403,22 @@ hashlimit_match(const struct sk_buff *skb,
		dst.src_ip = skb->nh.iph->saddr;
	if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT
	    ||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) {
		u_int16_t ports[2];
		if (get_ports(skb, offset, ports)) {
		u_int16_t _ports[2], *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
		 	  can't.  Hence, no choice but to drop. */
			*hotdrop = 1;
+4 −3
Original line number Diff line number Diff line
/* 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. */

/* (C) 1999-2001 Paul `Rusty' Russell
@@ -160,8 +160,9 @@ check(u_int16_t proto,
      u_int8_t match_flags,
      u_int8_t count)
{
	/* Must specify proto == TCP/UDP, no unknown flags or bad count */
	return (proto == IPPROTO_TCP || proto == IPPROTO_UDP)
	/* Must specify supported protocol, no unknown flags or bad count */
	return (proto == IPPROTO_TCP || proto == IPPROTO_UDP
		|| proto == IPPROTO_SCTP || proto == IPPROTO_DCCP)
		&& !(ip_invflags & XT_INV_PROTO)
		&& (match_flags == XT_MULTIPORT_SOURCE
		    || match_flags == XT_MULTIPORT_DESTINATION