Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits) bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL. vlan: Calling vlan_hwaccel_do_receive() is always valid. tproxy: use the interface primary IP address as a default value for --on-ip tproxy: added IPv6 support to the socket match cxgb3: function namespace cleanup tproxy: added IPv6 support to the TPROXY target tproxy: added IPv6 socket lookup function to nf_tproxy_core be2net: Changes to use only priority codes allowed by f/w tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled tproxy: added tproxy sockopt interface in the IPV6 layer tproxy: added udp6_lib_lookup function tproxy: added const specifiers to udp lookup functions tproxy: split off ipv6 defragmentation to a separate module l2tp: small cleanup nf_nat: restrict ICMP translation for embedded header can: mcp251x: fix generation of error frames can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set can-raw: add msg_flags to distinguish local traffic 9p: client code cleanup rds: make local functions/variables static ... Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and drivers/net/wireless/ath/ath9k/debug.c as per David
This commit is contained in:
6
include/net/netfilter/ipv6/nf_defrag_ipv6.h
Normal file
6
include/net/netfilter/ipv6/nf_defrag_ipv6.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _NF_DEFRAG_IPV6_H
|
||||
#define _NF_DEFRAG_IPV6_H
|
||||
|
||||
extern void nf_defrag_ipv6_enable(void);
|
||||
|
||||
#endif /* _NF_DEFRAG_IPV6_H */
|
@ -67,9 +67,6 @@ struct nf_conntrack_expect_policy {
|
||||
|
||||
#define NF_CT_EXPECT_CLASS_DEFAULT 0
|
||||
|
||||
#define NF_CT_EXPECT_PERMANENT 0x1
|
||||
#define NF_CT_EXPECT_INACTIVE 0x2
|
||||
|
||||
int nf_conntrack_expect_init(struct net *net);
|
||||
void nf_conntrack_expect_fini(struct net *net);
|
||||
|
||||
@ -85,9 +82,16 @@ struct nf_conntrack_expect *
|
||||
nf_ct_find_expectation(struct net *net, u16 zone,
|
||||
const struct nf_conntrack_tuple *tuple);
|
||||
|
||||
void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
|
||||
void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
|
||||
u32 pid, int report);
|
||||
static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
|
||||
{
|
||||
nf_ct_unlink_expect_report(exp, 0, 0);
|
||||
}
|
||||
|
||||
void nf_ct_remove_expectations(struct nf_conn *ct);
|
||||
void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
|
||||
void nf_ct_remove_userspace_expectations(void);
|
||||
|
||||
/* Allocate space for an expectation: this is mandatory before calling
|
||||
nf_ct_expect_related. You will have to call put afterwards. */
|
||||
|
@ -45,9 +45,6 @@ struct nf_nat_protocol {
|
||||
extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto);
|
||||
extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto);
|
||||
|
||||
extern const struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
|
||||
extern void nf_nat_proto_put(const struct nf_nat_protocol *proto);
|
||||
|
||||
/* Built-in protocols. */
|
||||
extern const struct nf_nat_protocol nf_nat_protocol_tcp;
|
||||
extern const struct nf_nat_protocol nf_nat_protocol_udp;
|
||||
|
@ -5,15 +5,201 @@
|
||||
#include <linux/in.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/inet_sock.h>
|
||||
#include <net/inet_hashtables.h>
|
||||
#include <net/inet6_hashtables.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
#define NFT_LOOKUP_ANY 0
|
||||
#define NFT_LOOKUP_LISTENER 1
|
||||
#define NFT_LOOKUP_ESTABLISHED 2
|
||||
|
||||
/* look up and get a reference to a matching socket */
|
||||
extern struct sock *
|
||||
|
||||
|
||||
/* This function is used by the 'TPROXY' target and the 'socket'
|
||||
* match. The following lookups are supported:
|
||||
*
|
||||
* Explicit TProxy target rule
|
||||
* ===========================
|
||||
*
|
||||
* This is used when the user wants to intercept a connection matching
|
||||
* an explicit iptables rule. In this case the sockets are assumed
|
||||
* matching in preference order:
|
||||
*
|
||||
* - match: if there's a fully established connection matching the
|
||||
* _packet_ tuple, it is returned, assuming the redirection
|
||||
* already took place and we process a packet belonging to an
|
||||
* established connection
|
||||
*
|
||||
* - match: if there's a listening socket matching the redirection
|
||||
* (e.g. on-port & on-ip of the connection), it is returned,
|
||||
* regardless if it was bound to 0.0.0.0 or an explicit
|
||||
* address. The reasoning is that if there's an explicit rule, it
|
||||
* does not really matter if the listener is bound to an interface
|
||||
* or to 0. The user already stated that he wants redirection
|
||||
* (since he added the rule).
|
||||
*
|
||||
* "socket" match based redirection (no specific rule)
|
||||
* ===================================================
|
||||
*
|
||||
* There are connections with dynamic endpoints (e.g. FTP data
|
||||
* connection) that the user is unable to add explicit rules
|
||||
* for. These are taken care of by a generic "socket" rule. It is
|
||||
* assumed that the proxy application is trusted to open such
|
||||
* connections without explicit iptables rule (except of course the
|
||||
* generic 'socket' rule). In this case the following sockets are
|
||||
* matched in preference order:
|
||||
*
|
||||
* - match: if there's a fully established connection matching the
|
||||
* _packet_ tuple
|
||||
*
|
||||
* - match: if there's a non-zero bound listener (possibly with a
|
||||
* non-local address) We don't accept zero-bound listeners, since
|
||||
* then local services could intercept traffic going through the
|
||||
* box.
|
||||
*
|
||||
* Please note that there's an overlap between what a TPROXY target
|
||||
* and a socket match will match. Normally if you have both rules the
|
||||
* "socket" match will be the first one, effectively all packets
|
||||
* belonging to established connections going through that one.
|
||||
*/
|
||||
static inline struct sock *
|
||||
nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
|
||||
const __be32 saddr, const __be32 daddr,
|
||||
const __be16 sport, const __be16 dport,
|
||||
const struct net_device *in, bool listening);
|
||||
const struct net_device *in, int lookup_type)
|
||||
{
|
||||
struct sock *sk;
|
||||
|
||||
/* look up socket */
|
||||
switch (protocol) {
|
||||
case IPPROTO_TCP:
|
||||
switch (lookup_type) {
|
||||
case NFT_LOOKUP_ANY:
|
||||
sk = __inet_lookup(net, &tcp_hashinfo,
|
||||
saddr, sport, daddr, dport,
|
||||
in->ifindex);
|
||||
break;
|
||||
case NFT_LOOKUP_LISTENER:
|
||||
sk = inet_lookup_listener(net, &tcp_hashinfo,
|
||||
daddr, dport,
|
||||
in->ifindex);
|
||||
|
||||
/* NOTE: we return listeners even if bound to
|
||||
* 0.0.0.0, those are filtered out in
|
||||
* xt_socket, since xt_TPROXY needs 0 bound
|
||||
* listeners too */
|
||||
|
||||
break;
|
||||
case NFT_LOOKUP_ESTABLISHED:
|
||||
sk = inet_lookup_established(net, &tcp_hashinfo,
|
||||
saddr, sport, daddr, dport,
|
||||
in->ifindex);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
sk = NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
|
||||
in->ifindex);
|
||||
if (sk && lookup_type != NFT_LOOKUP_ANY) {
|
||||
int connected = (sk->sk_state == TCP_ESTABLISHED);
|
||||
int wildcard = (inet_sk(sk)->inet_rcv_saddr == 0);
|
||||
|
||||
/* NOTE: we return listeners even if bound to
|
||||
* 0.0.0.0, those are filtered out in
|
||||
* xt_socket, since xt_TPROXY needs 0 bound
|
||||
* listeners too */
|
||||
if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
|
||||
(lookup_type == NFT_LOOKUP_LISTENER && connected)) {
|
||||
sock_put(sk);
|
||||
sk = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
sk = NULL;
|
||||
}
|
||||
|
||||
pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n",
|
||||
protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk);
|
||||
|
||||
return sk;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
static inline struct sock *
|
||||
nf_tproxy_get_sock_v6(struct net *net, const u8 protocol,
|
||||
const struct in6_addr *saddr, const struct in6_addr *daddr,
|
||||
const __be16 sport, const __be16 dport,
|
||||
const struct net_device *in, int lookup_type)
|
||||
{
|
||||
struct sock *sk;
|
||||
|
||||
/* look up socket */
|
||||
switch (protocol) {
|
||||
case IPPROTO_TCP:
|
||||
switch (lookup_type) {
|
||||
case NFT_LOOKUP_ANY:
|
||||
sk = inet6_lookup(net, &tcp_hashinfo,
|
||||
saddr, sport, daddr, dport,
|
||||
in->ifindex);
|
||||
break;
|
||||
case NFT_LOOKUP_LISTENER:
|
||||
sk = inet6_lookup_listener(net, &tcp_hashinfo,
|
||||
daddr, ntohs(dport),
|
||||
in->ifindex);
|
||||
|
||||
/* NOTE: we return listeners even if bound to
|
||||
* 0.0.0.0, those are filtered out in
|
||||
* xt_socket, since xt_TPROXY needs 0 bound
|
||||
* listeners too */
|
||||
|
||||
break;
|
||||
case NFT_LOOKUP_ESTABLISHED:
|
||||
sk = __inet6_lookup_established(net, &tcp_hashinfo,
|
||||
saddr, sport, daddr, ntohs(dport),
|
||||
in->ifindex);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
sk = NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
sk = udp6_lib_lookup(net, saddr, sport, daddr, dport,
|
||||
in->ifindex);
|
||||
if (sk && lookup_type != NFT_LOOKUP_ANY) {
|
||||
int connected = (sk->sk_state == TCP_ESTABLISHED);
|
||||
int wildcard = ipv6_addr_any(&inet6_sk(sk)->rcv_saddr);
|
||||
|
||||
/* NOTE: we return listeners even if bound to
|
||||
* 0.0.0.0, those are filtered out in
|
||||
* xt_socket, since xt_TPROXY needs 0 bound
|
||||
* listeners too */
|
||||
if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
|
||||
(lookup_type == NFT_LOOKUP_LISTENER && connected)) {
|
||||
sock_put(sk);
|
||||
sk = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
sk = NULL;
|
||||
}
|
||||
|
||||
pr_debug("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n",
|
||||
protocol, saddr, ntohs(sport), daddr, ntohs(dport), lookup_type, sk);
|
||||
|
||||
return sk;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
nf_tproxy_put_sock(struct sock *sk)
|
||||
|
54
include/net/netfilter/xt_log.h
Normal file
54
include/net/netfilter/xt_log.h
Normal file
@ -0,0 +1,54 @@
|
||||
#define S_SIZE (1024 - (sizeof(unsigned int) + 1))
|
||||
|
||||
struct sbuff {
|
||||
unsigned int count;
|
||||
char buf[S_SIZE + 1];
|
||||
};
|
||||
static struct sbuff emergency, *emergency_ptr = &emergency;
|
||||
|
||||
static int sb_add(struct sbuff *m, const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
int len;
|
||||
|
||||
if (likely(m->count < S_SIZE)) {
|
||||
va_start(args, f);
|
||||
len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args);
|
||||
va_end(args);
|
||||
if (likely(m->count + len < S_SIZE)) {
|
||||
m->count += len;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
m->count = S_SIZE;
|
||||
printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct sbuff *sb_open(void)
|
||||
{
|
||||
struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC);
|
||||
|
||||
if (unlikely(!m)) {
|
||||
local_bh_disable();
|
||||
do {
|
||||
m = xchg(&emergency_ptr, NULL);
|
||||
} while (!m);
|
||||
}
|
||||
m->count = 0;
|
||||
return m;
|
||||
}
|
||||
|
||||
static void sb_close(struct sbuff *m)
|
||||
{
|
||||
m->buf[m->count] = 0;
|
||||
printk("%s\n", m->buf);
|
||||
|
||||
if (likely(m != &emergency))
|
||||
kfree(m);
|
||||
else {
|
||||
xchg(&emergency_ptr, m);
|
||||
local_bh_enable();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user