From: Patrick McHardy <kaber@trash.net>
To: netfilter-devel@lists.netfilter.org
Cc: juha.heljoranta@evtek.fi, Rusty Russell <rusty@rustcorp.com.au>
Subject: [netfilter socket hooks 2/5]: Add protocol hooks
Date: Tue, 10 May 2005 18:00:34 +0200 [thread overview]
Message-ID: <4280DAA2.2030708@trash.net> (raw)
In-Reply-To: <4280DA51.8090201@trash.net>
[-- Attachment #1: 02.diff --]
[-- Type: text/x-patch, Size: 9709 bytes --]
[NETFILTER]: Add protocol hooks
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 03a2e97e71c3c9bfbfc3d357544348d393551658
tree b53df6f327c03ec282a1b75326db321dbd2f0bc0
parent 4ca9ffc0b58dd44e91cbaaa2de3c27faa220e047
author Patrick McHardy <kaber@trash.net> Mon, 09 May 2005 18:34:53 +0200
committer Patrick McHardy <kaber@trash.net> Mon, 09 May 2005 18:34:53 +0200
net/ipv4/raw.c | 8 ++-
net/ipv4/tcp_ipv4.c | 123 +++++++++++++++++++++++++++++++++-------------------
net/ipv4/udp.c | 109 +++++++++++++++++++++++++++-------------------
3 files changed, 151 insertions(+), 89 deletions(-)
Index: net/ipv4/raw.c
===================================================================
--- e97143c76936d02bb1817a1e109e36707202a6bb/net/ipv4/raw.c (mode:100644)
+++ b53df6f327c03ec282a1b75326db321dbd2f0bc0/net/ipv4/raw.c (mode:100644)
@@ -246,7 +246,7 @@
return NET_RX_SUCCESS;
}
-int raw_rcv(struct sock *sk, struct sk_buff *skb)
+static inline int raw_rcv_finish(struct sock *sk, struct sk_buff *skb)
{
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
kfree_skb(skb);
@@ -259,6 +259,12 @@
return 0;
}
+int raw_rcv(struct sock *sk, struct sk_buff *skb)
+{
+ return NF_SK_HOOK(AF_INET, NF_IP_LOCAL_IN, sk, skb, skb->dev, NULL,
+ raw_rcv_finish, NULL);
+}
+
static int raw_send_hdrinc(struct sock *sk, void *from, int length,
struct rtable *rt,
unsigned int flags)
Index: net/ipv4/tcp_ipv4.c
===================================================================
--- e97143c76936d02bb1817a1e109e36707202a6bb/net/ipv4/tcp_ipv4.c (mode:100644)
+++ b53df6f327c03ec282a1b75326db321dbd2f0bc0/net/ipv4/tcp_ipv4.c (mode:100644)
@@ -62,6 +62,8 @@
#include <linux/jhash.h>
#include <linux/init.h>
#include <linux/times.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
#include <net/icmp.h>
#include <net/tcp.h>
@@ -1713,52 +1715,24 @@
goto discard;
}
-/*
- * From tcp_input.c
- */
-
-int tcp_v4_rcv(struct sk_buff *skb)
+/* Dummy outfn for netfilter - caller still owns the skb */
+static inline int tcp_v4_rcv_finish2(struct sock *sk, struct sk_buff *skb)
{
- struct tcphdr *th;
- struct sock *sk;
- int ret;
-
- if (skb->pkt_type != PACKET_HOST)
- goto discard_it;
-
- /* Count it even if it's bad */
- TCP_INC_STATS_BH(TCP_MIB_INSEGS);
-
- if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
- goto discard_it;
-
- th = skb->h.th;
-
- if (th->doff < sizeof(struct tcphdr) / 4)
- goto bad_packet;
- if (!pskb_may_pull(skb, th->doff * 4))
- goto discard_it;
-
- /* An explanation is required here, I think.
- * Packet length and doff are validated by header prediction,
- * provided case of th->doff==0 is elimineted.
- * So, we defer the checks. */
- if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
- tcp_v4_checksum_init(skb) < 0))
- goto bad_packet;
+ return 0;
+}
- th = skb->h.th;
- TCP_SKB_CB(skb)->seq = ntohl(th->seq);
- TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
- skb->len - th->doff * 4);
- TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
- TCP_SKB_CB(skb)->when = 0;
- TCP_SKB_CB(skb)->flags = skb->nh.iph->tos;
- TCP_SKB_CB(skb)->sacked = 0;
+static inline void tcp_sock_put(struct sock *sk)
+{
+ if (sk->sk_state == TCP_TIME_WAIT)
+ tcp_tw_put((struct tcp_tw_bucket *)sk);
+ else
+ sock_put(sk);
+}
- sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
- skb->nh.iph->daddr, ntohs(th->dest),
- tcp_v4_iif(skb));
+static inline int tcp_v4_rcv_finish(struct sock *sk, struct sk_buff *skb)
+{
+ struct tcphdr *th = skb->h.th;
+ int ret;
if (!sk)
goto no_tcp_socket;
@@ -1793,7 +1767,6 @@
goto discard_it;
if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
-bad_packet:
TCP_INC_STATS_BH(TCP_MIB_INERRS);
} else {
tcp_v4_send_reset(skb);
@@ -1829,6 +1802,11 @@
tcp_tw_deschedule((struct tcp_tw_bucket *)sk);
tcp_tw_put((struct tcp_tw_bucket *)sk);
sk = sk2;
+ ret = NF_SK_HOOK(AF_INET, NF_IP_LOCAL_IN, sk, skb,
+ skb->dev, NULL, tcp_v4_rcv_finish2,
+ tcp_sock_put);
+ if (ret)
+ return ret;
goto process;
}
/* Fall through to ACK */
@@ -1843,6 +1821,63 @@
goto discard_it;
}
+/*
+ * From tcp_input.c
+ */
+
+int tcp_v4_rcv(struct sk_buff *skb)
+{
+ struct tcphdr *th;
+ struct sock *sk;
+
+ if (skb->pkt_type != PACKET_HOST)
+ goto discard_it;
+
+ /* Count it even if it's bad */
+ TCP_INC_STATS_BH(TCP_MIB_INSEGS);
+
+ if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
+ goto discard_it;
+
+ th = skb->h.th;
+
+ if (th->doff < sizeof(struct tcphdr) / 4)
+ goto bad_packet;
+ if (!pskb_may_pull(skb, th->doff * 4))
+ goto discard_it;
+
+ /* An explanation is required here, I think.
+ * Packet length and doff are validated by header prediction,
+ * provided case of th->doff==0 is elimineted.
+ * So, we defer the checks. */
+ if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
+ tcp_v4_checksum_init(skb) < 0))
+ goto bad_packet;
+
+ th = skb->h.th;
+ TCP_SKB_CB(skb)->seq = ntohl(th->seq);
+ TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
+ skb->len - th->doff * 4);
+ TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
+ TCP_SKB_CB(skb)->when = 0;
+ TCP_SKB_CB(skb)->flags = skb->nh.iph->tos;
+ TCP_SKB_CB(skb)->sacked = 0;
+
+ sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
+ skb->nh.iph->daddr, ntohs(th->dest),
+ tcp_v4_iif(skb));
+
+ return NF_SK_HOOK(AF_INET, NF_IP_LOCAL_IN, sk, skb, skb->dev, NULL,
+ tcp_v4_rcv_finish, tcp_sock_put);
+
+bad_packet:
+ TCP_INC_STATS_BH(TCP_MIB_INERRS);
+discard_it:
+ /* Discard frame. */
+ kfree_skb(skb);
+ return 0;
+}
+
/* With per-bucket locks this operation is not-atomic, so that
* this version is not worse.
*/
Index: net/ipv4/udp.c
===================================================================
--- e97143c76936d02bb1817a1e109e36707202a6bb/net/ipv4/udp.c (mode:100644)
+++ b53df6f327c03ec282a1b75326db321dbd2f0bc0/net/ipv4/udp.c (mode:100644)
@@ -94,6 +94,8 @@
#include <linux/inet.h>
#include <linux/ipv6.h>
#include <linux/netdevice.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
#include <net/snmp.h>
#include <net/tcp.h>
#include <net/protocol.h>
@@ -1113,6 +1115,55 @@
return 0;
}
+static inline int udp_rcv_finish(struct sock *sk, struct sk_buff *skb)
+{
+ if (sk != NULL) {
+ int ret = udp_queue_rcv_skb(sk, skb);
+ sock_put(sk);
+
+ /* a return value > 0 means to resubmit the input, but
+ * it it wants the return to be -protocol, or 0
+ */
+ if (ret > 0)
+ return -ret;
+ return 0;
+ }
+
+ if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+ goto drop;
+
+ /* No socket. Drop packet silently, if checksum is wrong */
+ if (udp_checksum_complete(skb))
+ goto csum_error;
+
+ UDP_INC_STATS_BH(UDP_MIB_NOPORTS);
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+
+ /*
+ * Hmm. We got an UDP packet to a port to which we
+ * don't wanna listen. Ignore it.
+ */
+ kfree_skb(skb);
+ return(0);
+
+csum_error:
+ /*
+ * RFC1122: OK. Discards the bad packet silently (as far as
+ * the network is concerned, anyway) as per 4.1.3.4 (MUST).
+ */
+ NETDEBUG(if (net_ratelimit())
+ printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
+ NIPQUAD(skb->nh.iph->saddr),
+ ntohs(skb->h.uh->source),
+ NIPQUAD(skb->nh.iph->daddr),
+ ntohs(skb->h.uh->dest),
+ ntohs(skb->h.uh->len)));
+drop:
+ UDP_INC_STATS_BH(UDP_MIB_INERRORS);
+ kfree_skb(skb);
+ return(0);
+}
+
/*
* All we need to do is get the socket, and then do a checksum.
*/
@@ -1151,35 +1202,21 @@
sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex);
- if (sk != NULL) {
- int ret = udp_queue_rcv_skb(sk, skb);
- sock_put(sk);
-
- /* a return value > 0 means to resubmit the input, but
- * it it wants the return to be -protocol, or 0
- */
- if (ret > 0)
- return -ret;
- return 0;
- }
-
- if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
- goto drop;
-
- /* No socket. Drop packet silently, if checksum is wrong */
- if (udp_checksum_complete(skb))
- goto csum_error;
-
- UDP_INC_STATS_BH(UDP_MIB_NOPORTS);
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
-
- /*
- * Hmm. We got an UDP packet to a port to which we
- * don't wanna listen. Ignore it.
+ return NF_SK_HOOK(AF_INET, NF_IP_LOCAL_IN, sk, skb, skb->dev, NULL,
+ udp_rcv_finish, sock_put);
+csum_error:
+ /*
+ * RFC1122: OK. Discards the bad packet silently (as far as
+ * the network is concerned, anyway) as per 4.1.3.4 (MUST).
*/
- kfree_skb(skb);
- return(0);
-
+ NETDEBUG(if (net_ratelimit())
+ printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
+ NIPQUAD(skb->nh.iph->saddr),
+ ntohs(skb->h.uh->source),
+ NIPQUAD(skb->nh.iph->daddr),
+ ntohs(skb->h.uh->dest),
+ ntohs(skb->h.uh->len)));
+ goto drop;
short_packet:
NETDEBUG(if (net_ratelimit())
printk(KERN_DEBUG "UDP: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
@@ -1191,23 +1228,7 @@
ntohs(uh->dest)));
no_header:
UDP_INC_STATS_BH(UDP_MIB_INERRORS);
- kfree_skb(skb);
- return(0);
-
-csum_error:
- /*
- * RFC1122: OK. Discards the bad packet silently (as far as
- * the network is concerned, anyway) as per 4.1.3.4 (MUST).
- */
- NETDEBUG(if (net_ratelimit())
- printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
- NIPQUAD(saddr),
- ntohs(uh->source),
- NIPQUAD(daddr),
- ntohs(uh->dest),
- ulen));
drop:
- UDP_INC_STATS_BH(UDP_MIB_INERRORS);
kfree_skb(skb);
return(0);
}
next prev parent reply other threads:[~2005-05-10 16:00 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-27 4:22 Status of owner-socketlookup James Morris
2005-04-27 4:22 ` David S. Miller
2005-04-27 4:44 ` James Morris
2005-04-27 10:09 ` Patrick McHardy
2005-04-27 13:59 ` James Morris
2005-04-27 14:04 ` Patrick McHardy
2005-04-27 18:47 ` David S. Miller
2005-04-27 14:40 ` Juha Heljoranta
2005-04-27 14:52 ` Patrick McHardy
2005-04-27 18:49 ` David S. Miller
2005-04-27 19:37 ` Patrick McHardy
2005-04-27 22:43 ` James Morris
2005-05-10 15:59 ` Netfilter socket hooks (was: Re: Status of owner-socketlookup) Patrick McHardy
2005-05-10 16:00 ` [netfilter socket hooks 1/5]: Add socket hook infrastructure Patrick McHardy
2005-05-11 23:22 ` James Morris
2005-05-11 23:27 ` James Morris
2005-05-11 23:27 ` Patrick McHardy
2005-05-10 16:00 ` Patrick McHardy [this message]
2005-05-10 16:01 ` [netfilter socket hooks 3/5]: Add struct sock * argument to ipt_do_table() Patrick McHardy
2005-05-10 16:01 ` [netfilter socket hooks 4/5]: Add struct sock * argument to match functions Patrick McHardy
2005-05-10 16:01 ` [netfilter socket hooks 5/5]: Add skfilter table Patrick McHardy
2005-05-10 18:26 ` Netfilter socket hooks (was: Re: Status of owner-socketlookup) James Morris
2005-05-10 20:37 ` Netfilter socket hooks Jonas Berlin
2005-05-11 0:04 ` David S. Miller
2005-05-11 23:57 ` Netfilter socket hooks (was: Re: Status of owner-socketlookup) James Morris
2005-05-12 0:12 ` Netfilter socket hooks Patrick McHardy
2005-04-27 6:04 ` [PATCH] owner-socketlookup update for 2.6.12-rc3 James Morris
2005-04-27 6:13 ` David S. Miller
2005-04-27 6:43 ` Patrick Schaaf
2005-04-27 6:55 ` Patrick Schaaf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4280DAA2.2030708@trash.net \
--to=kaber@trash.net \
--cc=juha.heljoranta@evtek.fi \
--cc=netfilter-devel@lists.netfilter.org \
--cc=rusty@rustcorp.com.au \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.