aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 08:26:19 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 08:26:19 -0700
commitd002ec481c24f325ed6cfcb7810d317c015dd1b5 (patch)
tree71fbdce6aab6ffb5f8590e7ddde7c095a7fa31ab
parent5a96c5d0c58ead9a0ece03ffe1c116dea6dafe9c (diff)
parent0a69452cb45add0841c2bc1e75c25f6bd4f1d8d9 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [XFRM]: BEET mode [TCP]: Kill warning in tcp_clean_rtx_queue(). [NET_SCHED]: Remove old estimator implementation [ATM]: [zatm] always *pcr in alloc_shaper() [ATM]: [ambassador] Change the return type to reflect reality [ATM]: kmalloc to kzalloc patches for drivers/atm [TIPC]: fix printk warning [XFRM]: Clearing xfrm_policy_count[] to zero during flush is incorrect. [XFRM] STATE: Use destination address for src hash. [NEIGH]: always use hash_mask under tbl lock [UDP]: Fix MSG_PROBE crash [UDP6]: Fix flowi clobbering [NET_SCHED]: Revert "HTB: fix incorrect use of RB_EMPTY_NODE" [NETFILTER]: ebt_mark: add or/and/xor action support to mark target [NETFILTER]: ipt_REJECT: remove largely duplicate route_reverse function [NETFILTER]: Honour source routing for LVS-NAT [NETFILTER]: add type parameter to ip_route_me_harder [NETFILTER]: Kconfig: fix xt_physdev dependencies
-rw-r--r--drivers/atm/adummy.c6
-rw-r--r--drivers/atm/ambassador.c4
-rw-r--r--drivers/atm/firestream.c12
-rw-r--r--drivers/atm/he.c4
-rw-r--r--drivers/atm/horizon.c4
-rw-r--r--drivers/atm/idt77252.c23
-rw-r--r--drivers/atm/lanai.c8
-rw-r--r--drivers/atm/zatm.c7
-rw-r--r--include/linux/in.h1
-rw-r--r--include/linux/ip.h9
-rw-r--r--include/linux/ipsec.h3
-rw-r--r--include/linux/netfilter_bridge/ebt_mark_t.h12
-rw-r--r--include/linux/netfilter_ipv4.h2
-rw-r--r--include/linux/xfrm.h3
-rw-r--r--net/bridge/netfilter/ebt_mark.c21
-rw-r--r--net/core/neighbour.c12
-rw-r--r--net/ipv4/Kconfig9
-rw-r--r--net/ipv4/Makefile1
-rw-r--r--net/ipv4/esp4.c26
-rw-r--r--net/ipv4/ipcomp.c5
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c10
-rw-r--r--net/ipv4/netfilter.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c3
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c97
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c3
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv4/xfrm4_mode_beet.c139
-rw-r--r--net/ipv6/Kconfig10
-rw-r--r--net/ipv6/Makefile1
-rw-r--r--net/ipv6/ipcomp6.c5
-rw-r--r--net/ipv6/udp.c64
-rw-r--r--net/ipv6/xfrm6_mode_beet.c107
-rw-r--r--net/netfilter/Kconfig2
-rw-r--r--net/sched/estimator.c196
-rw-r--r--net/sched/sch_htb.c2
-rw-r--r--net/tipc/link.c5
-rw-r--r--net/xfrm/xfrm_hash.h7
-rw-r--r--net/xfrm/xfrm_policy.c7
-rw-r--r--net/xfrm/xfrm_state.c16
-rw-r--r--net/xfrm/xfrm_user.c1
41 files changed, 462 insertions, 398 deletions
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
index 6cc93de0b71..ac2c10822be 100644
--- a/drivers/atm/adummy.c
+++ b/drivers/atm/adummy.c
@@ -113,15 +113,13 @@ static int __init adummy_init(void)
printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
- adummy_dev = (struct adummy_dev *) kmalloc(sizeof(struct adummy_dev),
+ adummy_dev = kzalloc(sizeof(struct adummy_dev),
GFP_KERNEL);
if (!adummy_dev) {
- printk(KERN_ERR DEV_LABEL ": kmalloc() failed\n");
+ printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
err = -ENOMEM;
goto out;
}
- memset(adummy_dev, 0, sizeof(struct adummy_dev));
-
atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
if (!atm_dev) {
printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 4521a249dd5..da599e6e9d3 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -915,8 +915,8 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id,
/********** make rate (not quite as much fun as Horizon) **********/
-static unsigned int make_rate (unsigned int rate, rounding r,
- u16 * bits, unsigned int * actual) {
+static int make_rate (unsigned int rate, rounding r,
+ u16 * bits, unsigned int * actual) {
unsigned char exp = -1; // hush gcc
unsigned int man = -1; // hush gcc
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 38fc054bd67..5f25e5efefc 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1784,7 +1784,7 @@ static int __devinit fs_init (struct fs_dev *dev)
write_fs (dev, RAM, (1 << (28 - FS155_VPI_BITS - FS155_VCI_BITS)) - 1);
dev->nchannels = FS155_NR_CHANNELS;
}
- dev->atm_vccs = kmalloc (dev->nchannels * sizeof (struct atm_vcc *),
+ dev->atm_vccs = kcalloc (dev->nchannels, sizeof (struct atm_vcc *),
GFP_KERNEL);
fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%Zd)\n",
dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *));
@@ -1794,9 +1794,8 @@ static int __devinit fs_init (struct fs_dev *dev)
/* XXX Clean up..... */
return 1;
}
- memset (dev->atm_vccs, 0, dev->nchannels * sizeof (struct atm_vcc *));
- dev->tx_inuse = kmalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
+ dev->tx_inuse = kzalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
fs_dprintk (FS_DEBUG_ALLOC, "Alloc tx_inuse: %p(%d)\n",
dev->atm_vccs, dev->nchannels / 8);
@@ -1805,8 +1804,6 @@ static int __devinit fs_init (struct fs_dev *dev)
/* XXX Clean up..... */
return 1;
}
- memset (dev->tx_inuse, 0, dev->nchannels / 8);
-
/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */
/* -- RAS2 : FS50 only: Default is OK. */
@@ -1893,14 +1890,11 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev,
if (pci_enable_device(pci_dev))
goto err_out;
- fs_dev = kmalloc (sizeof (struct fs_dev), GFP_KERNEL);
+ fs_dev = kzalloc (sizeof (struct fs_dev), GFP_KERNEL);
fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%Zd)\n",
fs_dev, sizeof (struct fs_dev));
if (!fs_dev)
goto err_out;
-
- memset (fs_dev, 0, sizeof (struct fs_dev));
-
atm_dev = atm_dev_register("fs", &ops, -1, NULL);
if (!atm_dev)
goto err_out_free_fs_dev;
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index f2511b42dba..b22a9142b24 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -383,14 +383,12 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
}
pci_set_drvdata(pci_dev, atm_dev);
- he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev),
+ he_dev = kzalloc(sizeof(struct he_dev),
GFP_KERNEL);
if (!he_dev) {
err = -ENOMEM;
goto init_one_failure;
}
- memset(he_dev, 0, sizeof(struct he_dev));
-
he_dev->pci_dev = pci_dev;
he_dev->atm_dev = atm_dev;
he_dev->atm_dev->dev_data = he_dev;
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index d1113e845f9..209dba1c70d 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2719,7 +2719,7 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
goto out_disable;
}
- dev = kmalloc(sizeof(hrz_dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(hrz_dev), GFP_KERNEL);
if (!dev) {
// perhaps we should be nice: deregister all adapters and abort?
PRINTD(DBG_ERR, "out of memory");
@@ -2727,8 +2727,6 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
goto out_release;
}
- memset(dev, 0, sizeof(hrz_dev));
-
pci_set_drvdata(pci_dev, dev);
// grab IRQ and install handler - move this someplace more sensible
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index b0369bb20f0..7487f0ad68e 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -642,11 +642,9 @@ alloc_scq(struct idt77252_dev *card, int class)
{
struct scq_info *scq;
- scq = (struct scq_info *) kmalloc(sizeof(struct scq_info), GFP_KERNEL);
+ scq = kzalloc(sizeof(struct scq_info), GFP_KERNEL);
if (!scq)
return NULL;
- memset(scq, 0, sizeof(struct scq_info));
-
scq->base = pci_alloc_consistent(card->pcidev, SCQ_SIZE,
&scq->paddr);
if (scq->base == NULL) {
@@ -2142,11 +2140,9 @@ idt77252_init_est(struct vc_map *vc, int pcr)
{
struct rate_estimator *est;
- est = kmalloc(sizeof(struct rate_estimator), GFP_KERNEL);
+ est = kzalloc(sizeof(struct rate_estimator), GFP_KERNEL);
if (!est)
return NULL;
- memset(est, 0, sizeof(*est));
-
est->maxcps = pcr < 0 ? -pcr : pcr;
est->cps = est->maxcps;
est->avcps = est->cps << 5;
@@ -2451,14 +2447,12 @@ idt77252_open(struct atm_vcc *vcc)
index = VPCI2VC(card, vpi, vci);
if (!card->vcs[index]) {
- card->vcs[index] = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+ card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
if (!card->vcs[index]) {
printk("%s: can't alloc vc in open()\n", card->name);
up(&card->mutex);
return -ENOMEM;
}
- memset(card->vcs[index], 0, sizeof(struct vc_map));
-
card->vcs[index]->card = card;
card->vcs[index]->index = index;
@@ -2926,13 +2920,11 @@ open_card_oam(struct idt77252_dev *card)
for (vci = 3; vci < 5; vci++) {
index = VPCI2VC(card, vpi, vci);
- vc = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+ vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
if (!vc) {
printk("%s: can't alloc vc\n", card->name);
return -ENOMEM;
}
- memset(vc, 0, sizeof(struct vc_map));
-
vc->index = index;
card->vcs[index] = vc;
@@ -2995,12 +2987,11 @@ open_card_ubr0(struct idt77252_dev *card)
{
struct vc_map *vc;
- vc = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+ vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
if (!vc) {
printk("%s: can't alloc vc\n", card->name);
return -ENOMEM;
}
- memset(vc, 0, sizeof(struct vc_map));
card->vcs[0] = vc;
vc->class = SCHED_UBR0;
@@ -3695,14 +3686,12 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
goto err_out_disable_pdev;
}
- card = kmalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
+ card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
if (!card) {
printk("idt77252-%d: can't allocate private data\n", index);
err = -ENOMEM;
goto err_out_disable_pdev;
}
- memset(card, 0, sizeof(struct idt77252_dev));
-
card->revision = revision;
card->index = index;
card->pcidev = pcidev;
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index fe60a59b7fc..b9568e10965 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -1482,16 +1482,10 @@ static inline void vcc_table_deallocate(const struct lanai_dev *lanai)
static inline struct lanai_vcc *new_lanai_vcc(void)
{
struct lanai_vcc *lvcc;
- lvcc = (struct lanai_vcc *) kmalloc(sizeof(*lvcc), GFP_KERNEL);
+ lvcc = kzalloc(sizeof(*lvcc), GFP_KERNEL);
if (likely(lvcc != NULL)) {
- lvcc->vbase = NULL;
- lvcc->rx.atmvcc = lvcc->tx.atmvcc = NULL;
- lvcc->nref = 0;
- memset(&lvcc->stats, 0, sizeof lvcc->stats);
- lvcc->rx.buf.start = lvcc->tx.buf.start = NULL;
skb_queue_head_init(&lvcc->tx.backlog);
#ifdef DEBUG
- lvcc->tx.unqueue = NULL;
lvcc->vci = -1;
#endif
}
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 2c65e82f0d6..083c5d3f2e1 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -603,9 +603,8 @@ static int start_rx(struct atm_dev *dev)
DPRINTK("start_rx\n");
zatm_dev = ZATM_DEV(dev);
size = sizeof(struct atm_vcc *)*zatm_dev->chans;
- zatm_dev->rx_map = (struct atm_vcc **) kmalloc(size,GFP_KERNEL);
+ zatm_dev->rx_map = kzalloc(size,GFP_KERNEL);
if (!zatm_dev->rx_map) return -ENOMEM;
- memset(zatm_dev->rx_map,0,size);
/* set VPI/VCI split (use all VCIs and give what's left to VPIs) */
zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);
/* prepare free buffer pools */
@@ -801,6 +800,7 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
i = m = 1;
zatm_dev->ubr_ref_cnt++;
zatm_dev->ubr = shaper;
+ *pcr = 0;
}
else {
if (min) {
@@ -951,9 +951,8 @@ static int open_tx_first(struct atm_vcc *vcc)
skb_queue_head_init(&zatm_vcc->tx_queue);
init_waitqueue_head(&zatm_vcc->tx_wait);
/* initialize ring */
- zatm_vcc->ring = kmalloc(RING_SIZE,GFP_KERNEL);
+ zatm_vcc->ring = kzalloc(RING_SIZE,GFP_KERNEL);
if (!zatm_vcc->ring) return -ENOMEM;
- memset(zatm_vcc->ring,0,RING_SIZE);
loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;
loop[0] = uPD98401_TXPD_V;
loop[1] = loop[2] = 0;
diff --git a/include/linux/in.h b/include/linux/in.h
index d79fc75fa7c..2619859f6e1 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -40,6 +40,7 @@ enum {
IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
IPPROTO_AH = 51, /* Authentication Header protocol */
+ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
IPPROTO_PIM = 103, /* Protocol Independent Multicast */
IPPROTO_COMP = 108, /* Compression Header protocol */
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 6b25d36fc54..ecee9bb27d0 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -80,6 +80,8 @@
#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+#define IPV4_BEET_PHMAXLEN 8
+
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
@@ -123,4 +125,11 @@ struct ip_comp_hdr {
__be16 cpi;
};
+struct ip_beet_phdr {
+ __u8 nexthdr;
+ __u8 hdrlen;
+ __u8 padlen;
+ __u8 reserved;
+};
+
#endif /* _LINUX_IP_H */
diff --git a/include/linux/ipsec.h b/include/linux/ipsec.h
index d3c527616b5..d17a6302a0e 100644
--- a/include/linux/ipsec.h
+++ b/include/linux/ipsec.h
@@ -12,7 +12,8 @@
enum {
IPSEC_MODE_ANY = 0, /* We do not support this for SA */
IPSEC_MODE_TRANSPORT = 1,
- IPSEC_MODE_TUNNEL = 2
+ IPSEC_MODE_TUNNEL = 2,
+ IPSEC_MODE_BEET = 3
};
enum {
diff --git a/include/linux/netfilter_bridge/ebt_mark_t.h b/include/linux/netfilter_bridge/ebt_mark_t.h
index 110fec6a40a..6270f6f3369 100644
--- a/include/linux/netfilter_bridge/ebt_mark_t.h
+++ b/include/linux/netfilter_bridge/ebt_mark_t.h
@@ -1,6 +1,18 @@
#ifndef __LINUX_BRIDGE_EBT_MARK_T_H
#define __LINUX_BRIDGE_EBT_MARK_T_H
+/* The target member is reused for adding new actions, the
+ * value of the real target is -1 to -NUM_STANDARD_TARGETS.
+ * For backward compatibility, the 4 lsb (2 would be enough,
+ * but let's play it safe) are kept to designate this target.
+ * The remaining bits designate the action. By making the set
+ * action 0xfffffff0, the result will look ok for older
+ * versions. [September 2006] */
+#define MARK_SET_VALUE (0xfffffff0)
+#define MARK_OR_VALUE (0xffffffe0)
+#define MARK_AND_VALUE (0xffffffd0)
+#define MARK_XOR_VALUE (0xffffffc0)
+
struct ebt_mark_t_info
{
unsigned long mark;
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index ce02c984f3b..5b63a231a76 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -77,7 +77,7 @@ enum nf_ip_hook_priorities {
#define SO_ORIGINAL_DST 80
#ifdef __KERNEL__
-extern int ip_route_me_harder(struct sk_buff **pskb);
+extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
extern int ip_xfrm_me_harder(struct sk_buff **pskb);
extern unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol);
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 430afd05826..8ae7f744917 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -129,7 +129,8 @@ enum
#define XFRM_MODE_TUNNEL 1
#define XFRM_MODE_ROUTEOPTIMIZATION 2
#define XFRM_MODE_IN_TRIGGER 3
-#define XFRM_MODE_MAX 4
+#define XFRM_MODE_BEET 4
+#define XFRM_MODE_MAX 5
/* Netlink configuration messages. */
enum {
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index 770c0df972a..b54306a934e 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -22,24 +22,37 @@ static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
const void *data, unsigned int datalen)
{
struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+ int action = info->target & -16;
- if ((*pskb)->nfmark != info->mark)
+ if (action == MARK_SET_VALUE)
(*pskb)->nfmark = info->mark;
+ else if (action == MARK_OR_VALUE)
+ (*pskb)->nfmark |= info->mark;
+ else if (action == MARK_AND_VALUE)
+ (*pskb)->nfmark &= info->mark;
+ else
+ (*pskb)->nfmark ^= info->mark;
- return info->target;
+ return info->target | -16;
}
static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+ int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
return -EINVAL;
- if (BASE_CHAIN && info->target == EBT_RETURN)
+ tmp = info->target | -16;
+ if (BASE_CHAIN && tmp == EBT_RETURN)
return -EINVAL;
CLEAR_BASE_CHAIN_BIT;
- if (INVALID_TARGET)
+ if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
+ return -EINVAL;
+ tmp = info->target & -16;
+ if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
+ tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
return -EINVAL;
return 0;
}
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 8ce8c471d86..b4b478353b2 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -344,12 +344,12 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
{
struct neighbour *n;
int key_len = tbl->key_len;
- u32 hash_val = tbl->hash(pkey, dev) & tbl->hash_mask;
+ u32 hash_val = tbl->hash(pkey, dev);
NEIGH_CACHE_STAT_INC(tbl, lookups);
read_lock_bh(&tbl->lock);
- for (n = tbl->hash_buckets[hash_val]; n; n = n->next) {
+ for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
neigh_hold(n);
NEIGH_CACHE_STAT_INC(tbl, hits);
@@ -364,12 +364,12 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey)
{
struct neighbour *n;
int key_len = tbl->key_len;
- u32 hash_val = tbl->hash(pkey, NULL) & tbl->hash_mask;
+ u32 hash_val = tbl->hash(pkey, NULL);
NEIGH_CACHE_STAT_INC(tbl, lookups);
read_lock_bh(&tbl->lock);
- for (n = tbl->hash_buckets[hash_val]; n; n = n->next) {
+ for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
if (!memcmp(n->primary_key, pkey, key_len)) {
neigh_hold(n);
NEIGH_CACHE_STAT_INC(tbl, hits);
@@ -1998,12 +1998,12 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
int rc, h, s_h = cb->args[1];
int idx, s_idx = idx = cb->args[2];
+ read_lock_bh(&tbl->lock);
for (h = 0; h <= tbl->hash_mask; h++) {
if (h < s_h)
continue;
if (h > s_h)
s_idx = 0;
- read_lock_bh(&tbl->lock);
for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next, idx++) {
if (idx < s_idx)
continue;
@@ -2016,8 +2016,8 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
goto out;
}
}
- read_unlock_bh(&tbl->lock);
}
+ read_unlock_bh(&tbl->lock);
rc = skb->len;
out:
cb->args[1] = h;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index d172a980444..5572071af73 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -434,6 +434,15 @@ config INET_XFRM_MODE_TUNNEL
If unsure, say Y.
+config INET_XFRM_MODE_BEET
+ tristate "IP: IPsec BEET mode"
+ default y
+ select XFRM
+ ---help---
+ Support for IPsec BEET mode.
+
+ If unsure, say Y.
+
config INET_DIAG
tristate "INET: socket monitoring interface"
default y
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f66049e28ae..15645c51520 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_INET_AH) += ah4.o
obj-$(CONFIG_INET_ESP) += esp4.o
obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o
+obj-$(CONFIG_INET_XFRM_MODE_BEET) += xfrm4_mode_beet.o
obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 13b29360d10..b5c205b5766 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -253,7 +253,8 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
* as per draft-ietf-ipsec-udp-encaps-06,
* section 3.1.2
*/
- if (x->props.mode == XFRM_MODE_TRANSPORT)
+ if (x->props.mode == XFRM_MODE_TRANSPORT ||
+ x->props.mode == XFRM_MODE_BEET)
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
@@ -271,17 +272,28 @@ static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
{
struct esp_data *esp = x->data;
u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
-
- if (x->props.mode == XFRM_MODE_TUNNEL) {
- mtu = ALIGN(mtu + 2, blksize);
- } else {
- /* The worst case. */
+ int enclen = 0;
+
+ switch (x->props.mode) {
+ case XFRM_MODE_TUNNEL:
+ mtu = ALIGN(mtu +2, blksize);
+ break;
+ default:
+ case XFRM_MODE_TRANSPORT:
+ /* The worst case */
mtu = ALIGN(mtu + 2, 4) + blksize - 4;
+ break;
+ case XFRM_MODE_BEET:
+ /* The worst case. */
+ enclen = IPV4_BEET_PHMAXLEN;
+ mtu = ALIGN(mtu + enclen + 2, blksize);
+ break;
}
+
if (esp->conf.padlen)
mtu = ALIGN(mtu, esp->conf.padlen);
- return mtu + x->props.header_len + esp->auth.icv_trunc_len;
+ return mtu + x->props.header_len + esp->auth.icv_trunc_len - enclen;
}
static void esp4_err(struct sk_buff *skb, u32 info)
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 2017d36024d..3839b706142 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -206,6 +206,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
{
struct xfrm_state *t;
+ u8 mode = XFRM_MODE_TUNNEL;
t = xfrm_state_alloc();
if (t == NULL)
@@ -216,7 +217,9 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t->id.daddr.a4 = x->id.daddr.a4;
memcpy(&t->sel, &x->sel, sizeof(t->sel));
t->props.family = AF_INET;
- t->props.mode = XFRM_MODE_TUNNEL;
+ if (x->props.mode == XFRM_MODE_BEET)
+ mode = x->props.mode;
+ t->props.mode = mode;
t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 6dee03935f7..1445bb47fea 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -813,6 +813,16 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
skb->nh.iph->saddr = cp->vaddr;
ip_send_check(skb->nh.iph);
+ /* For policy routing, packets originating from this
+ * machine itself may be routed differently to packets
+ * passing through. We want this packet to be routed as
+ * if it came from this machine itself. So re-compute
+ * the routing information.
+ */
+ if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
+ goto drop;
+ skb = *pskb;
+
IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
ip_vs_out_stats(cp, skb);
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 5ac15379a0c..e2005c6810a 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -8,7 +8,7 @@
#include <net/ip.h>
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
-int ip_route_me_harder(struct sk_buff **pskb)
+int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
{
struct iphdr *iph = (*pskb)->nh.iph;
struct rtable *rt;
@@ -16,10 +16,13 @@ int ip_route_me_harder(struct sk_buff **pskb)
struct dst_entry *odst;
unsigned int hh_len;
+ if (addr_type == RTN_UNSPEC)
+ addr_type = inet_addr_type(iph->saddr);
+
/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
* packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
*/
- if (inet_addr_type(iph->saddr) == RTN_LOCAL) {
+ if (addr_type == RTN_LOCAL) {
fl.nl_u.ip4_u.daddr = iph->daddr;
fl.nl_u.ip4_u.saddr = iph->saddr;
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
@@ -156,7 +159,7 @@ static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info)
if (!(iph->tos == rt_info->tos
&& iph->daddr == rt_info->daddr
&& iph->saddr == rt_info->saddr))
- return ip_route_me_harder(pskb);
+ return ip_route_me_harder(pskb, RTN_UNSPEC);
}
return 0;
}
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 021395b6746..d85d2de5044 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -265,7 +265,8 @@ ip_nat_local_fn(unsigned int hooknum,
ct->tuplehash[!dir].tuple.src.u.all
#endif
)
- return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ if (ip_route_me_harder(pskb, RTN_UNSPEC))
+ ret = NF_DROP;
}
return ret;
}
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index fd0c05efed8..ad0312d0e4f 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -38,76 +38,16 @@ MODULE_DESCRIPTION("iptables REJECT target module");
#define DEBUGP(format, args...)
#endif
-static inline struct rtable *route_reverse(struct sk_buff *skb,
- struct tcphdr *tcph, int hook)
-{
- struct iphdr *iph = skb->nh.iph