mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-25 03:55:09 +08:00
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
commit
4a4f8fdba6
@ -75,12 +75,6 @@ enum nf_ip_hook_priorities {
|
||||
#define SO_ORIGINAL_DST 80
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
void nf_debug_ip_local_deliver(struct sk_buff *skb);
|
||||
void nf_debug_ip_loopback_xmit(struct sk_buff *newskb);
|
||||
void nf_debug_ip_finish_output2(struct sk_buff *skb);
|
||||
#endif /*CONFIG_NETFILTER_DEBUG*/
|
||||
|
||||
extern int ip_route_me_harder(struct sk_buff **pskb);
|
||||
|
||||
/* Call this before modifying an existing IP packet: ensures it is
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef _IP_CONNTRACK_CORE_H
|
||||
#define _IP_CONNTRACK_CORE_H
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
|
||||
/* This header is used to share core functionality between the
|
||||
standalone connection tracking module, and the compatibility layer's use
|
||||
@ -47,6 +46,6 @@ static inline int ip_conntrack_confirm(struct sk_buff **pskb)
|
||||
|
||||
extern struct list_head *ip_conntrack_hash;
|
||||
extern struct list_head ip_conntrack_expect_list;
|
||||
DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
|
||||
extern rwlock_t ip_conntrack_lock;
|
||||
#endif /* _IP_CONNTRACK_CORE_H */
|
||||
|
||||
|
@ -50,10 +50,9 @@ struct ip_nat_multi_range_compat
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/list.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
|
||||
/* Protects NAT hash tables, and NAT-private part of conntracks. */
|
||||
DECLARE_RWLOCK_EXTERN(ip_nat_lock);
|
||||
extern rwlock_t ip_nat_lock;
|
||||
|
||||
/* The structure embedded in the conntrack structure. */
|
||||
struct ip_nat_info
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define _LISTHELP_H
|
||||
#include <linux/config.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
|
||||
/* Header to do more comprehensive job than linux/list.h; assume list
|
||||
is first entry in structure. */
|
||||
|
@ -1,129 +0,0 @@
|
||||
#ifndef _LOCKHELP_H
|
||||
#define _LOCKHELP_H
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
/* Header to do help in lock debugging. */
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
struct spinlock_debug
|
||||
{
|
||||
spinlock_t l;
|
||||
atomic_t locked_by;
|
||||
};
|
||||
|
||||
struct rwlock_debug
|
||||
{
|
||||
rwlock_t l;
|
||||
long read_locked_map;
|
||||
long write_locked_map;
|
||||
};
|
||||
|
||||
#define DECLARE_LOCK(l) \
|
||||
struct spinlock_debug l = { SPIN_LOCK_UNLOCKED, ATOMIC_INIT(-1) }
|
||||
#define DECLARE_LOCK_EXTERN(l) \
|
||||
extern struct spinlock_debug l
|
||||
#define DECLARE_RWLOCK(l) \
|
||||
struct rwlock_debug l = { RW_LOCK_UNLOCKED, 0, 0 }
|
||||
#define DECLARE_RWLOCK_EXTERN(l) \
|
||||
extern struct rwlock_debug l
|
||||
|
||||
#define MUST_BE_LOCKED(l) \
|
||||
do { if (atomic_read(&(l)->locked_by) != smp_processor_id()) \
|
||||
printk("ASSERT %s:%u %s unlocked\n", __FILE__, __LINE__, #l); \
|
||||
} while(0)
|
||||
|
||||
#define MUST_BE_UNLOCKED(l) \
|
||||
do { if (atomic_read(&(l)->locked_by) == smp_processor_id()) \
|
||||
printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l); \
|
||||
} while(0)
|
||||
|
||||
/* Write locked OK as well. */
|
||||
#define MUST_BE_READ_LOCKED(l) \
|
||||
do { if (!((l)->read_locked_map & (1UL << smp_processor_id())) \
|
||||
&& !((l)->write_locked_map & (1UL << smp_processor_id()))) \
|
||||
printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \
|
||||
} while(0)
|
||||
|
||||
#define MUST_BE_WRITE_LOCKED(l) \
|
||||
do { if (!((l)->write_locked_map & (1UL << smp_processor_id()))) \
|
||||
printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \
|
||||
} while(0)
|
||||
|
||||
#define MUST_BE_READ_WRITE_UNLOCKED(l) \
|
||||
do { if ((l)->read_locked_map & (1UL << smp_processor_id())) \
|
||||
printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l); \
|
||||
else if ((l)->write_locked_map & (1UL << smp_processor_id())) \
|
||||
printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \
|
||||
} while(0)
|
||||
|
||||
#define LOCK_BH(lk) \
|
||||
do { \
|
||||
MUST_BE_UNLOCKED(lk); \
|
||||
spin_lock_bh(&(lk)->l); \
|
||||
atomic_set(&(lk)->locked_by, smp_processor_id()); \
|
||||
} while(0)
|
||||
|
||||
#define UNLOCK_BH(lk) \
|
||||
do { \
|
||||
MUST_BE_LOCKED(lk); \
|
||||
atomic_set(&(lk)->locked_by, -1); \
|
||||
spin_unlock_bh(&(lk)->l); \
|
||||
} while(0)
|
||||
|
||||
#define READ_LOCK(lk) \
|
||||
do { \
|
||||
MUST_BE_READ_WRITE_UNLOCKED(lk); \
|
||||
read_lock_bh(&(lk)->l); \
|
||||
set_bit(smp_processor_id(), &(lk)->read_locked_map); \
|
||||
} while(0)
|
||||
|
||||
#define WRITE_LOCK(lk) \
|
||||
do { \
|
||||
MUST_BE_READ_WRITE_UNLOCKED(lk); \
|
||||
write_lock_bh(&(lk)->l); \
|
||||
set_bit(smp_processor_id(), &(lk)->write_locked_map); \
|
||||
} while(0)
|
||||
|
||||
#define READ_UNLOCK(lk) \
|
||||
do { \
|
||||
if (!((lk)->read_locked_map & (1UL << smp_processor_id()))) \
|
||||
printk("ASSERT: %s:%u %s not readlocked\n", \
|
||||
__FILE__, __LINE__, #lk); \
|
||||
clear_bit(smp_processor_id(), &(lk)->read_locked_map); \
|
||||
read_unlock_bh(&(lk)->l); \
|
||||
} while(0)
|
||||
|
||||
#define WRITE_UNLOCK(lk) \
|
||||
do { \
|
||||
MUST_BE_WRITE_LOCKED(lk); \
|
||||
clear_bit(smp_processor_id(), &(lk)->write_locked_map); \
|
||||
write_unlock_bh(&(lk)->l); \
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
#define DECLARE_LOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED
|
||||
#define DECLARE_LOCK_EXTERN(l) extern spinlock_t l
|
||||
#define DECLARE_RWLOCK(l) rwlock_t l = RW_LOCK_UNLOCKED
|
||||
#define DECLARE_RWLOCK_EXTERN(l) extern rwlock_t l
|
||||
|
||||
#define MUST_BE_LOCKED(l)
|
||||
#define MUST_BE_UNLOCKED(l)
|
||||
#define MUST_BE_READ_LOCKED(l)
|
||||
#define MUST_BE_WRITE_LOCKED(l)
|
||||
#define MUST_BE_READ_WRITE_UNLOCKED(l)
|
||||
|
||||
#define LOCK_BH(l) spin_lock_bh(l)
|
||||
#define UNLOCK_BH(l) spin_unlock_bh(l)
|
||||
|
||||
#define READ_LOCK(l) read_lock_bh(l)
|
||||
#define WRITE_LOCK(l) write_lock_bh(l)
|
||||
#define READ_UNLOCK(l) read_unlock_bh(l)
|
||||
#define WRITE_UNLOCK(l) write_unlock_bh(l)
|
||||
#endif /*CONFIG_NETFILTER_DEBUG*/
|
||||
|
||||
#endif /* _LOCKHELP_H */
|
@ -147,7 +147,7 @@ struct netlink_callback
|
||||
int (*dump)(struct sk_buff * skb, struct netlink_callback *cb);
|
||||
int (*done)(struct netlink_callback *cb);
|
||||
int family;
|
||||
long args[4];
|
||||
long args[5];
|
||||
};
|
||||
|
||||
struct netlink_notify
|
||||
|
@ -193,7 +193,6 @@ struct skb_shared_info {
|
||||
* @nfcache: Cache info
|
||||
* @nfct: Associated connection, if any
|
||||
* @nfctinfo: Relationship of this skb to the connection
|
||||
* @nf_debug: Netfilter debugging
|
||||
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
|
||||
* @private: Data which is private to the HIPPI implementation
|
||||
* @tc_index: Traffic control index
|
||||
@ -264,9 +263,6 @@ struct sk_buff {
|
||||
__u32 nfcache;
|
||||
__u32 nfctinfo;
|
||||
struct nf_conntrack *nfct;
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
unsigned int nf_debug;
|
||||
#endif
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
struct nf_bridge_info *nf_bridge;
|
||||
#endif
|
||||
@ -1219,15 +1215,6 @@ static inline void nf_reset(struct sk_buff *skb)
|
||||
{
|
||||
nf_conntrack_put(skb->nfct);
|
||||
skb->nfct = NULL;
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug = 0;
|
||||
#endif
|
||||
}
|
||||
static inline void nf_reset_debug(struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
|
@ -167,14 +167,17 @@ extern int fib6_walk_continue(struct fib6_walker_t *w);
|
||||
extern int fib6_add(struct fib6_node *root,
|
||||
struct rt6_info *rt,
|
||||
struct nlmsghdr *nlh,
|
||||
void *rtattr);
|
||||
void *rtattr,
|
||||
struct netlink_skb_parms *req);
|
||||
|
||||
extern int fib6_del(struct rt6_info *rt,
|
||||
struct nlmsghdr *nlh,
|
||||
void *rtattr);
|
||||
void *rtattr,
|
||||
struct netlink_skb_parms *req);
|
||||
|
||||
extern void inet6_rt_notify(int event, struct rt6_info *rt,
|
||||
struct nlmsghdr *nlh);
|
||||
struct nlmsghdr *nlh,
|
||||
struct netlink_skb_parms *req);
|
||||
|
||||
extern void fib6_run_gc(unsigned long dummy);
|
||||
|
||||
|
@ -41,13 +41,16 @@ extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
|
||||
|
||||
extern int ip6_route_add(struct in6_rtmsg *rtmsg,
|
||||
struct nlmsghdr *,
|
||||
void *rtattr);
|
||||
void *rtattr,
|
||||
struct netlink_skb_parms *req);
|
||||
extern int ip6_ins_rt(struct rt6_info *,
|
||||
struct nlmsghdr *,
|
||||
void *rtattr);
|
||||
void *rtattr,
|
||||
struct netlink_skb_parms *req);
|
||||
extern int ip6_del_rt(struct rt6_info *,
|
||||
struct nlmsghdr *,
|
||||
void *rtattr);
|
||||
void *rtattr,
|
||||
struct netlink_skb_parms *req);
|
||||
|
||||
extern int ip6_rt_addr_add(struct in6_addr *addr,
|
||||
struct net_device *dev,
|
||||
|
@ -57,9 +57,6 @@ int br_forward_finish(struct sk_buff *skb)
|
||||
static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
|
||||
{
|
||||
skb->dev = to->dev;
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug = 0;
|
||||
#endif
|
||||
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
|
||||
br_forward_finish);
|
||||
}
|
||||
|
@ -23,11 +23,7 @@ const unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
|
||||
|
||||
static int br_pass_frame_up_finish(struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug = 0;
|
||||
#endif
|
||||
netif_receive_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,6 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
|
||||
{
|
||||
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING);
|
||||
#endif
|
||||
|
||||
if (nf_bridge->mask & BRNF_PKT_TYPE) {
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
nf_bridge->mask ^= BRNF_PKT_TYPE;
|
||||
@ -182,10 +178,6 @@ static void __br_dnat_complain(void)
|
||||
* --Bart, 20021007 (updated) */
|
||||
static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug |= (1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_FORWARD);
|
||||
#endif
|
||||
|
||||
if (skb->pkt_type == PACKET_OTHERHOST) {
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
skb->nf_bridge->mask |= BRNF_PKT_TYPE;
|
||||
@ -207,10 +199,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
|
||||
struct iphdr *iph = skb->nh.iph;
|
||||
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING);
|
||||
#endif
|
||||
|
||||
if (nf_bridge->mask & BRNF_PKT_TYPE) {
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
nf_bridge->mask ^= BRNF_PKT_TYPE;
|
||||
@ -382,9 +370,6 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
|
||||
if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb))
|
||||
goto inhdr_error;
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_IP6_PRE_ROUTING);
|
||||
#endif
|
||||
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
|
||||
return NF_DROP;
|
||||
setup_pre_routing(skb);
|
||||
@ -468,9 +453,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_IP_PRE_ROUTING);
|
||||
#endif
|
||||
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
|
||||
return NF_DROP;
|
||||
setup_pre_routing(skb);
|
||||
@ -517,10 +499,6 @@ static int br_nf_forward_finish(struct sk_buff *skb)
|
||||
struct net_device *in;
|
||||
struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_BR_FORWARD);
|
||||
#endif
|
||||
|
||||
if (skb->protocol != __constant_htons(ETH_P_ARP) && !IS_VLAN_ARP) {
|
||||
in = nf_bridge->physindev;
|
||||
if (nf_bridge->mask & BRNF_PKT_TYPE) {
|
||||
@ -566,9 +544,6 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
|
||||
(*pskb)->nh.raw += VLAN_HLEN;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_BR_FORWARD);
|
||||
#endif
|
||||
nf_bridge = skb->nf_bridge;
|
||||
if (skb->pkt_type == PACKET_OTHERHOST) {
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
@ -605,10 +580,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
|
||||
(*pskb)->nh.raw += VLAN_HLEN;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_BR_FORWARD);
|
||||
#endif
|
||||
|
||||
if (skb->nh.arph->ar_pln != 4) {
|
||||
if (IS_VLAN_ARP) {
|
||||
skb_push(*pskb, VLAN_HLEN);
|
||||
@ -627,9 +598,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
|
||||
/* PF_BRIDGE/LOCAL_OUT ***********************************************/
|
||||
static int br_nf_local_out_finish(struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug &= ~(1 << NF_BR_LOCAL_OUT);
|
||||
#endif
|
||||
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
||||
skb_push(skb, VLAN_HLEN);
|
||||
skb->nh.raw -= VLAN_HLEN;
|
||||
@ -731,10 +699,6 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
|
||||
realoutdev, br_nf_local_out_finish,
|
||||
NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1);
|
||||
} else {
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
skb->nf_debug ^= (1 << NF_IP_LOCAL_OUT);
|
||||
#endif
|
||||
|
||||
NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev,
|
||||
realoutdev, br_nf_local_out_finish,
|
||||
NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1);
|
||||
@ -779,8 +743,6 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
|
||||
printk(KERN_CRIT "br_netfilter: skb->dst == NULL.");
|
||||
goto print_error;
|
||||
}
|
||||
|
||||
skb->nf_debug ^= (1 << NF_IP_POST_ROUTING);
|
||||
#endif
|
||||
|
||||
/* We assume any code from br_dev_queue_push_xmit onwards doesn't care
|
||||
|
@ -141,136 +141,6 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg)
|
||||
up(&nf_sockopt_mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
#include <net/ip.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
|
||||
static void debug_print_hooks_ip(unsigned int nf_debug)
|
||||
{
|
||||
if (nf_debug & (1 << NF_IP_PRE_ROUTING)) {
|
||||
printk("PRE_ROUTING ");
|
||||
nf_debug ^= (1 << NF_IP_PRE_ROUTING);
|
||||
}
|
||||
if (nf_debug & (1 << NF_IP_LOCAL_IN)) {
|
||||
printk("LOCAL_IN ");
|
||||
nf_debug ^= (1 << NF_IP_LOCAL_IN);
|
||||
}
|
||||
if (nf_debug & (1 << NF_IP_FORWARD)) {
|
||||
printk("FORWARD ");
|
||||
nf_debug ^= (1 << NF_IP_FORWARD);
|
||||
}
|
||||
if (nf_debug & (1 << NF_IP_LOCAL_OUT)) {
|
||||
printk("LOCAL_OUT ");
|
||||
nf_debug ^= (1 << NF_IP_LOCAL_OUT);
|
||||
}
|
||||
if (nf_debug & (1 << NF_IP_POST_ROUTING)) {
|
||||
printk("POST_ROUTING ");
|
||||
nf_debug ^= (1 << NF_IP_POST_ROUTING);
|
||||
}
|
||||
if (nf_debug)
|
||||
printk("Crap bits: 0x%04X", nf_debug);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void nf_dump_skb(int pf, struct sk_buff *skb)
|
||||
{
|
||||
printk("skb: pf=%i %s dev=%s len=%u\n",
|
||||
pf,
|
||||
skb->sk ? "(owned)" : "(unowned)",
|
||||
skb->dev ? skb->dev->name : "(no dev)",
|
||||
skb->len);
|
||||
switch (pf) {
|
||||
case PF_INET: {
|
||||
const struct iphdr *ip = skb->nh.iph;
|
||||
__u32 *opt = (__u32 *) (ip + 1);
|
||||
int opti;
|
||||
__u16 src_port = 0, dst_port = 0;
|
||||
|
||||
if (ip->protocol == IPPROTO_TCP
|
||||
|| ip->protocol == IPPROTO_UDP) {
|
||||
struct tcphdr *tcp=(struct tcphdr *)((__u32 *)ip+ip->ihl);
|
||||
src_port = ntohs(tcp->source);
|
||||
dst_port = ntohs(tcp->dest);
|
||||
}
|
||||
|
||||
printk("PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu"
|
||||
" L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
|
||||
ip->protocol, NIPQUAD(ip->saddr),
|
||||
src_port, NIPQUAD(ip->daddr),
|
||||
dst_port,
|
||||
ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
|
||||
ntohs(ip->frag_off), ip->ttl);
|
||||
|
||||
for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
|
||||
printk(" O=0x%8.8X", *opt++);
|
||||
printk("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nf_debug_ip_local_deliver(struct sk_buff *skb)
|
||||
{
|
||||
/* If it's a loopback packet, it must have come through
|
||||
* NF_IP_LOCAL_OUT, NF_IP_RAW_INPUT, NF_IP_PRE_ROUTING and
|
||||
* NF_IP_LOCAL_IN. Otherwise, must have gone through
|
||||
* NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */
|
||||
if (!skb->dev) {
|
||||
printk("ip_local_deliver: skb->dev is NULL.\n");
|
||||
} else {
|
||||
if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING)
|
||||
| (1<<NF_IP_LOCAL_IN))) {
|
||||
printk("ip_local_deliver: bad skb: ");
|
||||
debug_print_hooks_ip(skb->nf_debug);
|
||||
nf_dump_skb(PF_INET, skb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nf_debug_ip_loopback_xmit(struct sk_buff *newskb)
|
||||
{
|
||||
if (newskb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
|
||||
| (1 << NF_IP_POST_ROUTING))) {
|
||||
printk("ip_dev_loopback_xmit: bad owned skb = %p: ",
|
||||
newskb);
|
||||
debug_print_hooks_ip(newskb->nf_debug);
|
||||
nf_dump_skb(PF_INET, newskb);
|
||||
}
|
||||
}
|
||||
|
||||
void nf_debug_ip_finish_output2(struct sk_buff *skb)
|
||||
{
|
||||
/* If it's owned, it must have gone through the
|
||||
* NF_IP_LOCAL_OUT and NF_IP_POST_ROUTING.
|
||||
* Otherwise, must have gone through
|
||||
* NF_IP_PRE_ROUTING, NF_IP_FORWARD and NF_IP_POST_ROUTING.
|
||||
*/
|
||||
if (skb->sk) {
|
||||
if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
|
||||
| (1 << NF_IP_POST_ROUTING))) {
|
||||
printk("ip_finish_output: bad owned skb = %p: ", skb);
|
||||
debug_print_hooks_ip(skb->nf_debug);
|
||||
nf_dump_skb(PF_INET, skb);
|
||||
}
|
||||
} else {
|
||||
if (skb->nf_debug != ((1 << NF_IP_PRE_ROUTING)
|
||||
| (1 << NF_IP_FORWARD)
|
||||
| (1 << NF_IP_POST_ROUTING))) {
|
||||
/* Fragments, entunnelled packets, TCP RSTs
|
||||
generated by ipt_REJECT will have no
|
||||
owners, but still may be local */
|
||||
if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
|
||||
| (1 << NF_IP_POST_ROUTING))){
|
||||
printk("ip_finish_output:"
|
||||
" bad unowned skb = %p: ",skb);
|
||||
debug_print_hooks_ip(skb->nf_debug);
|
||||
nf_dump_skb(PF_INET, skb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*CONFIG_NETFILTER_DEBUG*/
|
||||
|
||||
/* Call get/setsockopt() */
|
||||
static int nf_sockopt(struct sock *sk, int pf, int val,
|
||||
char __user *opt, int *len, int get)
|
||||
@ -488,14 +358,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
|
||||
/* We may already have this, but read-locks nest anyway */
|
||||
rcu_read_lock();
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
if (unlikely((*pskb)->nf_debug & (1 << hook))) {
|
||||
printk("nf_hook: hook %i already set.\n", hook);
|
||||
nf_dump_skb(pf, *pskb);
|
||||
}
|
||||
(*pskb)->nf_debug |= (1 << hook);
|
||||
#endif
|
||||
|
||||
elem = &nf_hooks[pf][hook];
|
||||
next_hook:
|
||||
verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
|
||||
|
@ -365,9 +365,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
|
||||
C(nfct);
|
||||
nf_conntrack_get(skb->nfct);
|
||||
C(nfctinfo);
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
C(nf_debug);
|
||||
#endif
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
C(nf_bridge);
|
||||
nf_bridge_get(skb->nf_bridge);
|
||||
@ -432,9 +429,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
|
||||
new->nfct = old->nfct;
|
||||
nf_conntrack_get(old->nfct);
|
||||
new->nfctinfo = old->nfctinfo;
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
new->nf_debug = old->nf_debug;
|
||||
#endif
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
new->nf_bridge = old->nf_bridge;
|
||||
nf_bridge_get(old->nf_bridge);
|
||||
|
@ -1,6 +1,32 @@
|
||||
#
|
||||
# IP configuration
|
||||
#
|
||||
choice
|
||||
prompt "Choose IP: FIB lookup""
|
||||
depends on INET
|
||||
default IP_FIB_HASH
|
||||
|
||||
config IP_FIB_HASH
|
||||
bool "FIB_HASH"
|
||||
---help---
|
||||
Current FIB is very proven and good enough for most users.
|
||||
|
||||
config IP_FIB_TRIE
|
||||
bool "FIB_TRIE"
|
||||
---help---
|
||||
Use new experimental LC-trie as FIB lookup algoritm.
|
||||
This improves lookup performance
|
||||
|
||||
LC-trie is described in:
|
||||
|
||||
IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
|
||||
IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
|
||||
An experimental study of compression methods for dynamic tries
|
||||
Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
|
||||
http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/
|
||||
|
||||
endchoice
|
||||
|
||||
config IP_MULTICAST
|
||||
bool "IP: multicasting"
|
||||
depends on INET
|
||||
|
@ -7,8 +7,10 @@ obj-y := utils.o route.o inetpeer.o protocol.o \
|
||||
ip_output.o ip_sockglue.o \
|
||||
tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \
|
||||
datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \
|
||||
sysctl_net_ipv4.o fib_frontend.o fib_semantics.o fib_hash.o
|
||||
sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
|
||||
|
||||
obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
|
||||
obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
|
||||
obj-$(CONFIG_PROC_FS) += proc.o
|
||||
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
|
||||
obj-$(CONFIG_IP_MROUTE) += ipmr.o
|
||||
|
@ -1119,6 +1119,10 @@ module_init(inet_init);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
extern int fib_proc_init(void);
|
||||
extern void fib_proc_exit(void);
|
||||
#ifdef CONFIG_IP_FIB_TRIE
|
||||
extern int fib_stat_proc_init(void);
|
||||
extern void fib_stat_proc_exit(void);
|
||||
#endif
|
||||
extern int ip_misc_proc_init(void);
|
||||
extern int raw_proc_init(void);
|
||||
extern void raw_proc_exit(void);
|
||||
@ -1139,11 +1143,19 @@ static int __init ipv4_proc_init(void)
|
||||
goto out_udp;
|
||||
if (fib_proc_init())
|
||||
goto out_fib;
|
||||
#ifdef CONFIG_IP_FIB_TRIE
|
||||
if (fib_stat_proc_init())
|
||||
goto out_fib_stat;
|
||||
#endif
|
||||
if (ip_misc_proc_init())
|
||||
goto out_misc;
|
||||
out:
|
||||
return rc;
|
||||
out_misc:
|
||||
#ifdef CONFIG_IP_FIB_TRIE
|
||||
fib_stat_proc_exit();
|
||||
out_fib_stat:
|
||||
#endif
|
||||
fib_proc_exit();
|
||||
out_fib:
|
||||
udp4_proc_exit();
|
||||
|
2454
net/ipv4/fib_trie.c
Normal file
2454
net/ipv4/fib_trie.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -184,6 +184,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
|
||||
raw_rcv(last, skb2);
|
||||
}
|
||||
last = sk;
|
||||
nf_reset(skb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,10 +201,6 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
|
||||
{
|
||||
int ihl = skb->nh.iph->ihl*4;
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
nf_debug_ip_local_deliver(skb);
|
||||
#endif /*CONFIG_NETFILTER_DEBUG*/
|
||||
|
||||
__skb_pull(skb, ihl);
|
||||
|
||||
/* Free reference early: we don't need it any more, and it may
|
||||
|
@ -107,10 +107,6 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
|
||||
newskb->pkt_type = PACKET_LOOPBACK;
|
||||
newskb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
BUG_TRAP(newskb->dst);
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
nf_debug_ip_loopback_xmit(newskb);
|
||||
#endif
|
||||
nf_reset(newskb);
|
||||
netif_rx(newskb);
|
||||
return 0;
|
||||
@ -192,10 +188,6 @@ static inline int ip_finish_output2(struct sk_buff *skb)
|
||||
skb = skb2;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
nf_debug_ip_finish_output2(skb);
|
||||
#endif /*CONFIG_NETFILTER_DEBUG*/
|
||||
|
||||
nf_reset(skb);
|
||||
|
||||
if (hh) {
|
||||
@ -415,9 +407,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
|
||||
to->nf_bridge = from->nf_bridge;
|
||||
nf_bridge_get(to->nf_bridge);
|
||||
#endif
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
to->nf_debug = from->nf_debug;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1350,6 +1350,7 @@ int ip_mr_input(struct sk_buff *skb)
|
||||
*/
|
||||
read_lock(&mrt_lock);
|
||||
if (mroute_socket) {
|
||||
nf_reset(skb);
|
||||
raw_rcv(mroute_socket, skb);
|
||||
read_unlock(&mrt_lock);
|
||||
return 0;
|
||||
|
@ -127,7 +127,6 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
|
||||
|
||||
#define IP_VS_XMIT(skb, rt) \
|
||||
do { \
|
||||
nf_reset_debug(skb); \
|
||||
(skb)->nfcache |= NFC_IPVS_PROPERTY; \
|
||||
(skb)->ip_summed = CHECKSUM_NONE; \
|
||||
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL, \
|
||||
|
@ -60,7 +60,6 @@ static DECLARE_MUTEX(arpt_mutex);
|
||||
|
||||
#define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
|
||||
#define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
#include <linux/netfilter_ipv4/listhelp.h>
|
||||
|
||||
struct arpt_table_info {
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <net/checksum.h>
|
||||
#include <net/udp.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
|
||||
|
||||
@ -42,7 +41,7 @@ static char *conns[] = { "DATA ", "MESG ", "INDEX " };
|
||||
|
||||
/* This is slow, but it's simple. --RR */
|
||||
static char amanda_buffer[65536];
|
||||
static DECLARE_LOCK(amanda_buffer_lock);
|
||||
static DEFINE_SPINLOCK(amanda_buffer_lock);
|
||||
|
||||
unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
@ -76,7 +75,7 @@ static int help(struct sk_buff **pskb,
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
LOCK_BH(&amanda_buffer_lock);
|
||||
spin_lock_bh(&amanda_buffer_lock);
|
||||
skb_copy_bits(*pskb, dataoff, amanda_buffer, (*pskb)->len - dataoff);
|
||||
data = amanda_buffer;
|
||||
data_limit = amanda_buffer + (*pskb)->len - dataoff;
|
||||
@ -134,7 +133,7 @@ static int help(struct sk_buff **pskb,
|
||||
}
|
||||
|
||||
out:
|
||||
UNLOCK_BH(&amanda_buffer_lock);
|
||||
spin_unlock_bh(&amanda_buffer_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,10 @@
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
/* This rwlock protects the main hash table, protocol/helper/expected
|
||||
/* ip_conntrack_lock protects the main hash table, protocol/helper/expected
|
||||
registrations, conntrack timers*/
|
||||
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
|
||||
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
|
||||
#define ASSERT_READ_LOCK(x)
|
||||
#define ASSERT_WRITE_LOCK(x)
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
@ -57,7 +57,7 @@
|
||||
#define DEBUGP(format, args...)
|
||||
#endif
|
||||
|
||||
DECLARE_RWLOCK(ip_conntrack_lock);
|
||||
DEFINE_RWLOCK(ip_conntrack_lock);
|
||||
|
||||
/* ip_conntrack_standalone needs this */
|
||||
atomic_t ip_conntrack_count = ATOMIC_INIT(0);
|
||||
@ -147,7 +147,7 @@ static void destroy_expect(struct ip_conntrack_expect *exp)
|
||||
|
||||
static void unlink_expect(struct ip_conntrack_expect *exp)
|
||||
{
|
||||
MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
|
||||
ASSERT_WRITE_LOCK(&ip_conntrack_lock);
|
||||
list_del(&exp->list);
|
||||
/* Logically in destroy_expect, but we hold the lock here. */
|
||||
exp->master->expecting--;
|
||||
@ -157,9 +157,9 @@ static void expectation_timed_out(unsigned long ul_expect)
|
||||
{
|
||||
struct ip_conntrack_expect *exp = (void *)ul_expect;
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
unlink_expect(exp);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
destroy_expect(exp);
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ clean_from_lists(struct ip_conntrack *ct)
|
||||
unsigned int ho, hr;
|
||||
|
||||
DEBUGP("clean_from_lists(%p)\n", ct);
|
||||
MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
|
||||
ASSERT_WRITE_LOCK(&ip_conntrack_lock);
|
||||
|
||||
ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||
hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
||||
@ -240,7 +240,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
||||
if (ip_conntrack_destroyed)
|
||||
ip_conntrack_destroyed(ct);
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
/* Expectations will have been removed in clean_from_lists,
|
||||
* except TFTP can create an expectation on the first packet,
|
||||
* before connection is in the list, so we need to clean here,
|
||||
@ -254,7 +254,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
||||
}
|
||||
|
||||
CONNTRACK_STAT_INC(delete);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
if (ct->master)
|
||||
ip_conntrack_put(ct->master);
|
||||
@ -268,12 +268,12 @@ static void death_by_timeout(unsigned long ul_conntrack)
|
||||
{
|
||||
struct ip_conntrack *ct = (void *)ul_conntrack;
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
/* Inside lock so preempt is disabled on module removal path.
|
||||
* Otherwise we can get spurious warnings. */
|
||||
CONNTRACK_STAT_INC(delete_list);
|
||||
clean_from_lists(ct);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
ip_conntrack_put(ct);
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ conntrack_tuple_cmp(const struct ip_conntrack_tuple_hash *i,
|
||||
const struct ip_conntrack_tuple *tuple,
|
||||
const struct ip_conntrack *ignored_conntrack)
|
||||
{
|
||||
MUST_BE_READ_LOCKED(&ip_conntrack_lock);
|
||||
ASSERT_READ_LOCK(&ip_conntrack_lock);
|
||||
return tuplehash_to_ctrack(i) != ignored_conntrack
|
||||
&& ip_ct_tuple_equal(tuple, &i->tuple);
|
||||
}
|
||||
@ -294,7 +294,7 @@ __ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
|
||||
struct ip_conntrack_tuple_hash *h;
|
||||
unsigned int hash = hash_conntrack(tuple);
|
||||
|
||||
MUST_BE_READ_LOCKED(&ip_conntrack_lock);
|
||||
ASSERT_READ_LOCK(&ip_conntrack_lock);
|
||||
list_for_each_entry(h, &ip_conntrack_hash[hash], list) {
|
||||
if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) {
|
||||
CONNTRACK_STAT_INC(found);
|
||||
@ -313,11 +313,11 @@ ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
|
||||
{
|
||||
struct ip_conntrack_tuple_hash *h;
|
||||
|
||||
READ_LOCK(&ip_conntrack_lock);
|
||||
read_lock_bh(&ip_conntrack_lock);
|
||||
h = __ip_conntrack_find(tuple, ignored_conntrack);
|
||||
if (h)
|
||||
atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
|
||||
READ_UNLOCK(&ip_conntrack_lock);
|
||||
read_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
return h;
|
||||
}
|
||||
@ -352,7 +352,7 @@ __ip_conntrack_confirm(struct sk_buff **pskb)
|
||||
IP_NF_ASSERT(!is_confirmed(ct));
|
||||
DEBUGP("Confirming conntrack %p\n", ct);
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
|
||||
/* See if there's one in the list already, including reverse:
|
||||
NAT could have grabbed it without realizing, since we're
|
||||
@ -380,12 +380,12 @@ __ip_conntrack_confirm(struct sk_buff **pskb)
|
||||
atomic_inc(&ct->ct_general.use);
|
||||
set_bit(IPS_CONFIRMED_BIT, &ct->status);
|
||||
CONNTRACK_STAT_INC(insert);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
CONNTRACK_STAT_INC(insert_failed);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
return NF_DROP;
|
||||
}
|
||||
@ -398,9 +398,9 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
|
||||
{
|
||||
struct ip_conntrack_tuple_hash *h;
|
||||
|
||||
READ_LOCK(&ip_conntrack_lock);
|
||||
read_lock_bh(&ip_conntrack_lock);
|
||||
h = __ip_conntrack_find(tuple, ignored_conntrack);
|
||||
READ_UNLOCK(&ip_conntrack_lock);
|
||||
read_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
return h != NULL;
|
||||
}
|
||||
@ -419,13 +419,13 @@ static int early_drop(struct list_head *chain)
|
||||
struct ip_conntrack *ct = NULL;
|
||||
int dropped = 0;
|
||||
|
||||
READ_LOCK(&ip_conntrack_lock);
|
||||
read_lock_bh(&ip_conntrack_lock);
|
||||
h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *);
|
||||
if (h) {
|
||||
ct = tuplehash_to_ctrack(h);
|
||||
atomic_inc(&ct->ct_general.use);
|
||||
}
|
||||
READ_UNLOCK(&ip_conntrack_lock);
|
||||
read_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
if (!ct)
|
||||
return dropped;
|
||||
@ -508,7 +508,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
|
||||
conntrack->timeout.data = (unsigned long)conntrack;
|
||||
conntrack->timeout.function = death_by_timeout;
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
exp = find_expectation(tuple);
|
||||
|
||||
if (exp) {
|
||||
@ -532,7 +532,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
|
||||
list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
|
||||
|
||||
atomic_inc(&ip_conntrack_count);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
if (exp) {
|
||||
if (exp->expectfn)
|
||||
@ -723,17 +723,17 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
|
||||
{
|
||||
struct ip_conntrack_expect *i;
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
/* choose the the oldest expectation to evict */
|
||||
list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
|
||||
if (expect_matches(i, exp) && del_timer(&i->timeout)) {
|
||||
unlink_expect(i);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
destroy_expect(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
}
|
||||
|
||||
struct ip_conntrack_expect *ip_conntrack_expect_alloc(void)
|
||||
@ -760,15 +760,11 @@ static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
|
||||
exp->master->expecting++;
|
||||
list_add(&exp->list, &ip_conntrack_expect_list);
|
||||
|
||||
if (exp->master->helper->timeout) {
|
||||
init_timer(&exp->timeout);
|
||||
exp->timeout.data = (unsigned long)exp;
|
||||
exp->timeout.function = expectation_timed_out;
|
||||
exp->timeout.expires
|
||||
= jiffies + exp->master->helper->timeout * HZ;
|
||||
add_timer(&exp->timeout);
|
||||
} else
|
||||
exp->timeout.function = NULL;
|
||||
init_timer(&exp->timeout);
|
||||
exp->timeout.data = (unsigned long)exp;
|
||||
exp->timeout.function = expectation_timed_out;
|
||||
exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
|
||||
add_timer(&exp->timeout);
|
||||
|
||||
CONNTRACK_STAT_INC(expect_create);
|
||||
}
|
||||
@ -808,7 +804,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
|
||||
DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
|
||||
DEBUGP("mask: "); DUMP_TUPLE(&expect->mask);
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
list_for_each_entry(i, &ip_conntrack_expect_list, list) {
|
||||
if (expect_matches(i, expect)) {
|
||||
/* Refresh timer: if it's dying, ignore.. */
|
||||
@ -832,7 +828,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
|
||||
ip_conntrack_expect_insert(expect);
|
||||
ret = 0;
|
||||
out:
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -841,7 +837,7 @@ out:
|
||||
void ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
|
||||
const struct ip_conntrack_tuple *newreply)
|
||||
{
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
/* Should be unconfirmed, so not in hash table yet */
|
||||
IP_NF_ASSERT(!is_confirmed(conntrack));
|
||||
|
||||
@ -851,15 +847,15 @@ void ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
|
||||
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
|
||||
if (!conntrack->master && conntrack->expecting == 0)
|
||||
conntrack->helper = ip_ct_find_helper(newreply);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
}
|
||||
|
||||
int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
|
||||
{
|
||||
BUG_ON(me->timeout == 0);
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
list_prepend(&helpers, me);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -878,7 +874,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
|
||||
struct ip_conntrack_expect *exp, *tmp;
|
||||
|
||||
/* Need write lock here, to delete helper. */
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
LIST_DELETE(&helpers, me);
|
||||
|
||||
/* Get rid of expectations */
|
||||
@ -893,7 +889,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
|
||||
for (i = 0; i < ip_conntrack_htable_size; i++)
|
||||
LIST_FIND_W(&ip_conntrack_hash[i], unhelp,
|
||||
struct ip_conntrack_tuple_hash *, me);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
/* Someone could be still looking at the helper in a bh. */
|
||||
synchronize_net();
|
||||
@ -925,14 +921,14 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct,
|
||||
ct->timeout.expires = extra_jiffies;
|
||||
ct_add_counters(ct, ctinfo, skb);
|
||||
} else {
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
/* Need del_timer for race avoidance (may already be dying). */
|
||||
if (del_timer(&ct->timeout)) {
|
||||
ct->timeout.expires = jiffies + extra_jiffies;
|
||||
add_timer(&ct->timeout);
|
||||
}
|
||||
ct_add_counters(ct, ctinfo, skb);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -940,10 +936,6 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct,
|
||||
struct sk_buff *
|
||||
ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
|
||||
{
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
unsigned int olddebug = skb->nf_debug;
|
||||
#endif
|
||||
|
||||
skb_orphan(skb);
|
||||
|
||||
local_bh_disable();
|
||||
@ -953,12 +945,7 @@ ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
|
||||
if (skb) {
|
||||
ip_send_check(skb->nh.iph);
|
||||
skb->nfcache |= NFC_ALTERED;
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
/* Packet path as if nothing had happened. */
|
||||
skb->nf_debug = olddebug;
|
||||
#endif
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
@ -997,7 +984,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data),
|
||||
{
|
||||
struct ip_conntrack_tuple_hash *h = NULL;
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
for (; *bucket < ip_conntrack_htable_size; (*bucket)++) {
|
||||
h = LIST_FIND_W(&ip_conntrack_hash[*bucket], do_iter,
|
||||
struct ip_conntrack_tuple_hash *, iter, data);
|
||||
@ -1009,7 +996,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data),
|
||||
struct ip_conntrack_tuple_hash *, iter, data);
|
||||
if (h)
|
||||
atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
return h;
|
||||
}
|
||||
@ -1201,14 +1188,14 @@ int __init ip_conntrack_init(void)
|
||||
}
|
||||
|
||||
/* Don't NEED lock here, but good form anyway. */
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
for (i = 0; i < MAX_IP_CT_PROTO; i++)
|
||||
ip_ct_protos[i] = &ip_conntrack_generic_protocol;
|
||||
/* Sew in builtin protocols. */
|
||||
ip_ct_protos[IPPROTO_TCP] = &ip_conntrack_protocol_tcp;
|
||||
ip_ct_protos[IPPROTO_UDP] = &ip_conntrack_protocol_udp;
|
||||
ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
for (i = 0; i < ip_conntrack_htable_size; i++)
|
||||
INIT_LIST_HEAD(&ip_conntrack_hash[i]);
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <net/checksum.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
|
||||
#include <linux/moduleparam.h>
|
||||
@ -28,7 +27,7 @@ MODULE_DESCRIPTION("ftp connection tracking helper");
|
||||
/* This is slow, but it's simple. --RR */
|
||||
static char ftp_buffer[65536];
|
||||
|
||||
static DECLARE_LOCK(ip_ftp_lock);
|
||||
static DEFINE_SPINLOCK(ip_ftp_lock);
|
||||
|
||||
#define MAX_PORTS 8
|
||||
static int ports[MAX_PORTS];
|
||||
@ -319,7 +318,7 @@ static int help(struct sk_buff **pskb,
|
||||
}
|
||||
datalen = (*pskb)->len - dataoff;
|
||||
|
||||
LOCK_BH(&ip_ftp_lock);
|
||||
spin_lock_bh(&ip_ftp_lock);
|
||||
fb_ptr = skb_header_pointer(*pskb, dataoff,
|
||||
(*pskb)->len - dataoff, ftp_buffer);
|
||||
BUG_ON(fb_ptr == NULL);
|
||||
@ -442,7 +441,7 @@ out_update_nl:
|
||||
if (ends_in_nl)
|
||||
update_nl_seq(seq, ct_ftp_info,dir);
|
||||
out:
|
||||
UNLOCK_BH(&ip_ftp_lock);
|
||||
spin_unlock_bh(&ip_ftp_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <net/checksum.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
|
||||
#include <linux/moduleparam.h>
|
||||
@ -41,7 +40,7 @@ static int max_dcc_channels = 8;
|
||||
static unsigned int dcc_timeout = 300;
|
||||
/* This is slow, but it's simple. --RR */
|
||||
static char irc_buffer[65536];
|
||||
static DECLARE_LOCK(irc_buffer_lock);
|
||||
static DEFINE_SPINLOCK(irc_buffer_lock);
|
||||
|
||||
unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
@ -141,7 +140,7 @@ static int help(struct sk_buff **pskb,
|
||||
if (dataoff >= (*pskb)->len)
|
||||
return NF_ACCEPT;
|
||||
|
||||
LOCK_BH(&irc_buffer_lock);
|
||||
spin_lock_bh(&irc_buffer_lock);
|
||||
ib_ptr = skb_header_pointer(*pskb, dataoff,
|
||||
(*pskb)->len - dataoff, irc_buffer);
|
||||
BUG_ON(ib_ptr == NULL);
|
||||
@ -237,7 +236,7 @@ static int help(struct sk_buff **pskb,
|
||||
} /* while data < ... */
|
||||
|
||||
out:
|
||||
UNLOCK_BH(&irc_buffer_lock);
|
||||
spin_unlock_bh(&irc_buffer_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
|
||||
#if 0
|
||||
#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
|
||||
@ -35,7 +34,7 @@
|
||||
#endif
|
||||
|
||||
/* Protects conntrack->proto.sctp */
|
||||
static DECLARE_RWLOCK(sctp_lock);
|
||||
static DEFINE_RWLOCK(sctp_lock);
|
||||
|
||||
/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
|
||||
closely. They're more complex. --RR
|
||||
@ -199,9 +198,9 @@ static int sctp_print_conntrack(struct seq_file *s,
|
||||
DEBUGP(__FUNCTION__);
|
||||
DEBUGP("\n");
|
||||
|
||||
READ_LOCK(&sctp_lock);
|
||||
read_lock_bh(&sctp_lock);
|
||||
state = conntrack->proto.sctp.state;
|
||||
READ_UNLOCK(&sctp_lock);
|
||||
read_unlock_bh(&sctp_lock);
|
||||
|
||||
return seq_printf(s, "%s ", sctp_conntrack_names[state]);
|
||||
}
|
||||
@ -343,13 +342,13 @@ static int sctp_packet(struct ip_conntrack *conntrack,
|
||||
|
||||
oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
|
||||
for_each_sctp_chunk (skb, sch, _sch, offset, count) {
|
||||
WRITE_LOCK(&sctp_lock);
|
||||
write_lock_bh(&sctp_lock);
|
||||
|
||||
/* Special cases of Verification tag check (Sec 8.5.1) */
|
||||
if (sch->type == SCTP_CID_INIT) {
|
||||
/* Sec 8.5.1 (A) */
|
||||
if (sh->vtag != 0) {
|
||||
WRITE_UNLOCK(&sctp_lock);
|
||||
write_unlock_bh(&sctp_lock);
|
||||
return -1;
|
||||
}
|
||||
} else if (sch->type == SCTP_CID_ABORT) {
|
||||
@ -357,7 +356,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
|
||||
if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
|
||||
&& !(sh->vtag == conntrack->proto.sctp.vtag
|
||||
[1 - CTINFO2DIR(ctinfo)])) {
|
||||
WRITE_UNLOCK(&sctp_lock);
|
||||
write_unlock_bh(&sctp_lock);
|
||||
return -1;
|
||||
}
|
||||
} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
|
||||
@ -366,13 +365,13 @@ static int sctp_packet(struct ip_conntrack *conntrack,
|
||||
&& !(sh->vtag == conntrack->proto.sctp.vtag
|
||||
[1 - CTINFO2DIR(ctinfo)]
|
||||
&& (sch->flags & 1))) {
|
||||
WRITE_UNLOCK(&sctp_lock);
|
||||
write_unlock_bh(&sctp_lock);
|
||||
return -1;
|
||||
}
|
||||
} else if (sch->type == SCTP_CID_COOKIE_ECHO) {
|
||||
/* Sec 8.5.1 (D) */
|
||||
if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
|
||||
WRITE_UNLOCK(&sctp_lock);
|
||||
write_unlock_bh(&sctp_lock);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -384,7 +383,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
|
||||
if (newconntrack == SCTP_CONNTRACK_MAX) {
|
||||
DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
|
||||
CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
|
||||
WRITE_UNLOCK(&sctp_lock);
|
||||
write_unlock_bh(&sctp_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -396,7 +395,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
|
||||
ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
|
||||
sizeof(_inithdr), &_inithdr);
|
||||
if (ih == NULL) {
|
||||
WRITE_UNLOCK(&sctp_lock);
|
||||
write_unlock_bh(&sctp_lock);
|
||||
return -1;
|
||||
}
|
||||
DEBUGP("Setting vtag %x for dir %d\n",
|
||||
@ -405,7 +404,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
|
||||
}
|
||||
|
||||
conntrack->proto.sctp.state = newconntrack;
|
||||
WRITE_UNLOCK(&sctp_lock);
|
||||
write_unlock_bh(&sctp_lock);
|
||||
}
|
||||
|
||||
ip_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
|
||||
#if 0
|
||||
#define DEBUGP printk
|
||||
@ -46,7 +45,7 @@
|
||||
#endif
|
||||
|
||||
/* Protects conntrack->proto.tcp */
|
||||
static DECLARE_RWLOCK(tcp_lock);
|
||||
static DEFINE_RWLOCK(tcp_lock);
|
||||
|
||||
/* "Be conservative in what you do,
|
||||
be liberal in what you accept from others."
|
||||
@ -330,9 +329,9 @@ static int tcp_print_conntrack(struct seq_file *s,
|
||||
{
|
||||
enum tcp_conntrack state;
|
||||
|
||||
READ_LOCK(&tcp_lock);
|
||||
read_lock_bh(&tcp_lock);
|
||||
state = conntrack->proto.tcp.state;
|
||||
READ_UNLOCK(&tcp_lock);
|
||||
read_unlock_bh(&tcp_lock);
|
||||
|
||||
return seq_printf(s, "%s ", tcp_conntrack_names[state]);
|
||||
}
|
||||
@ -738,14 +737,14 @@ void ip_conntrack_tcp_update(struct sk_buff *skb,
|
||||
|
||||
end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, iph, tcph);
|
||||
|
||||
WRITE_LOCK(&tcp_lock);
|
||||
write_lock_bh(&tcp_lock);
|
||||
/*
|
||||
* We have to worry for the ack in the reply packet only...
|
||||
*/
|
||||
if (after(end, conntrack->proto.tcp.seen[dir].td_end))
|
||||
conntrack->proto.tcp.seen[dir].td_end = end;
|
||||
conntrack->proto.tcp.last_end = end;
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
|
||||
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
|
||||
sender->td_end, sender->td_maxend, sender->td_maxwin,
|
||||
@ -857,7 +856,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
|
||||
sizeof(_tcph), &_tcph);
|
||||
BUG_ON(th == NULL);
|
||||
|
||||
WRITE_LOCK(&tcp_lock);
|
||||
write_lock_bh(&tcp_lock);
|
||||
old_state = conntrack->proto.tcp.state;
|
||||
dir = CTINFO2DIR(ctinfo);
|
||||
index = get_conntrack_index(th);
|
||||
@ -879,7 +878,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
|
||||
* that the client cannot but retransmit its SYN and
|
||||
* thus initiate a clean new session.
|
||||
*/
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
if (LOG_INVALID(IPPROTO_TCP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
|
||||
"ip_ct_tcp: killing out of sync session ");
|
||||
@ -894,7 +893,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
|
||||
conntrack->proto.tcp.last_end =
|
||||
segment_seq_plus_len(ntohl(th->seq), skb->len, iph, th);
|
||||
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
if (LOG_INVALID(IPPROTO_TCP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
|
||||
"ip_ct_tcp: invalid packet ignored ");
|
||||
@ -904,7 +903,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
|
||||
DEBUGP("ip_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
|
||||
dir, get_conntrack_index(th),
|
||||
old_state);
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
if (LOG_INVALID(IPPROTO_TCP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
|
||||
"ip_ct_tcp: invalid state ");
|
||||
@ -918,13 +917,13 @@ static int tcp_packet(struct ip_conntrack *conntrack,
|
||||
conntrack->proto.tcp.seen[dir].td_end)) {
|
||||
/* Attempt to reopen a closed connection.
|
||||
* Delete this connection and look up again. */
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
if (del_timer(&conntrack->timeout))
|
||||
conntrack->timeout.function((unsigned long)
|
||||
conntrack);
|
||||
return -NF_REPEAT;
|
||||
} else {
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
if (LOG_INVALID(IPPROTO_TCP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
|
||||
"ip_ct_tcp: invalid SYN");
|
||||
@ -949,7 +948,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
|
||||
|
||||
if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
|
||||
skb, iph, th)) {
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
in_window:
|
||||
@ -972,7 +971,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
|
||||
timeout = conntrack->proto.tcp.retrans >= ip_ct_tcp_max_retrans
|
||||
&& *tcp_timeouts[new_state] > ip_ct_tcp_timeout_max_retrans
|
||||
? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
|
||||
WRITE_UNLOCK(&tcp_lock);
|
||||
write_unlock_bh(&tcp_lock);
|
||||
|
||||
if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
|
||||
/* If only reply is a RST, we can consider ourselves not to
|
||||
|
@ -120,6 +120,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
|
||||
* and moreover root might send raw packets.
|
||||
* FIXME: Source route IP option packets --RR */
|
||||
if (hooknum == NF_IP_PRE_ROUTING
|
||||
&& skb->ip_summed != CHECKSUM_UNNECESSARY
|
||||
&& csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
|
||||
skb->ip_summed == CHECKSUM_HW ? skb->csum
|
||||
: skb_checksum(skb, iph->ihl*4, udplen, 0))) {
|
||||
|
@ -28,8 +28,8 @@
|
||||
#include <net/checksum.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
|
||||
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
|
||||
#define ASSERT_READ_LOCK(x)
|
||||
#define ASSERT_WRITE_LOCK(x)
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
@ -119,7 +119,7 @@ static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
|
||||
|
||||
static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
READ_LOCK(&ip_conntrack_lock);
|
||||
read_lock_bh(&ip_conntrack_lock);
|
||||
return ct_get_idx(seq, *pos);
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
||||
|
||||
static void ct_seq_stop(struct seq_file *s, void *v)
|
||||
{
|
||||
READ_UNLOCK(&ip_conntrack_lock);
|
||||
read_unlock_bh(&ip_conntrack_lock);
|
||||
}
|
||||
|
||||
static int ct_seq_show(struct seq_file *s, void *v)
|
||||
@ -140,7 +140,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||
const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash);
|
||||
struct ip_conntrack_protocol *proto;
|
||||
|
||||
MUST_BE_READ_LOCKED(&ip_conntrack_lock);
|
||||
ASSERT_READ_LOCK(&ip_conntrack_lock);
|
||||
IP_NF_ASSERT(conntrack);
|
||||
|
||||
/* we only want to print DIR_ORIGINAL */
|
||||
@ -239,7 +239,7 @@ static void *exp_seq_start(struct seq_file *s, loff_t *pos)
|
||||
|
||||
/* strange seq_file api calls stop even if we fail,
|
||||
* thus we need to grab lock since stop unlocks */
|
||||
READ_LOCK(&ip_conntrack_lock);
|
||||
read_lock_bh(&ip_conntrack_lock);
|
||||
|
||||
if (list_empty(e))
|
||||
return NULL;
|
||||
@ -267,7 +267,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
||||
|
||||
static void exp_seq_stop(struct seq_file *s, void *v)
|
||||
{
|
||||
READ_UNLOCK(&ip_conntrack_lock);
|
||||
read_unlock_bh(&ip_conntrack_lock);
|
||||
}
|
||||
|
||||
static int exp_seq_show(struct seq_file *s, void *v)
|
||||
@ -921,22 +921,22 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
ip_ct_protos[proto->proto] = proto;
|
||||
out:
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
|
||||
{
|
||||
WRITE_LOCK(&ip_conntrack_lock);
|
||||
write_lock_bh(&ip_conntrack_lock);
|
||||
ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol;
|
||||
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||
write_unlock_bh(&ip_conntrack_lock);
|
||||
|
||||
/* Somebody could be still looking at the proto in bh. */
|
||||
synchronize_net();
|
||||
|
@ -22,8 +22,8 @@
|
||||
#include <linux/udp.h>
|
||||
#include <linux/jhash.h>
|
||||
|
||||
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_READ_LOCK(x)
|
||||
#define ASSERT_WRITE_LOCK(x)
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
||||
@ -41,7 +41,7 @@
|
||||
#define DEBUGP(format, args...)
|
||||
#endif
|
||||
|
||||
DECLARE_RWLOCK(ip_nat_lock);
|
||||
DEFINE_RWLOCK(ip_nat_lock);
|
||||
|
||||
/* Calculated at init based on memory size */
|
||||
static unsigned int ip_nat_htable_size;
|
||||
@ -65,9 +65,9 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn)
|
||||
if (!(conn->status & IPS_NAT_DONE_MASK))
|
||||
return;
|
||||
|
||||
WRITE_LOCK(&ip_nat_lock);
|
||||
write_lock_bh(&ip_nat_lock);
|
||||
list_del(&conn->nat.info.bysource);
|
||||
WRITE_UNLOCK(&ip_nat_lock);
|
||||
write_unlock_bh(&ip_nat_lock);
|
||||
}
|
||||
|
||||
/* We do checksum mangling, so if they were wrong before they're still
|
||||
@ -142,7 +142,7 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple,
|
||||
unsigned int h = hash_by_src(tuple);
|
||||
struct ip_conntrack *ct;
|
||||
|
||||
READ_LOCK(&ip_nat_lock);
|
||||
read_lock_bh(&ip_nat_lock);
|
||||
list_for_each_entry(ct, &bysource[h], nat.info.bysource) {
|
||||
if (same_src(ct, tuple)) {
|
||||
/* Copy source part from reply tuple. */
|
||||
@ -151,12 +151,12 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple,
|
||||
result->dst = tuple->dst;
|
||||
|
||||
if (in_range(result, range)) {
|
||||
READ_UNLOCK(&ip_nat_lock);
|
||||
read_unlock_bh(&ip_nat_lock);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
READ_UNLOCK(&ip_nat_lock);
|
||||
read_unlock_bh(&ip_nat_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -297,9 +297,9 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
|
||||
unsigned int srchash
|
||||
= hash_by_src(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
|
||||
.tuple);
|
||||
WRITE_LOCK(&ip_nat_lock);
|
||||
write_lock_bh(&ip_nat_lock);
|
||||
list_add(&info->bysource, &bysource[srchash]);
|
||||
WRITE_UNLOCK(&ip_nat_lock);
|
||||
write_unlock_bh(&ip_nat_lock);
|
||||
}
|
||||
|
||||
/* It's done. */
|
||||
@ -474,23 +474,23 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
WRITE_LOCK(&ip_nat_lock);
|
||||
write_lock_bh(&ip_nat_lock);
|
||||
if (ip_nat_protos[proto->protonum] != &ip_nat_unknown_protocol) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
ip_nat_protos[proto->protonum] = proto;
|
||||
out:
|
||||
WRITE_UNLOCK(&ip_nat_lock);
|
||||
write_unlock_bh(&ip_nat_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Noone stores the protocol anywhere; simply delete it. */
|
||||
void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
|
||||
{
|
||||
WRITE_LOCK(&ip_nat_lock);
|
||||
write_lock_bh(&ip_nat_lock);
|
||||
ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol;
|
||||
WRITE_UNLOCK(&ip_nat_lock);
|
||||
write_unlock_bh(&ip_nat_lock);
|
||||
|
||||
/* Someone could be still looking at the proto in a bh. */
|
||||
synchronize_net();
|
||||
@ -509,13 +509,13 @@ int __init ip_nat_init(void)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Sew in builtin protocols. */
|
||||
WRITE_LOCK(&ip_nat_lock);
|
||||
write_lock_bh(&ip_nat_lock);
|
||||
for (i = 0; i < MAX_IP_NAT_PROTO; i++)
|
||||
ip_nat_protos[i] = &ip_nat_unknown_protocol;
|
||||
ip_nat_protos[IPPROTO_TCP] = &ip_nat_protocol_tcp;
|
||||
ip_nat_protos[IPPROTO_UDP] = &ip_nat_protocol_udp;
|
||||
ip_nat_protos[IPPROTO_ICMP] = &ip_nat_protocol_icmp;
|
||||
WRITE_UNLOCK(&ip_nat_lock);
|
||||
write_unlock_bh(&ip_nat_lock);
|
||||
|
||||
for (i = 0; i < ip_nat_htable_size; i++) {
|
||||
INIT_LIST_HEAD(&bysource[i]);
|
||||
|
@ -28,8 +28,8 @@
|
||||
#include <net/tcp.h>
|
||||
#include <net/udp.h>
|
||||
|
||||
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_READ_LOCK(x)
|
||||
#define ASSERT_WRITE_LOCK(x)
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
@ -47,7 +47,7 @@
|
||||
#define DUMP_OFFSET(x)
|
||||
#endif
|
||||
|
||||
static DECLARE_LOCK(ip_nat_seqofs_lock);
|
||||
static DEFINE_SPINLOCK(ip_nat_seqofs_lock);
|
||||
|
||||
/* Setup TCP sequence correction given this change at this sequence */
|
||||
static inline void
|
||||
@ -70,7 +70,7 @@ adjust_tcp_sequence(u32 seq,
|
||||
DEBUGP("ip_nat_resize_packet: Seq_offset before: ");
|
||||
DUMP_OFFSET(this_way);
|
||||
|
||||
LOCK_BH(&ip_nat_seqofs_lock);
|
||||
spin_lock_bh(&ip_nat_seqofs_lock);
|
||||
|
||||
/* SYN adjust. If it's uninitialized, or this is after last
|
||||
* correction, record it: we don't handle more than one
|
||||
@ -82,7 +82,7 @@ adjust_tcp_sequence(u32 seq,
|
||||
this_way->offset_before = this_way->offset_after;
|
||||
this_way->offset_after += sizediff;
|
||||
}
|
||||
UNLOCK_BH(&ip_nat_seqofs_lock);
|
||||
spin_unlock_bh(&ip_nat_seqofs_lock);
|
||||
|
||||
DEBUGP("ip_nat_resize_packet: Seq_offset after: ");
|
||||
DUMP_OFFSET(this_way);
|
||||
@ -142,9 +142,6 @@ static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
|
||||
/* Transfer socket to new skb. */
|
||||
if ((*pskb)->sk)
|
||||
skb_set_owner_w(nskb, (*pskb)->sk);
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
nskb->nf_debug = (*pskb)->nf_debug;
|
||||
#endif
|
||||
kfree_skb(*pskb);
|
||||
*pskb = nskb;
|
||||
return 1;
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include <net/route.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_READ_LOCK(x)
|
||||
#define ASSERT_WRITE_LOCK(x)
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ip_nat.h>
|
||||
|
@ -31,8 +31,8 @@
|
||||
#include <net/checksum.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
|
||||
#define ASSERT_READ_LOCK(x)
|
||||
#define ASSERT_WRITE_LOCK(x)
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_nat.h>
|
||||
#include <linux/netfilter_ipv4/ip_nat_rule.h>
|
||||
@ -373,7 +373,6 @@ static int init_or_cleanup(int init)
|
||||
cleanup_rule_init:
|
||||
ip_nat_rule_cleanup();
|
||||
cleanup_nothing:
|
||||
MUST_BE_READ_WRITE_UNLOCKED(&ip_nat_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,6 @@ static DECLARE_MUTEX(ipt_mutex);
|
||||
/* Must have mutex */
|
||||
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
|
||||
#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
#include <linux/netfilter_ipv4/listhelp.h>
|
||||
|
||||
#if 0
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
|
||||
#define CLUSTERIP_VERSION "0.6"
|
||||
|
||||
@ -41,6 +40,8 @@
|
||||
#define DEBUGP
|
||||
#endif
|
||||
|
||||
#define ASSERT_READ_LOCK(x)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("iptables target for CLUSTERIP");
|
||||
@ -67,7 +68,7 @@ static LIST_HEAD(clusterip_configs);
|
||||
|
||||
/* clusterip_lock protects the clusterip_configs list _AND_ the configurable
|
||||
* data within all structurses (num_local_nodes, local_nodes[]) */
|
||||
static DECLARE_RWLOCK(clusterip_lock);
|
||||
static DEFINE_RWLOCK(clusterip_lock);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static struct file_operations clusterip_proc_fops;
|
||||
@ -82,9 +83,9 @@ clusterip_config_get(struct clusterip_config *c) {
|
||||
static inline void
|
||||
clusterip_config_put(struct clusterip_config *c) {
|
||||
if (atomic_dec_and_test(&c->refcount)) {
|
||||
WRITE_LOCK(&clusterip_lock);
|
||||
write_lock_bh(&clusterip_lock);
|
||||
list_del(&c->list);
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0);
|
||||
dev_put(c->dev);
|
||||
kfree(c);
|
||||
@ -97,7 +98,7 @@ __clusterip_config_find(u_int32_t clusterip)
|
||||
{
|
||||
struct list_head *pos;
|
||||
|
||||
MUST_BE_READ_LOCKED(&clusterip_lock);
|
||||
ASSERT_READ_LOCK(&clusterip_lock);
|
||||
list_for_each(pos, &clusterip_configs) {
|
||||
struct clusterip_config *c = list_entry(pos,
|
||||
struct clusterip_config, list);
|
||||
@ -114,14 +115,14 @@ clusterip_config_find_get(u_int32_t clusterip)
|
||||
{
|
||||
struct clusterip_config *c;
|
||||
|
||||
READ_LOCK(&clusterip_lock);
|
||||
read_lock_bh(&clusterip_lock);
|
||||
c = __clusterip_config_find(clusterip);
|
||||
if (!c) {
|
||||
READ_UNLOCK(&clusterip_lock);
|
||||
read_unlock_bh(&clusterip_lock);
|
||||
return NULL;
|
||||
}
|
||||
atomic_inc(&c->refcount);
|
||||
READ_UNLOCK(&clusterip_lock);
|
||||
read_unlock_bh(&clusterip_lock);
|
||||
|
||||
return c;
|
||||
}
|
||||
@ -160,9 +161,9 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
|
||||
c->pde->data = c;
|
||||
#endif
|
||||
|
||||
WRITE_LOCK(&clusterip_lock);
|
||||
write_lock_bh(&clusterip_lock);
|
||||
list_add(&c->list, &clusterip_configs);
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
|
||||
return c;
|
||||
}
|
||||
@ -172,25 +173,25 @@ clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum)
|
||||
{
|
||||
int i;
|
||||
|
||||
WRITE_LOCK(&clusterip_lock);
|
||||
write_lock_bh(&clusterip_lock);
|
||||
|
||||
if (c->num_local_nodes >= CLUSTERIP_MAX_NODES
|
||||
|| nodenum > CLUSTERIP_MAX_NODES) {
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check if we alrady have this number in our array */
|
||||
for (i = 0; i < c->num_local_nodes; i++) {
|
||||
if (c->local_nodes[i] == nodenum) {
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
c->local_nodes[c->num_local_nodes++] = nodenum;
|
||||
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -199,10 +200,10 @@ clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
|
||||
{
|
||||
int i;
|
||||
|
||||
WRITE_LOCK(&clusterip_lock);
|
||||
write_lock_bh(&clusterip_lock);
|
||||
|
||||
if (c->num_local_nodes <= 1 || nodenum > CLUSTERIP_MAX_NODES) {
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -211,12 +212,12 @@ clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
|
||||
int size = sizeof(u_int16_t)*(c->num_local_nodes-(i+1));
|
||||
memmove(&c->local_nodes[i], &c->local_nodes[i+1], size);
|
||||
c->num_local_nodes--;
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_UNLOCK(&clusterip_lock);
|
||||
write_unlock_bh(&clusterip_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -286,21 +287,21 @@ clusterip_responsible(struct clusterip_config *config, u_int32_t hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
READ_LOCK(&clusterip_lock);
|
||||
read_lock_bh(&clusterip_lock);
|
||||
|
||||
if (config->num_local_nodes == 0) {
|
||||
READ_UNLOCK(&clusterip_lock);
|
||||
read_unlock_bh(&clusterip_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < config->num_local_nodes; i++) {
|
||||
if (config->local_nodes[i] == hash) {
|
||||
READ_UNLOCK(&clusterip_lock);
|
||||
read_unlock_bh(&clusterip_lock);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
READ_UNLOCK(&clusterip_lock);
|
||||
read_unlock_bh(&clusterip_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -578,7 +579,7 @@ static void *clusterip_seq_start(struct seq_file *s, loff_t *pos)
|
||||
struct clusterip_config *c = pde->data;
|
||||
unsigned int *nodeidx;
|
||||
|
||||
READ_LOCK(&clusterip_lock);
|
||||
read_lock_bh(&clusterip_lock);
|
||||
if (*pos >= c->num_local_nodes)
|
||||
return NULL;
|
||||
|
||||
@ -608,7 +609,7 @@ static void clusterip_seq_stop(struct seq_file *s, void *v)
|
||||
{
|
||||
kfree(v);
|
||||
|
||||
READ_UNLOCK(&clusterip_lock);
|
||||
read_unlock_bh(&clusterip_lock);
|
||||
}
|
||||
|
||||
static int clusterip_seq_show(struct seq_file *s, void *v)
|
||||
|
@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables MASQUERADE target module");
|
||||
#endif
|
||||
|
||||
/* Lock protects masq region inside conntrack */
|
||||
static DECLARE_RWLOCK(masq_lock);
|
||||
static DEFINE_RWLOCK(masq_lock);
|
||||
|
||||
/* FIXME: Multiple targets. --RR */
|
||||
static int
|
||||
@ -103,9 +103,9 @@ masquerade_target(struct sk_buff **pskb,
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
WRITE_LOCK(&masq_lock);
|
||||
write_lock_bh(&masq_lock);
|
||||
ct->nat.masq_index = out->ifindex;
|
||||
WRITE_UNLOCK(&masq_lock);
|
||||
write_unlock_bh(&masq_lock);
|
||||
|
||||
/* Transfer from original range. */
|
||||
newrange = ((struct ip_nat_range)
|
||||
@ -122,9 +122,9 @@ device_cmp(struct ip_conntrack *i, void *ifindex)
|
||||
{
|
||||
int ret;
|
||||
|
||||
READ_LOCK(&masq_lock);
|
||||
read_lock_bh(&masq_lock);
|
||||
ret = (i->nat.masq_index == (int)(long)ifindex);
|
||||
READ_UNLOCK(&masq_lock);
|
||||
read_unlock_bh(&masq_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -104,10 +104,12 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
|
||||
static void send_reset(struct sk_buff *oldskb, int hook)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
struct iphdr *iph = oldskb->nh.iph;
|
||||
struct tcphdr _otcph, *oth, *tcph;
|
||||
struct rtable *rt;
|
||||
u_int16_t tmp_port;
|
||||
u_int32_t tmp_addr;
|
||||
unsigned int tcplen;
|
||||
int needs_ack;
|
||||
int hh_len;
|
||||
|
||||
@ -124,7 +126,16 @@ static void send_reset(struct sk_buff *oldskb, int hook)
|
||||
if (oth->rst)
|
||||
return;
|
||||
|
||||
/* FIXME: Check checksum --RR */
|
||||
/* Check checksum */
|
||||
tcplen = oldskb->len - iph->ihl * 4;
|
||||
if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) ||
|
||||
(hook == NF_IP_LOCAL_IN &&
|
||||
oldskb->ip_summed != CHECKSUM_UNNECESSARY)) &&
|
||||
csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
|
||||
oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum :
|
||||
skb_checksum(oldskb, iph->ihl * 4, tcplen, 0)))
|
||||
return;
|
||||
|
||||
if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
|
||||
return;
|
||||
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_ULOG.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
@ -99,8 +98,8 @@ typedef struct {
|
||||
|
||||
static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS]; /* array of buffers */
|
||||
|
||||
static struct sock *nflognl; /* our socket */
|
||||
static DECLARE_LOCK(ulog_lock); /* spinlock */
|
||||
static struct sock *nflognl; /* our socket */
|
||||
static DEFINE_SPINLOCK(ulog_lock); /* spinlock */
|
||||
|
||||
/* send one ulog_buff_t to userspace */
|
||||
static void ulog_send(unsigned int nlgroupnum)
|
||||
@ -135,9 +134,9 @@ static void ulog_timer(unsigned long data)
|
||||
|
||||
/* lock to protect against somebody modifying our structure
|
||||
* from ipt_ulog_target at the same time */
|
||||
LOCK_BH(&ulog_lock);
|
||||
spin_lock_bh(&ulog_lock);
|
||||
ulog_send(data);
|
||||
UNLOCK_BH(&ulog_lock);
|
||||
spin_unlock_bh(&ulog_lock);
|
||||
}
|
||||
|
||||
static struct sk_buff *ulog_alloc_skb(unsigned int size)
|
||||
@ -193,7 +192,7 @@ static void ipt_ulog_packet(unsigned int hooknum,
|
||||
|
||||
ub = &ulog_buffers[groupnum];
|
||||
|
||||
LOCK_BH(&ulog_lock);
|
||||
spin_lock_bh(&ulog_lock);
|
||||
|
||||
if (!ub->skb) {
|
||||
if (!(ub->skb = ulog_alloc_skb(size)))
|
||||
@ -278,7 +277,7 @@ static void ipt_ulog_packet(unsigned int hooknum,
|
||||
ulog_send(groupnum);
|
||||
}
|
||||
|
||||
UNLOCK_BH(&ulog_lock);
|
||||
spin_unlock_bh(&ulog_lock);
|
||||
|
||||
return;
|
||||
|
||||
@ -288,7 +287,7 @@ nlmsg_failure:
|
||||
alloc_failure:
|
||||
PRINTR("ipt_ULOG: Error building netlink message\n");
|
||||
|
||||
UNLOCK_BH(&ulog_lock);
|
||||
spin_unlock_bh(&ulog_lock);
|
||||
}
|
||||
|
||||
static unsigned int ipt_ulog_target(struct sk_buff **pskb,
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ipt_hashlimit.h>
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
|
||||
/* FIXME: this is just for IP_NF_ASSERRT */
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
@ -92,7 +91,7 @@ struct ipt_hashlimit_htable {
|
||||
struct hlist_head hash[0]; /* hashtable itself */
|
||||
};
|
||||
|
||||
static DECLARE_LOCK(hashlimit_lock); /* protects htables list */
|
||||
static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */
|
||||
static DECLARE_MUTEX(hlimit_mutex); /* additional checkentry protection */
|
||||
static HLIST_HEAD(hashlimit_htables);
|
||||
static kmem_cache_t *hashlimit_cachep;
|
||||
@ -233,9 +232,9 @@ static int htable_create(struct ipt_hashlimit_info *minfo)
|
||||
hinfo->timer.function = htable_gc;
|
||||
add_timer(&hinfo->timer);
|
||||
|
||||
LOCK_BH(&hashlimit_lock);
|
||||
spin_lock_bh(&hashlimit_lock);
|
||||
hlist_add_head(&hinfo->node, &hashlimit_htables);
|
||||
UNLOCK_BH(&hashlimit_lock);
|
||||
spin_unlock_bh(&hashlimit_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -301,15 +300,15 @@ static struct ipt_hashlimit_htable *htable_find_get(char *name)
|
||||
struct ipt_hashlimit_htable *hinfo;
|
||||
struct hlist_node *pos;
|
||||
|
||||
LOCK_BH(&hashlimit_lock);
|
||||
spin_lock_bh(&hashlimit_lock);
|
||||
hlist_for_each_entry(hinfo, pos, &hashlimit_htables, node) {
|
||||
if (!strcmp(name, hinfo->pde->name)) {
|
||||
atomic_inc(&hinfo->use);
|
||||
UNLOCK_BH(&hashlimit_lock);
|
||||
spin_unlock_bh(&hashlimit_lock);
|
||||
return hinfo;
|
||||
}
|
||||
}
|
||||
UNLOCK_BH(&hashlimit_lock);
|
||||
spin_unlock_bh(&hashlimit_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -317,9 +316,9 @@ static struct ipt_hashlimit_htable *htable_find_get(char *name)
|
||||
static void htable_put(struct ipt_hashlimit_htable *hinfo)
|
||||
{
|
||||
if (atomic_dec_and_test(&hinfo->use)) {
|
||||
LOCK_BH(&hashlimit_lock);
|
||||
spin_lock_bh(&hashlimit_lock);
|
||||
hlist_del(&hinfo->node);
|
||||
UNLOCK_BH(&hashlimit_lock);
|
||||
spin_unlock_bh(&hashlimit_lock);
|
||||
htable_destroy(hinfo);
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ match(const struct sk_buff *skb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
READ_LOCK(&ip_conntrack_lock);
|
||||
read_lock_bh(&ip_conntrack_lock);
|
||||
if (!ct->master->helper) {
|
||||
DEBUGP("ipt_helper: master ct %p has no helper\n",
|
||||
exp->expectant);
|
||||
@ -69,7 +69,7 @@ match(const struct sk_buff *skb,
|
||||
ret ^= !strncmp(ct->master->helper->name, info->name,
|
||||
strlen(ct->master->helper->name));
|
||||
out_unlock:
|
||||
READ_UNLOCK(&ip_conntrack_lock);
|
||||
read_unlock_bh(&ip_conntrack_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -695,7 +695,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
|
||||
|
||||
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
|
||||
if (onlink == 0) {
|
||||
ip6_del_rt(rt, NULL, NULL);
|
||||
ip6_del_rt(rt, NULL, NULL, NULL);
|
||||
rt = NULL;
|
||||
} else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
|
||||
rt->rt6i_expires = expires;
|
||||
@ -1340,7 +1340,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
|
||||
if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT))
|
||||
rtmsg.rtmsg_flags |= RTF_NONEXTHOP;
|
||||
|
||||
ip6_route_add(&rtmsg, NULL, NULL);
|
||||
ip6_route_add(&rtmsg, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Create "default" multicast route to the interface */
|
||||
@ -1357,7 +1357,7 @@ static void addrconf_add_mroute(struct net_device *dev)
|
||||
rtmsg.rtmsg_ifindex = dev->ifindex;
|
||||
rtmsg.rtmsg_flags = RTF_UP;
|
||||
rtmsg.rtmsg_type = RTMSG_NEWROUTE;
|
||||
ip6_route_add(&rtmsg, NULL, NULL);
|
||||
ip6_route_add(&rtmsg, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void sit_route_add(struct net_device *dev)
|
||||
@ -1374,7 +1374,7 @@ static void sit_route_add(struct net_device *dev)
|
||||
rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP;
|
||||
rtmsg.rtmsg_ifindex = dev->ifindex;
|
||||
|
||||
ip6_route_add(&rtmsg, NULL, NULL);
|
||||
ip6_route_add(&rtmsg, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void addrconf_add_lroute(struct net_device *dev)
|
||||
@ -1467,7 +1467,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
|
||||
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
|
||||
if (rt->rt6i_flags&RTF_EXPIRES) {
|
||||
if (valid_lft == 0) {
|
||||
ip6_del_rt(rt, NULL, NULL);
|
||||
ip6_del_rt(rt, NULL, NULL, NULL);
|
||||
rt = NULL;
|
||||
} else {
|
||||
rt->rt6i_expires = rt_expires;
|
||||
@ -3094,7 +3094,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
|
||||
switch (event) {
|
||||
case RTM_NEWADDR:
|
||||
dst_hold(&ifp->rt->u.dst);
|
||||
if (ip6_ins_rt(ifp->rt, NULL, NULL))
|
||||
if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL))
|
||||
dst_release(&ifp->rt->u.dst);
|
||||
if (ifp->idev->cnf.forwarding)
|
||||
addrconf_join_anycast(ifp);
|
||||
@ -3104,7 +3104,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
|
||||
addrconf_leave_anycast(ifp);
|
||||
addrconf_leave_solict(ifp->idev, &ifp->addr);
|
||||
dst_hold(&ifp->rt->u.dst);
|
||||
if (ip6_del_rt(ifp->rt, NULL, NULL))
|
||||
if (ip6_del_rt(ifp->rt, NULL, NULL, NULL))
|
||||
dst_free(&ifp->rt->u.dst);
|
||||
else
|
||||
dst_release(&ifp->rt->u.dst);
|
||||
|
@ -337,7 +337,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
|
||||
write_unlock_bh(&idev->lock);
|
||||
|
||||
dst_hold(&rt->u.dst);
|
||||
if (ip6_ins_rt(rt, NULL, NULL))
|
||||
if (ip6_ins_rt(rt, NULL, NULL, NULL))
|
||||
dst_release(&rt->u.dst);
|
||||
|
||||
addrconf_join_solict(dev, &aca->aca_addr);
|
||||
@ -380,7 +380,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr)
|
||||
addrconf_leave_solict(idev, &aca->aca_addr);
|
||||
|
||||
dst_hold(&aca->aca_rt->u.dst);
|
||||
if (ip6_del_rt(aca->aca_rt, NULL, NULL))
|
||||
if (ip6_del_rt(aca->aca_rt, NULL, NULL, NULL))
|
||||
dst_free(&aca->aca_rt->u.dst);
|
||||
else
|
||||
dst_release(&aca->aca_rt->u.dst);
|
||||
|
@ -394,7 +394,7 @@ insert_above:
|
||||
*/
|
||||
|
||||
static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||
struct nlmsghdr *nlh)
|
||||
struct nlmsghdr *nlh, struct netlink_skb_parms *req)
|
||||
{
|
||||
struct rt6_info *iter = NULL;
|
||||
struct rt6_info **ins;
|
||||
@ -449,7 +449,7 @@ out:
|
||||
*ins = rt;
|
||||
rt->rt6i_node = fn;
|
||||
atomic_inc(&rt->rt6i_ref);
|
||||
inet6_rt_notify(RTM_NEWROUTE, rt, nlh);
|
||||
inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req);
|
||||
rt6_stats.fib_rt_entries++;
|
||||
|
||||
if ((fn->fn_flags & RTN_RTINFO) == 0) {
|
||||
@ -479,7 +479,8 @@ void fib6_force_start_gc(void)
|
||||
* with source addr info in sub-trees
|
||||
*/
|
||||
|
||||
int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
int fib6_add(struct fib6_node *root, struct rt6_info *rt,
|
||||
struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
|
||||
{
|
||||
struct fib6_node *fn;
|
||||
int err = -ENOMEM;
|
||||
@ -552,7 +553,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh,
|
||||
}
|
||||
#endif
|
||||
|
||||
err = fib6_add_rt2node(fn, rt, nlh);
|
||||
err = fib6_add_rt2node(fn, rt, nlh, req);
|
||||
|
||||
if (err == 0) {
|
||||
fib6_start_gc(rt);
|
||||
@ -859,7 +860,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
|
||||
}
|
||||
|
||||
static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
|
||||
struct nlmsghdr *nlh, void *_rtattr)
|
||||
struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
|
||||
{
|
||||
struct fib6_walker_t *w;
|
||||
struct rt6_info *rt = *rtp;
|
||||
@ -915,11 +916,11 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
|
||||
if (atomic_read(&rt->rt6i_ref) != 1) BUG();
|
||||
}
|
||||
|
||||
inet6_rt_notify(RTM_DELROUTE, rt, nlh);
|
||||
inet6_rt_notify(RTM_DELROUTE, rt, nlh, req);
|
||||
rt6_release(rt);
|
||||
}
|
||||
|
||||
int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
|
||||
{
|
||||
struct fib6_node *fn = rt->rt6i_node;
|
||||
struct rt6_info **rtp;
|
||||
@ -944,7 +945,7 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
|
||||
for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
|
||||
if (*rtp == rt) {
|
||||
fib6_del_route(fn, rtp, nlh, _rtattr);
|
||||
fib6_del_route(fn, rtp, nlh, _rtattr, req);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1073,7 +1074,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
|
||||
res = c->func(rt, c->arg);
|
||||
if (res < 0) {
|
||||
w->leaf = rt;
|
||||
res = fib6_del(rt, NULL, NULL);
|
||||
res = fib6_del(rt, NULL, NULL, NULL);
|
||||
if (res) {
|
||||
#if RT6_DEBUG >= 2
|
||||
printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
|
||||
|
@ -484,9 +484,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
|
||||
to->nf_bridge = from->nf_bridge;
|
||||
nf_bridge_get(to->nf_bridge);
|
||||
#endif
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
to->nf_debug = from->nf_debug;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -423,11 +423,12 @@ done:
|
||||
psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
|
||||
retv = ipv6_sock_mc_join(sk, greqs.gsr_interface,
|
||||
&psin6->sin6_addr);
|
||||
if (retv)
|
||||
/* prior join w/ different source is ok */
|
||||
if (retv && retv != -EADDRINUSE)
|
||||
break;
|
||||
omode = MCAST_INCLUDE;
|
||||
add = 1;
|
||||
} else /*IP_DROP_SOURCE_MEMBERSHIP */ {
|
||||
} else /* MCAST_LEAVE_SOURCE_GROUP */ {
|
||||
omode = MCAST_INCLUDE;
|
||||
add = 0;
|
||||
}
|
||||
|
@ -188,6 +188,16 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
|
||||
if (!ipv6_addr_is_multicast(addr))
|
||||
return -EINVAL;
|
||||
|
||||
read_lock_bh(&ipv6_sk_mc_lock);
|
||||
for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) {
|
||||
if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
|
||||
ipv6_addr_equal(&mc_lst->addr, addr)) {
|
||||
read_unlock_bh(&ipv6_sk_mc_lock);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
}
|
||||
read_unlock_bh(&ipv6_sk_mc_lock);
|
||||
|
||||
mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
|
||||
|
||||
if (mc_lst == NULL)
|
||||
@ -349,6 +359,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
|
||||
struct ipv6_pinfo *inet6 = inet6_sk(sk);
|
||||
struct ip6_sf_socklist *psl;
|
||||
int i, j, rv;
|
||||
int leavegroup = 0;
|
||||
int err;
|
||||
|
||||
if (pgsr->gsr_group.ss_family != AF_INET6 ||
|
||||
@ -368,6 +379,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
|
||||
|
||||
err = -EADDRNOTAVAIL;
|
||||
|
||||
read_lock_bh(&ipv6_sk_mc_lock);
|
||||
for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
|
||||
if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
|
||||
continue;
|
||||
@ -401,6 +413,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
|
||||
if (rv) /* source not found */
|
||||
goto done;
|
||||
|
||||
/* special case - (INCLUDE, empty) == LEAVE_GROUP */
|
||||
if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
|
||||
leavegroup = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* update the interface filter */
|
||||
ip6_mc_del_src(idev, group, omode, 1, source, 1);
|
||||
|
||||
@ -453,9 +471,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
|
||||
/* update the interface list */
|
||||
ip6_mc_add_src(idev, group, omode, 1, source, 1);
|
||||
done:
|
||||
read_unlock_bh(&ipv6_sk_mc_lock);
|
||||
read_unlock_bh(&idev->lock);
|
||||
in6_dev_put(idev);
|
||||
dev_put(dev);
|
||||
if (leavegroup)
|
||||
return ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1280,15 +1301,6 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
|
||||
return NULL;
|
||||
|
||||
skb_reserve(skb, LL_RESERVED_SPACE(dev));
|
||||
if (dev->hard_header) {
|
||||
unsigned char ha[MAX_ADDR_LEN];
|
||||
|
||||
ndisc_mc_map(&mld2_all_mcr, ha, dev, 1);
|
||||
if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) {
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ipv6_get_lladdr(dev, &addr_buf)) {
|
||||
/* <draft-ietf-magma-mld-source-05.txt>:
|
||||
@ -1312,6 +1324,30 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
|
||||
return skb;
|
||||
}
|
||||
|
||||
static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
|
||||
{
|
||||
struct net_device *dev = skb->dev;
|
||||
|
||||
if (dev->hard_header) {
|
||||
unsigned char ha[MAX_ADDR_LEN];
|
||||
int err;
|
||||
|
||||
ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1);
|
||||
err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len);
|
||||
if (err < 0) {
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return dev_queue_xmit(skb);
|
||||
}
|
||||
|
||||
static inline int mld_dev_queue_xmit(struct sk_buff *skb)
|
||||
{
|
||||
return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev,
|
||||
mld_dev_queue_xmit2);
|
||||
}
|
||||
|
||||
static void mld_sendpack(struct sk_buff *skb)
|
||||
{
|
||||
struct ipv6hdr *pip6 = skb->nh.ipv6h;
|
||||
@ -1329,7 +1365,7 @@ static void mld_sendpack(struct sk_buff *skb)
|
||||
pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
|
||||
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
|
||||
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
|
||||
dev_queue_xmit);
|
||||
mld_dev_queue_xmit);
|
||||
if (!err) {
|
||||
ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
|
||||
IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS);
|
||||
@ -1635,12 +1671,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
|
||||
}
|
||||
|
||||
skb_reserve(skb, LL_RESERVED_SPACE(dev));
|
||||
if (dev->hard_header) {
|
||||
unsigned char ha[MAX_ADDR_LEN];
|
||||
ndisc_mc_map(snd_addr, ha, dev, 1);
|
||||
if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ipv6_get_lladdr(dev, &addr_buf)) {
|
||||
/* <draft-ietf-magma-mld-source-05.txt>:
|
||||
@ -1668,7 +1698,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
|
||||
idev = in6_dev_get(skb->dev);
|
||||
|
||||
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
|
||||
dev_queue_xmit);
|
||||
mld_dev_queue_xmit);
|
||||
if (!err) {
|
||||
if (type == ICMPV6_MGM_REDUCTION)
|
||||
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS);
|
||||
@ -1682,10 +1712,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
|
||||
if (likely(idev != NULL))
|
||||
in6_dev_put(idev);
|
||||
return;
|
||||
|
||||
out:
|
||||
IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
|
||||
|
@ -955,7 +955,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
|
||||
struct rt6_info *rt;
|
||||
rt = rt6_get_dflt_router(saddr, dev);
|
||||
if (rt)
|
||||
ip6_del_rt(rt, NULL, NULL);
|
||||
ip6_del_rt(rt, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
@ -1096,7 +1096,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
|
||||
|
||||
if (rt && lifetime == 0) {
|
||||
neigh_clone(neigh);
|
||||
ip6_del_rt(rt, NULL, NULL);
|
||||
ip6_del_rt(rt, NULL, NULL, NULL);
|
||||
rt = NULL;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,6 @@ static DECLARE_MUTEX(ip6t_mutex);
|
||||
/* Must have mutex */
|
||||
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
|
||||
#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
|
||||
#include <linux/netfilter_ipv4/lockhelp.h>
|
||||
#include <linux/netfilter_ipv4/listhelp.h>
|
||||
|
||||
#if 0
|
||||
|
@ -366,8 +366,6 @@ ip6t_log_packet(unsigned int hooknum,
|
||||
const char *level_string,
|
||||
const char *prefix)
|
||||
{
|
||||
struct ipv6hdr *ipv6h = skb->nh.ipv6h;
|
||||
|
||||
spin_lock_bh(&log_lock);
|
||||
printk(level_string);
|
||||
printk("%sIN=%s OUT=%s ",
|
||||
@ -377,39 +375,25 @@ ip6t_log_packet(unsigned int hooknum,
|
||||
if (in && !out) {
|
||||
/* MAC logging for input chain only. */
|
||||
printk("MAC=");
|
||||
if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
|
||||
if (skb->dev->type != ARPHRD_SIT){
|
||||
int i;
|
||||
unsigned char *p = skb->mac.raw;
|
||||
for (i = 0; i < skb->dev->hard_header_len; i++,p++)
|
||||
printk("%02x%c", *p,
|
||||
i==skb->dev->hard_header_len - 1
|
||||
? ' ':':');
|
||||
} else {
|
||||
int i;
|
||||
unsigned char *p = skb->mac.raw;
|
||||
if ( p - (ETH_ALEN*2+2) > skb->head ){
|
||||
p -= (ETH_ALEN+2);
|
||||
for (i = 0; i < (ETH_ALEN); i++,p++)
|
||||
printk("%02x%s", *p,
|
||||
i == ETH_ALEN-1 ? "->" : ":");
|
||||
p -= (ETH_ALEN*2);
|
||||
for (i = 0; i < (ETH_ALEN); i++,p++)
|
||||
printk("%02x%c", *p,
|
||||
i == ETH_ALEN-1 ? ' ' : ':');
|
||||
}
|
||||
|
||||
if ((skb->dev->addr_len == 4) &&
|
||||
skb->dev->hard_header_len > 20){
|
||||
printk("TUNNEL=");
|
||||
p = skb->mac.raw + 12;
|
||||
for (i = 0; i < 4; i++,p++)
|
||||
printk("%3d%s", *p,
|
||||
i == 3 ? "->" : ".");
|
||||
for (i = 0; i < 4; i++,p++)
|
||||
printk("%3d%c", *p,
|
||||
i == 3 ? ' ' : '.');
|
||||
}
|
||||
if (skb->dev && skb->dev->hard_header_len &&
|
||||
skb->mac.raw != skb->nh.raw) {
|
||||
unsigned char *p = skb->mac.raw;
|
||||
int i;
|
||||
|
||||
if (skb->dev->type == ARPHRD_SIT &&
|
||||
(p -= ETH_HLEN) < skb->head)
|
||||
p = NULL;
|
||||
|
||||
if (p != NULL)
|
||||
for (i = 0; i < skb->dev->hard_header_len; i++)
|
||||
printk("%02x", p[i]);
|
||||
printk(" ");
|
||||
|
||||
if (skb->dev->type == ARPHRD_SIT) {
|
||||
struct iphdr *iph = (struct iphdr *)skb->mac.raw;
|
||||
printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ",
|
||||
NIPQUAD(iph->saddr),
|
||||
NIPQUAD(iph->daddr));
|
||||
}
|
||||
} else
|
||||
printk(" ");
|
||||
|
@ -129,13 +129,15 @@ static struct nf_hook_ops ip6t_ops[] = {
|
||||
.hook = ip6t_hook,
|
||||
.pf = PF_INET6,
|
||||
.hooknum = NF_IP6_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_FIRST
|
||||
.priority = NF_IP6_PRI_FIRST,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_hook,
|
||||
.pf = PF_INET6,
|
||||
.hooknum = NF_IP6_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_FIRST
|
||||
.priority = NF_IP6_PRI_FIRST,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -384,12 +384,13 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
|
||||
be destroyed.
|
||||
*/
|
||||
|
||||
int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh,
|
||||
void *_rtattr, struct netlink_skb_parms *req)
|
||||
{
|
||||
int err;
|
||||
|
||||
write_lock_bh(&rt6_lock);
|
||||
err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr);
|
||||
err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr, req);
|
||||
write_unlock_bh(&rt6_lock);
|
||||
|
||||
return err;
|
||||
@ -400,7 +401,7 @@ int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
*/
|
||||
|
||||
static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
|
||||
struct in6_addr *saddr)
|
||||
struct in6_addr *saddr, struct netlink_skb_parms *req)
|
||||
{
|
||||
int err;
|
||||
struct rt6_info *rt;
|
||||
@ -432,7 +433,7 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
|
||||
|
||||
dst_hold(&rt->u.dst);
|
||||
|
||||
err = ip6_ins_rt(rt, NULL, NULL);
|
||||
err = ip6_ins_rt(rt, NULL, NULL, req);
|
||||
if (err == 0)
|
||||
return rt;
|
||||
|
||||
@ -491,7 +492,8 @@ restart:
|
||||
read_unlock_bh(&rt6_lock);
|
||||
|
||||
nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr,
|
||||
&skb->nh.ipv6h->saddr);
|
||||
&skb->nh.ipv6h->saddr,
|
||||
&NETLINK_CB(skb));
|
||||
|
||||
dst_release(&rt->u.dst);
|
||||
rt = nrt;
|
||||
@ -551,7 +553,7 @@ restart:
|
||||
dst_hold(&rt->u.dst);
|
||||
read_unlock_bh(&rt6_lock);
|
||||
|
||||
nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src);
|
||||
nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src, NULL);
|
||||
|
||||
dst_release(&rt->u.dst);
|
||||
rt = nrt;
|
||||
@ -598,7 +600,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
|
||||
|
||||
if (rt) {
|
||||
if (rt->rt6i_flags & RTF_CACHE)
|
||||
ip6_del_rt(rt, NULL, NULL);
|
||||
ip6_del_rt(rt, NULL, NULL, NULL);
|
||||
else
|
||||
dst_release(dst);
|
||||
}
|
||||
@ -787,7 +789,8 @@ int ipv6_get_hoplimit(struct net_device *dev)
|
||||
*
|
||||
*/
|
||||
|
||||
int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
|
||||
int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
|
||||
void *_rtattr, struct netlink_skb_parms *req)
|
||||
{
|
||||
int err;
|
||||
struct rtmsg *r;
|
||||
@ -974,7 +977,7 @@ install_route:
|
||||
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
|
||||
rt->u.dst.dev = dev;
|
||||
rt->rt6i_idev = idev;
|
||||
return ip6_ins_rt(rt, nlh, _rtattr);
|
||||
return ip6_ins_rt(rt, nlh, _rtattr, req);
|
||||
|
||||
out:
|
||||
if (dev)
|
||||
@ -986,7 +989,7 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
|
||||
{
|
||||
int err;
|
||||
|
||||
@ -994,7 +997,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
|
||||
rt6_reset_dflt_pointer(NULL);
|
||||
|
||||
err = fib6_del(rt, nlh, _rtattr);
|
||||
err = fib6_del(rt, nlh, _rtattr, req);
|
||||
dst_release(&rt->u.dst);
|
||||
|
||||
write_unlock_bh(&rt6_lock);
|
||||
@ -1002,7 +1005,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
|
||||
static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
|
||||
{
|
||||
struct fib6_node *fn;
|
||||
struct rt6_info *rt;
|
||||
@ -1029,7 +1032,7 @@ static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_r
|
||||
dst_hold(&rt->u.dst);
|
||||
read_unlock_bh(&rt6_lock);
|
||||
|
||||
return ip6_del_rt(rt, nlh, _rtattr);
|
||||
return ip6_del_rt(rt, nlh, _rtattr, req);
|
||||
}
|
||||
}
|
||||
read_unlock_bh(&rt6_lock);
|
||||
@ -1136,11 +1139,11 @@ source_ok:
|
||||
nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev);
|
||||
nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst));
|
||||
|
||||
if (ip6_ins_rt(nrt, NULL, NULL))
|
||||
if (ip6_ins_rt(nrt, NULL, NULL, NULL))
|
||||
goto out;
|
||||
|
||||
if (rt->rt6i_flags&RTF_CACHE) {
|
||||
ip6_del_rt(rt, NULL, NULL);
|
||||
ip6_del_rt(rt, NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1204,7 +1207,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
|
||||
2. It is gatewayed route or NONEXTHOP route. Action: clone it.
|
||||
*/
|
||||
if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) {
|
||||
nrt = rt6_cow(rt, daddr, saddr);
|
||||
nrt = rt6_cow(rt, daddr, saddr, NULL);
|
||||
if (!nrt->u.dst.error) {
|
||||
nrt->u.dst.metrics[RTAX_MTU-1] = pmtu;
|
||||
if (allfrag)
|
||||
@ -1232,7 +1235,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
|
||||
nrt->u.dst.metrics[RTAX_MTU-1] = pmtu;
|
||||
if (allfrag)
|
||||
nrt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
|
||||
ip6_ins_rt(nrt, NULL, NULL);
|
||||
ip6_ins_rt(nrt, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
@ -1305,7 +1308,7 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
|
||||
|
||||
rtmsg.rtmsg_ifindex = dev->ifindex;
|
||||
|
||||
ip6_route_add(&rtmsg, NULL, NULL);
|
||||
ip6_route_add(&rtmsg, NULL, NULL, NULL);
|
||||
return rt6_get_dflt_router(gwaddr, dev);
|
||||
}
|
||||
|
||||
@ -1323,7 +1326,7 @@ restart:
|
||||
|
||||
read_unlock_bh(&rt6_lock);
|
||||
|
||||
ip6_del_rt(rt, NULL, NULL);
|
||||
ip6_del_rt(rt, NULL, NULL, NULL);
|
||||
|
||||
goto restart;
|
||||
}
|
||||
@ -1349,10 +1352,10 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
|
||||
rtnl_lock();
|
||||
switch (cmd) {
|
||||
case SIOCADDRT:
|
||||
err = ip6_route_add(&rtmsg, NULL, NULL);
|
||||
err = ip6_route_add(&rtmsg, NULL, NULL, NULL);
|
||||
break;
|
||||
case SIOCDELRT:
|
||||
err = ip6_route_del(&rtmsg, NULL, NULL);
|
||||
err = ip6_route_del(&rtmsg, NULL, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
@ -1546,7 +1549,7 @@ int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||
|
||||
if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
|
||||
return -EINVAL;
|
||||
return ip6_route_del(&rtmsg, nlh, arg);
|
||||
return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb));
|
||||
}
|
||||
|
||||
int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||
@ -1556,7 +1559,7 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||
|
||||
if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
|
||||
return -EINVAL;
|
||||
return ip6_route_add(&rtmsg, nlh, arg);
|
||||
return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb));
|
||||
}
|
||||
|
||||
struct rt6_rtnl_dump_arg
|
||||
@ -1566,12 +1569,9 @@ struct rt6_rtnl_dump_arg
|
||||
};
|
||||
|
||||
static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
|
||||
struct in6_addr *dst,
|
||||
struct in6_addr *src,
|
||||
int iif,
|
||||
int type, u32 pid, u32 seq,
|
||||
struct nlmsghdr *in_nlh, int prefix,
|
||||
unsigned int flags)
|
||||
struct in6_addr *dst, struct in6_addr *src,
|
||||
int iif, int type, u32 pid, u32 seq,
|
||||
int prefix, unsigned int flags)
|
||||
{
|
||||
struct rtmsg *rtm;
|
||||
struct nlmsghdr *nlh;
|
||||
@ -1585,10 +1585,6 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
|
||||
}
|
||||
}
|
||||
|
||||
if (!pid && in_nlh) {
|
||||
pid = in_nlh->nlmsg_pid;
|
||||
}
|
||||
|
||||
nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags);
|
||||
rtm = NLMSG_DATA(nlh);
|
||||
rtm->rtm_family = AF_INET6;
|
||||
@ -1675,7 +1671,7 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg)
|
||||
|
||||
return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
|
||||
NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
|
||||
NULL, prefix, NLM_F_MULTI);
|
||||
prefix, NLM_F_MULTI);
|
||||
}
|
||||
|
||||
static int fib6_dump_node(struct fib6_walker_t *w)
|
||||
@ -1823,7 +1819,7 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
|
||||
&fl.fl6_dst, &fl.fl6_src,
|
||||
iif,
|
||||
RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
|
||||
nlh->nlmsg_seq, nlh, 0, 0);
|
||||
nlh->nlmsg_seq, 0, 0);
|
||||
if (err < 0) {
|
||||
err = -EMSGSIZE;
|
||||
goto out_free;
|
||||
@ -1839,17 +1835,25 @@ out_free:
|
||||
goto out;
|
||||
}
|
||||
|
||||
void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh)
|
||||
void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh,
|
||||
struct netlink_skb_parms *req)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
|
||||
u32 pid = current->pid;
|
||||
u32 seq = 0;
|
||||
|
||||
if (req)
|
||||
pid = req->pid;
|
||||
if (nlh)
|
||||
seq = nlh->nlmsg_seq;
|
||||
|
||||
skb = alloc_skb(size, gfp_any());
|
||||
if (!skb) {
|
||||
netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS);
|
||||
return;
|
||||
}
|
||||
if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0, 0) < 0) {
|
||||
if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) {
|
||||
kfree_skb(skb);
|
||||
netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user