mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 00:52:01 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
commit
15578eeb6c
@ -1925,8 +1925,8 @@ static void cas_tx(struct net_device *dev, struct cas *cp,
|
|||||||
u64 compwb = le64_to_cpu(cp->init_block->tx_compwb);
|
u64 compwb = le64_to_cpu(cp->init_block->tx_compwb);
|
||||||
#endif
|
#endif
|
||||||
if (netif_msg_intr(cp))
|
if (netif_msg_intr(cp))
|
||||||
printk(KERN_DEBUG "%s: tx interrupt, status: 0x%x, %lx\n",
|
printk(KERN_DEBUG "%s: tx interrupt, status: 0x%x, %llx\n",
|
||||||
cp->dev->name, status, compwb);
|
cp->dev->name, status, (unsigned long long)compwb);
|
||||||
/* process all the rings */
|
/* process all the rings */
|
||||||
for (ring = 0; ring < N_TX_RINGS; ring++) {
|
for (ring = 0; ring < N_TX_RINGS; ring++) {
|
||||||
#ifdef USE_TX_COMPWB
|
#ifdef USE_TX_COMPWB
|
||||||
|
@ -69,8 +69,8 @@
|
|||||||
|
|
||||||
#define DRV_MODULE_NAME "tg3"
|
#define DRV_MODULE_NAME "tg3"
|
||||||
#define PFX DRV_MODULE_NAME ": "
|
#define PFX DRV_MODULE_NAME ": "
|
||||||
#define DRV_MODULE_VERSION "3.47"
|
#define DRV_MODULE_VERSION "3.48"
|
||||||
#define DRV_MODULE_RELDATE "Dec 28, 2005"
|
#define DRV_MODULE_RELDATE "Jan 16, 2006"
|
||||||
|
|
||||||
#define TG3_DEF_MAC_MODE 0
|
#define TG3_DEF_MAC_MODE 0
|
||||||
#define TG3_DEF_RX_MODE 0
|
#define TG3_DEF_RX_MODE 0
|
||||||
@ -1325,10 +1325,12 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
|
|||||||
val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
|
val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
|
||||||
tw32(0x7d00, val);
|
tw32(0x7d00, val);
|
||||||
if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
|
if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
|
||||||
tg3_nvram_lock(tp);
|
int err;
|
||||||
|
|
||||||
|
err = tg3_nvram_lock(tp);
|
||||||
tg3_halt_cpu(tp, RX_CPU_BASE);
|
tg3_halt_cpu(tp, RX_CPU_BASE);
|
||||||
tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0);
|
if (!err)
|
||||||
tg3_nvram_unlock(tp);
|
tg3_nvram_unlock(tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4193,14 +4195,19 @@ static int tg3_nvram_lock(struct tg3 *tp)
|
|||||||
if (tp->tg3_flags & TG3_FLAG_NVRAM) {
|
if (tp->tg3_flags & TG3_FLAG_NVRAM) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
tw32(NVRAM_SWARB, SWARB_REQ_SET1);
|
if (tp->nvram_lock_cnt == 0) {
|
||||||
for (i = 0; i < 8000; i++) {
|
tw32(NVRAM_SWARB, SWARB_REQ_SET1);
|
||||||
if (tr32(NVRAM_SWARB) & SWARB_GNT1)
|
for (i = 0; i < 8000; i++) {
|
||||||
break;
|
if (tr32(NVRAM_SWARB) & SWARB_GNT1)
|
||||||
udelay(20);
|
break;
|
||||||
|
udelay(20);
|
||||||
|
}
|
||||||
|
if (i == 8000) {
|
||||||
|
tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (i == 8000)
|
tp->nvram_lock_cnt++;
|
||||||
return -ENODEV;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -4208,8 +4215,12 @@ static int tg3_nvram_lock(struct tg3 *tp)
|
|||||||
/* tp->lock is held. */
|
/* tp->lock is held. */
|
||||||
static void tg3_nvram_unlock(struct tg3 *tp)
|
static void tg3_nvram_unlock(struct tg3 *tp)
|
||||||
{
|
{
|
||||||
if (tp->tg3_flags & TG3_FLAG_NVRAM)
|
if (tp->tg3_flags & TG3_FLAG_NVRAM) {
|
||||||
tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
|
if (tp->nvram_lock_cnt > 0)
|
||||||
|
tp->nvram_lock_cnt--;
|
||||||
|
if (tp->nvram_lock_cnt == 0)
|
||||||
|
tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tp->lock is held. */
|
/* tp->lock is held. */
|
||||||
@ -4320,8 +4331,13 @@ static int tg3_chip_reset(struct tg3 *tp)
|
|||||||
void (*write_op)(struct tg3 *, u32, u32);
|
void (*write_op)(struct tg3 *, u32, u32);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
|
if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
|
||||||
tg3_nvram_lock(tp);
|
tg3_nvram_lock(tp);
|
||||||
|
/* No matching tg3_nvram_unlock() after this because
|
||||||
|
* chip reset below will undo the nvram lock.
|
||||||
|
*/
|
||||||
|
tp->nvram_lock_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must avoid the readl() that normally takes place.
|
* We must avoid the readl() that normally takes place.
|
||||||
@ -4717,6 +4733,10 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
|
|||||||
(offset == RX_CPU_BASE ? "RX" : "TX"));
|
(offset == RX_CPU_BASE ? "RX" : "TX"));
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear firmware's nvram arbitration. */
|
||||||
|
if (tp->tg3_flags & TG3_FLAG_NVRAM)
|
||||||
|
tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4736,7 +4756,7 @@ struct fw_info {
|
|||||||
static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base,
|
static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base,
|
||||||
int cpu_scratch_size, struct fw_info *info)
|
int cpu_scratch_size, struct fw_info *info)
|
||||||
{
|
{
|
||||||
int err, i;
|
int err, lock_err, i;
|
||||||
void (*write_op)(struct tg3 *, u32, u32);
|
void (*write_op)(struct tg3 *, u32, u32);
|
||||||
|
|
||||||
if (cpu_base == TX_CPU_BASE &&
|
if (cpu_base == TX_CPU_BASE &&
|
||||||
@ -4755,9 +4775,10 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
|
|||||||
/* It is possible that bootcode is still loading at this point.
|
/* It is possible that bootcode is still loading at this point.
|
||||||
* Get the nvram lock first before halting the cpu.
|
* Get the nvram lock first before halting the cpu.
|
||||||
*/
|
*/
|
||||||
tg3_nvram_lock(tp);
|
lock_err = tg3_nvram_lock(tp);
|
||||||
err = tg3_halt_cpu(tp, cpu_base);
|
err = tg3_halt_cpu(tp, cpu_base);
|
||||||
tg3_nvram_unlock(tp);
|
if (!lock_err)
|
||||||
|
tg3_nvram_unlock(tp);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -8182,7 +8203,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
|
|||||||
data[1] = 1;
|
data[1] = 1;
|
||||||
}
|
}
|
||||||
if (etest->flags & ETH_TEST_FL_OFFLINE) {
|
if (etest->flags & ETH_TEST_FL_OFFLINE) {
|
||||||
int irq_sync = 0;
|
int err, irq_sync = 0;
|
||||||
|
|
||||||
if (netif_running(dev)) {
|
if (netif_running(dev)) {
|
||||||
tg3_netif_stop(tp);
|
tg3_netif_stop(tp);
|
||||||
@ -8192,11 +8213,12 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
|
|||||||
tg3_full_lock(tp, irq_sync);
|
tg3_full_lock(tp, irq_sync);
|
||||||
|
|
||||||
tg3_halt(tp, RESET_KIND_SUSPEND, 1);
|
tg3_halt(tp, RESET_KIND_SUSPEND, 1);
|
||||||
tg3_nvram_lock(tp);
|
err = tg3_nvram_lock(tp);
|
||||||
tg3_halt_cpu(tp, RX_CPU_BASE);
|
tg3_halt_cpu(tp, RX_CPU_BASE);
|
||||||
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
|
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
|
||||||
tg3_halt_cpu(tp, TX_CPU_BASE);
|
tg3_halt_cpu(tp, TX_CPU_BASE);
|
||||||
tg3_nvram_unlock(tp);
|
if (!err)
|
||||||
|
tg3_nvram_unlock(tp);
|
||||||
|
|
||||||
if (tg3_test_registers(tp) != 0) {
|
if (tg3_test_registers(tp) != 0) {
|
||||||
etest->flags |= ETH_TEST_FL_FAILED;
|
etest->flags |= ETH_TEST_FL_FAILED;
|
||||||
@ -8588,7 +8610,11 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
|
|||||||
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
|
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
|
||||||
tp->tg3_flags |= TG3_FLAG_NVRAM;
|
tp->tg3_flags |= TG3_FLAG_NVRAM;
|
||||||
|
|
||||||
tg3_nvram_lock(tp);
|
if (tg3_nvram_lock(tp)) {
|
||||||
|
printk(KERN_WARNING PFX "%s: Cannot get nvarm lock, "
|
||||||
|
"tg3_nvram_init failed.\n", tp->dev->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tg3_enable_nvram_access(tp);
|
tg3_enable_nvram_access(tp);
|
||||||
|
|
||||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
|
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
|
||||||
@ -8686,7 +8712,9 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
|
|||||||
if (offset > NVRAM_ADDR_MSK)
|
if (offset > NVRAM_ADDR_MSK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
tg3_nvram_lock(tp);
|
ret = tg3_nvram_lock(tp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
tg3_enable_nvram_access(tp);
|
tg3_enable_nvram_access(tp);
|
||||||
|
|
||||||
@ -8785,10 +8813,6 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
|
|||||||
|
|
||||||
offset = offset + (pagesize - page_off);
|
offset = offset + (pagesize - page_off);
|
||||||
|
|
||||||
/* Nvram lock released by tg3_nvram_read() above,
|
|
||||||
* so need to get it again.
|
|
||||||
*/
|
|
||||||
tg3_nvram_lock(tp);
|
|
||||||
tg3_enable_nvram_access(tp);
|
tg3_enable_nvram_access(tp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8925,7 +8949,9 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
|
|||||||
else {
|
else {
|
||||||
u32 grc_mode;
|
u32 grc_mode;
|
||||||
|
|
||||||
tg3_nvram_lock(tp);
|
ret = tg3_nvram_lock(tp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
tg3_enable_nvram_access(tp);
|
tg3_enable_nvram_access(tp);
|
||||||
if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
|
if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
|
||||||
|
@ -2275,6 +2275,7 @@ struct tg3 {
|
|||||||
dma_addr_t stats_mapping;
|
dma_addr_t stats_mapping;
|
||||||
struct work_struct reset_task;
|
struct work_struct reset_task;
|
||||||
|
|
||||||
|
int nvram_lock_cnt;
|
||||||
u32 nvram_size;
|
u32 nvram_size;
|
||||||
u32 nvram_pagesize;
|
u32 nvram_pagesize;
|
||||||
u32 nvram_jedecnum;
|
u32 nvram_jedecnum;
|
||||||
|
@ -228,6 +228,7 @@ extern void dump_stack(void);
|
|||||||
ntohs((addr).s6_addr16[6]), \
|
ntohs((addr).s6_addr16[6]), \
|
||||||
ntohs((addr).s6_addr16[7])
|
ntohs((addr).s6_addr16[7])
|
||||||
#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
|
#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
|
||||||
|
#define NIP6_SEQFMT "%04x%04x%04x%04x%04x%04x%04x%04x"
|
||||||
|
|
||||||
#if defined(__LITTLE_ENDIAN)
|
#if defined(__LITTLE_ENDIAN)
|
||||||
#define HIPQUAD(addr) \
|
#define HIPQUAD(addr) \
|
||||||
|
@ -18,13 +18,4 @@ struct ip6t_ah
|
|||||||
#define IP6T_AH_INV_LEN 0x02 /* Invert the sense of length. */
|
#define IP6T_AH_INV_LEN 0x02 /* Invert the sense of length. */
|
||||||
#define IP6T_AH_INV_MASK 0x03 /* All possible flags. */
|
#define IP6T_AH_INV_MASK 0x03 /* All possible flags. */
|
||||||
|
|
||||||
#define MASK_HOPOPTS 128
|
|
||||||
#define MASK_DSTOPTS 64
|
|
||||||
#define MASK_ROUTING 32
|
|
||||||
#define MASK_FRAGMENT 16
|
|
||||||
#define MASK_AH 8
|
|
||||||
#define MASK_ESP 4
|
|
||||||
#define MASK_NONE 2
|
|
||||||
#define MASK_PROTO 1
|
|
||||||
|
|
||||||
#endif /*_IP6T_AH_H*/
|
#endif /*_IP6T_AH_H*/
|
||||||
|
@ -7,15 +7,6 @@ struct ip6t_esp
|
|||||||
u_int8_t invflags; /* Inverse flags */
|
u_int8_t invflags; /* Inverse flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MASK_HOPOPTS 128
|
|
||||||
#define MASK_DSTOPTS 64
|
|
||||||
#define MASK_ROUTING 32
|
|
||||||
#define MASK_FRAGMENT 16
|
|
||||||
#define MASK_AH 8
|
|
||||||
#define MASK_ESP 4
|
|
||||||
#define MASK_NONE 2
|
|
||||||
#define MASK_PROTO 1
|
|
||||||
|
|
||||||
/* Values for "invflags" field in struct ip6t_esp. */
|
/* Values for "invflags" field in struct ip6t_esp. */
|
||||||
#define IP6T_ESP_INV_SPI 0x01 /* Invert the sense of spi. */
|
#define IP6T_ESP_INV_SPI 0x01 /* Invert the sense of spi. */
|
||||||
#define IP6T_ESP_INV_MASK 0x01 /* All possible flags. */
|
#define IP6T_ESP_INV_MASK 0x01 /* All possible flags. */
|
||||||
|
@ -21,13 +21,4 @@ struct ip6t_frag
|
|||||||
#define IP6T_FRAG_INV_LEN 0x02 /* Invert the sense of length. */
|
#define IP6T_FRAG_INV_LEN 0x02 /* Invert the sense of length. */
|
||||||
#define IP6T_FRAG_INV_MASK 0x03 /* All possible flags. */
|
#define IP6T_FRAG_INV_MASK 0x03 /* All possible flags. */
|
||||||
|
|
||||||
#define MASK_HOPOPTS 128
|
|
||||||
#define MASK_DSTOPTS 64
|
|
||||||
#define MASK_ROUTING 32
|
|
||||||
#define MASK_FRAGMENT 16
|
|
||||||
#define MASK_AH 8
|
|
||||||
#define MASK_ESP 4
|
|
||||||
#define MASK_NONE 2
|
|
||||||
#define MASK_PROTO 1
|
|
||||||
|
|
||||||
#endif /*_IP6T_FRAG_H*/
|
#endif /*_IP6T_FRAG_H*/
|
||||||
|
@ -20,13 +20,4 @@ struct ip6t_opts
|
|||||||
#define IP6T_OPTS_INV_LEN 0x01 /* Invert the sense of length. */
|
#define IP6T_OPTS_INV_LEN 0x01 /* Invert the sense of length. */
|
||||||
#define IP6T_OPTS_INV_MASK 0x01 /* All possible flags. */
|
#define IP6T_OPTS_INV_MASK 0x01 /* All possible flags. */
|
||||||
|
|
||||||
#define MASK_HOPOPTS 128
|
|
||||||
#define MASK_DSTOPTS 64
|
|
||||||
#define MASK_ROUTING 32
|
|
||||||
#define MASK_FRAGMENT 16
|
|
||||||
#define MASK_AH 8
|
|
||||||
#define MASK_ESP 4
|
|
||||||
#define MASK_NONE 2
|
|
||||||
#define MASK_PROTO 1
|
|
||||||
|
|
||||||
#endif /*_IP6T_OPTS_H*/
|
#endif /*_IP6T_OPTS_H*/
|
||||||
|
@ -30,13 +30,4 @@ struct ip6t_rt
|
|||||||
#define IP6T_RT_INV_LEN 0x04 /* Invert the sense of length. */
|
#define IP6T_RT_INV_LEN 0x04 /* Invert the sense of length. */
|
||||||
#define IP6T_RT_INV_MASK 0x07 /* All possible flags. */
|
#define IP6T_RT_INV_MASK 0x07 /* All possible flags. */
|
||||||
|
|
||||||
#define MASK_HOPOPTS 128
|
|
||||||
#define MASK_DSTOPTS 64
|
|
||||||
#define MASK_ROUTING 32
|
|
||||||
#define MASK_FRAGMENT 16
|
|
||||||
#define MASK_AH 8
|
|
||||||
#define MASK_ESP 4
|
|
||||||
#define MASK_NONE 2
|
|
||||||
#define MASK_PROTO 1
|
|
||||||
|
|
||||||
#endif /*_IP6T_RT_H*/
|
#endif /*_IP6T_RT_H*/
|
||||||
|
@ -926,7 +926,7 @@ static inline int skb_tailroom(const struct sk_buff *skb)
|
|||||||
* Increase the headroom of an empty &sk_buff by reducing the tail
|
* Increase the headroom of an empty &sk_buff by reducing the tail
|
||||||
* room. This is only allowed for an empty buffer.
|
* room. This is only allowed for an empty buffer.
|
||||||
*/
|
*/
|
||||||
static inline void skb_reserve(struct sk_buff *skb, unsigned int len)
|
static inline void skb_reserve(struct sk_buff *skb, int len)
|
||||||
{
|
{
|
||||||
skb->data += len;
|
skb->data += len;
|
||||||
skb->tail += len;
|
skb->tail += len;
|
||||||
|
@ -92,7 +92,9 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask,
|
|||||||
if (info->invflags & EBT_IP_PROTO)
|
if (info->invflags & EBT_IP_PROTO)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (info->protocol != IPPROTO_TCP &&
|
if (info->protocol != IPPROTO_TCP &&
|
||||||
info->protocol != IPPROTO_UDP)
|
info->protocol != IPPROTO_UDP &&
|
||||||
|
info->protocol != IPPROTO_SCTP &&
|
||||||
|
info->protocol != IPPROTO_DCCP)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
|
if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
|
||||||
|
@ -95,7 +95,9 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
|
|||||||
"tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
|
"tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
|
||||||
NIPQUAD(ih->daddr), ih->tos, ih->protocol);
|
NIPQUAD(ih->daddr), ih->tos, ih->protocol);
|
||||||
if (ih->protocol == IPPROTO_TCP ||
|
if (ih->protocol == IPPROTO_TCP ||
|
||||||
ih->protocol == IPPROTO_UDP) {
|
ih->protocol == IPPROTO_UDP ||
|
||||||
|
ih->protocol == IPPROTO_SCTP ||
|
||||||
|
ih->protocol == IPPROTO_DCCP) {
|
||||||
struct tcpudphdr _ports, *pptr;
|
struct tcpudphdr _ports, *pptr;
|
||||||
|
|
||||||
pptr = skb_header_pointer(skb, ih->ihl*4,
|
pptr = skb_header_pointer(skb, ih->ihl*4,
|
||||||
|
@ -74,7 +74,6 @@ static inline void *load_pointer(struct sk_buff *skb, int k,
|
|||||||
* filtering, filter is the array of filter instructions, and
|
* filtering, filter is the array of filter instructions, and
|
||||||
* len is the number of filter blocks in the array.
|
* len is the number of filter blocks in the array.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
|
unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
|
||||||
{
|
{
|
||||||
struct sock_filter *fentry; /* We walk down these */
|
struct sock_filter *fentry; /* We walk down these */
|
||||||
@ -175,7 +174,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
|
|||||||
continue;
|
continue;
|
||||||
case BPF_LD|BPF_W|BPF_ABS:
|
case BPF_LD|BPF_W|BPF_ABS:
|
||||||
k = fentry->k;
|
k = fentry->k;
|
||||||
load_w:
|
load_w:
|
||||||
ptr = load_pointer(skb, k, 4, &tmp);
|
ptr = load_pointer(skb, k, 4, &tmp);
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
A = ntohl(*(u32 *)ptr);
|
A = ntohl(*(u32 *)ptr);
|
||||||
@ -184,7 +183,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
|
|||||||
break;
|
break;
|
||||||
case BPF_LD|BPF_H|BPF_ABS:
|
case BPF_LD|BPF_H|BPF_ABS:
|
||||||
k = fentry->k;
|
k = fentry->k;
|
||||||
load_h:
|
load_h:
|
||||||
ptr = load_pointer(skb, k, 2, &tmp);
|
ptr = load_pointer(skb, k, 2, &tmp);
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
A = ntohs(*(u16 *)ptr);
|
A = ntohs(*(u16 *)ptr);
|
||||||
@ -374,7 +373,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
|
|||||||
case BPF_JMP|BPF_JSET|BPF_K:
|
case BPF_JMP|BPF_JSET|BPF_K:
|
||||||
case BPF_JMP|BPF_JSET|BPF_X:
|
case BPF_JMP|BPF_JSET|BPF_X:
|
||||||
/* for conditionals both must be safe */
|
/* for conditionals both must be safe */
|
||||||
if (pc + ftest->jt + 1 >= flen ||
|
if (pc + ftest->jt + 1 >= flen ||
|
||||||
pc + ftest->jf + 1 >= flen)
|
pc + ftest->jf + 1 >= flen)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
@ -384,7 +383,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL;
|
return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -404,8 +403,8 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Make sure new filter is there and in the right amounts. */
|
/* Make sure new filter is there and in the right amounts. */
|
||||||
if (fprog->filter == NULL)
|
if (fprog->filter == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
|
fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
|
||||||
if (!fp)
|
if (!fp)
|
||||||
|
@ -703,7 +703,7 @@ int netpoll_setup(struct netpoll *np)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memcmp(np->local_mac, "\0\0\0\0\0\0", 6) && ndev->dev_addr)
|
if (is_zero_ether_addr(np->local_mac) && ndev->dev_addr)
|
||||||
memcpy(np->local_mac, ndev->dev_addr, 6);
|
memcpy(np->local_mac, ndev->dev_addr, 6);
|
||||||
|
|
||||||
if (!np->local_ip) {
|
if (!np->local_ip) {
|
||||||
|
@ -139,6 +139,7 @@
|
|||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
#include <net/checksum.h>
|
#include <net/checksum.h>
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
#include <net/addrconf.h>
|
#include <net/addrconf.h>
|
||||||
@ -281,8 +282,8 @@ struct pktgen_dev {
|
|||||||
__u32 src_mac_count; /* How many MACs to iterate through */
|
__u32 src_mac_count; /* How many MACs to iterate through */
|
||||||
__u32 dst_mac_count; /* How many MACs to iterate through */
|
__u32 dst_mac_count; /* How many MACs to iterate through */
|
||||||
|
|
||||||
unsigned char dst_mac[6];
|
unsigned char dst_mac[ETH_ALEN];
|
||||||
unsigned char src_mac[6];
|
unsigned char src_mac[ETH_ALEN];
|
||||||
|
|
||||||
__u32 cur_dst_mac_offset;
|
__u32 cur_dst_mac_offset;
|
||||||
__u32 cur_src_mac_offset;
|
__u32 cur_src_mac_offset;
|
||||||
@ -594,16 +595,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
|
|||||||
|
|
||||||
seq_puts(seq, " src_mac: ");
|
seq_puts(seq, " src_mac: ");
|
||||||
|
|
||||||
if ((pkt_dev->src_mac[0] == 0) &&
|
if (is_zero_ether_addr(pkt_dev->src_mac))
|
||||||
(pkt_dev->src_mac[1] == 0) &&
|
|
||||||
(pkt_dev->src_mac[2] == 0) &&
|
|
||||||
(pkt_dev->src_mac[3] == 0) &&
|
|
||||||
(pkt_dev->src_mac[4] == 0) &&
|
|
||||||
(pkt_dev->src_mac[5] == 0))
|
|
||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
|
seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
|
||||||
|
|
||||||
else
|
else
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
|
seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
|
||||||
@ -1189,9 +1183,9 @@ static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer
|
|||||||
}
|
}
|
||||||
if (!strcmp(name, "dst_mac")) {
|
if (!strcmp(name, "dst_mac")) {
|
||||||
char *v = valstr;
|
char *v = valstr;
|
||||||
unsigned char old_dmac[6];
|
unsigned char old_dmac[ETH_ALEN];
|
||||||
unsigned char *m = pkt_dev->dst_mac;
|
unsigned char *m = pkt_dev->dst_mac;
|
||||||
memcpy(old_dmac, pkt_dev->dst_mac, 6);
|
memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
|
||||||
|
|
||||||
len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
|
len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
|
||||||
if (len < 0) { return len; }
|
if (len < 0) { return len; }
|
||||||
@ -1220,8 +1214,8 @@ static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set up Dest MAC */
|
/* Set up Dest MAC */
|
||||||
if (memcmp(old_dmac, pkt_dev->dst_mac, 6) != 0)
|
if (compare_ether_addr(old_dmac, pkt_dev->dst_mac))
|
||||||
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
|
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
|
||||||
|
|
||||||
sprintf(pg_result, "OK: dstmac");
|
sprintf(pg_result, "OK: dstmac");
|
||||||
return count;
|
return count;
|
||||||
@ -1560,17 +1554,11 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
|
|||||||
|
|
||||||
/* Default to the interface's mac if not explicitly set. */
|
/* Default to the interface's mac if not explicitly set. */
|
||||||
|
|
||||||
if ((pkt_dev->src_mac[0] == 0) &&
|
if (is_zero_ether_addr(pkt_dev->src_mac))
|
||||||
(pkt_dev->src_mac[1] == 0) &&
|
memcpy(&(pkt_dev->hh[6]), pkt_dev->odev->dev_addr, ETH_ALEN);
|
||||||
(pkt_dev->src_mac[2] == 0) &&
|
|
||||||
(pkt_dev->src_mac[3] == 0) &&
|
|
||||||
(pkt_dev->src_mac[4] == 0) &&
|
|
||||||
(pkt_dev->src_mac[5] == 0)) {
|
|
||||||
|
|
||||||
memcpy(&(pkt_dev->hh[6]), pkt_dev->odev->dev_addr, 6);
|
|
||||||
}
|
|
||||||
/* Set up Dest MAC */
|
/* Set up Dest MAC */
|
||||||
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
|
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
|
||||||
|
|
||||||
/* Set up pkt size */
|
/* Set up pkt size */
|
||||||
pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
|
pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
|
||||||
|
@ -144,7 +144,7 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
|
|||||||
const unsigned char state)
|
const unsigned char state)
|
||||||
{
|
{
|
||||||
unsigned int gap;
|
unsigned int gap;
|
||||||
signed long new_head;
|
long new_head;
|
||||||
|
|
||||||
if (av->dccpav_vec_len + packets > av->dccpav_buf_len)
|
if (av->dccpav_vec_len + packets > av->dccpav_buf_len)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
@ -46,7 +46,6 @@ obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
|
|||||||
obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
|
obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
|
||||||
|
|
||||||
# matches
|
# matches
|
||||||
obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
|
|
||||||
obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
|
obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
|
||||||
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
|
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
|
||||||
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
|
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
static DEFINE_RWLOCK(ip_ct_gre_lock);
|
static DEFINE_RWLOCK(ip_ct_gre_lock);
|
||||||
#define ASSERT_READ_LOCK(x)
|
#define ASSERT_READ_LOCK(x)
|
||||||
|
@ -95,7 +95,10 @@ match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
|
|||||||
static int match(const struct sk_buff *skb,
|
static int match(const struct sk_buff *skb,
|
||||||
const struct net_device *in,
|
const struct net_device *in,
|
||||||
const struct net_device *out,
|
const struct net_device *out,
|
||||||
const void *matchinfo, int offset, int *hotdrop)
|
const void *matchinfo,
|
||||||
|
int offset,
|
||||||
|
unsigned int protoff,
|
||||||
|
int *hotdrop)
|
||||||
{
|
{
|
||||||
const struct ipt_policy_info *info = matchinfo;
|
const struct ipt_policy_info *info = matchinfo;
|
||||||
int ret;
|
int ret;
|
||||||
@ -113,7 +116,7 @@ static int match(const struct sk_buff *skb,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int checkentry(const char *tablename, const struct ipt_ip *ip,
|
static int checkentry(const char *tablename, const void *ip_void,
|
||||||
void *matchinfo, unsigned int matchsize,
|
void *matchinfo, unsigned int matchsize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
|
@ -240,9 +240,8 @@ static unsigned rt_hash_mask;
|
|||||||
static int rt_hash_log;
|
static int rt_hash_log;
|
||||||
static unsigned int rt_hash_rnd;
|
static unsigned int rt_hash_rnd;
|
||||||
|
|
||||||
static struct rt_cache_stat *rt_cache_stat;
|
static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
|
||||||
#define RT_CACHE_STAT_INC(field) \
|
#define RT_CACHE_STAT_INC(field) (__get_cpu_var(rt_cache_stat).field++)
|
||||||
(per_cpu_ptr(rt_cache_stat, raw_smp_processor_id())->field++)
|
|
||||||
|
|
||||||
static int rt_intern_hash(unsigned hash, struct rtable *rth,
|
static int rt_intern_hash(unsigned hash, struct rtable *rth,
|
||||||
struct rtable **res);
|
struct rtable **res);
|
||||||
@ -401,7 +400,7 @@ static void *rt_cpu_seq_start(struct seq_file *seq, loff_t *pos)
|
|||||||
if (!cpu_possible(cpu))
|
if (!cpu_possible(cpu))
|
||||||
continue;
|
continue;
|
||||||
*pos = cpu+1;
|
*pos = cpu+1;
|
||||||
return per_cpu_ptr(rt_cache_stat, cpu);
|
return &per_cpu(rt_cache_stat, cpu);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -414,7 +413,7 @@ static void *rt_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|||||||
if (!cpu_possible(cpu))
|
if (!cpu_possible(cpu))
|
||||||
continue;
|
continue;
|
||||||
*pos = cpu+1;
|
*pos = cpu+1;
|
||||||
return per_cpu_ptr(rt_cache_stat, cpu);
|
return &per_cpu(rt_cache_stat, cpu);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -3160,10 +3159,6 @@ int __init ip_rt_init(void)
|
|||||||
ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
|
ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
|
||||||
ip_rt_max_size = (rt_hash_mask + 1) * 16;
|
ip_rt_max_size = (rt_hash_mask + 1) * 16;
|
||||||
|
|
||||||
rt_cache_stat = alloc_percpu(struct rt_cache_stat);
|
|
||||||
if (!rt_cache_stat)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
devinet_init();
|
devinet_init();
|
||||||
ip_fib_init();
|
ip_fib_init();
|
||||||
|
|
||||||
@ -3191,7 +3186,6 @@ int __init ip_rt_init(void)
|
|||||||
if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
|
if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
|
||||||
!(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
|
!(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
|
||||||
proc_net_stat))) {
|
proc_net_stat))) {
|
||||||
free_percpu(rt_cache_stat);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
rtstat_pde->proc_fops = &rt_cpu_seq_fops;
|
rtstat_pde->proc_fops = &rt_cpu_seq_fops;
|
||||||
|
@ -2644,7 +2644,7 @@ static int if6_seq_show(struct seq_file *seq, void *v)
|
|||||||
{
|
{
|
||||||
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
|
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
NIP6_FMT " %02x %02x %02x %02x %8s\n",
|
NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
|
||||||
NIP6(ifp->addr),
|
NIP6(ifp->addr),
|
||||||
ifp->idev->dev->ifindex,
|
ifp->idev->dev->ifindex,
|
||||||
ifp->prefix_len,
|
ifp->prefix_len,
|
||||||
|
@ -532,7 +532,7 @@ static int ac6_seq_show(struct seq_file *seq, void *v)
|
|||||||
struct ac6_iter_state *state = ac6_seq_private(seq);
|
struct ac6_iter_state *state = ac6_seq_private(seq);
|
||||||
|
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"%-4d %-15s " NIP6_FMT " %5d\n",
|
"%-4d %-15s " NIP6_SEQFMT " %5d\n",
|
||||||
state->dev->ifindex, state->dev->name,
|
state->dev->ifindex, state->dev->name,
|
||||||
NIP6(im->aca_addr),
|
NIP6(im->aca_addr),
|
||||||
im->aca_users);
|
im->aca_users);
|
||||||
|
@ -629,7 +629,7 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl)
|
|||||||
{
|
{
|
||||||
while(fl) {
|
while(fl) {
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_FMT " %-4d\n",
|
"%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n",
|
||||||
(unsigned)ntohl(fl->label),
|
(unsigned)ntohl(fl->label),
|
||||||
fl->share,
|
fl->share,
|
||||||
(unsigned)fl->owner,
|
(unsigned)fl->owner,
|
||||||
@ -645,7 +645,7 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl)
|
|||||||
static int ip6fl_seq_show(struct seq_file *seq, void *v)
|
static int ip6fl_seq_show(struct seq_file *seq, void *v)
|
||||||
{
|
{
|
||||||
if (v == SEQ_START_TOKEN)
|
if (v == SEQ_START_TOKEN)
|
||||||
seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-39s %s\n",
|
seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
|
||||||
"Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
|
"Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
|
||||||
else
|
else
|
||||||
ip6fl_fl_seq_show(seq, v);
|
ip6fl_fl_seq_show(seq, v);
|
||||||
|
@ -2373,7 +2373,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
|
|||||||
struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
|
struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
|
||||||
|
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"%-4d %-15s " NIP6_FMT " %5d %08X %ld\n",
|
"%-4d %-15s " NIP6_SEQFMT " %5d %08X %ld\n",
|
||||||
state->dev->ifindex, state->dev->name,
|
state->dev->ifindex, state->dev->name,
|
||||||
NIP6(im->mca_addr),
|
NIP6(im->mca_addr),
|
||||||
im->mca_users, im->mca_flags,
|
im->mca_users, im->mca_flags,
|
||||||
@ -2542,12 +2542,12 @@ static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
|
|||||||
if (v == SEQ_START_TOKEN) {
|
if (v == SEQ_START_TOKEN) {
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"%3s %6s "
|
"%3s %6s "
|
||||||
"%39s %39s %6s %6s\n", "Idx",
|
"%32s %32s %6s %6s\n", "Idx",
|
||||||
"Device", "Multicast Address",
|
"Device", "Multicast Address",
|
||||||
"Source Address", "INC", "EXC");
|
"Source Address", "INC", "EXC");
|
||||||
} else {
|
} else {
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"%3d %6.6s " NIP6_FMT " " NIP6_FMT " %6lu %6lu\n",
|
"%3d %6.6s " NIP6_SEQFMT " " NIP6_SEQFMT " %6lu %6lu\n",
|
||||||
state->dev->ifindex, state->dev->name,
|
state->dev->ifindex, state->dev->name,
|
||||||
NIP6(state->im->mca_addr),
|
NIP6(state->im->mca_addr),
|
||||||
NIP6(psf->sf_addr),
|
NIP6(psf->sf_addr),
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
# Link order matters here.
|
# Link order matters here.
|
||||||
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
|
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
|
||||||
obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
|
|
||||||
obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
|
obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
|
||||||
obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
|
obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
|
||||||
obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
|
obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
|
||||||
|
@ -36,19 +36,19 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (Type & 0xC0) >> 6
|
* (Type & 0xC0) >> 6
|
||||||
* 0 -> ignorable
|
* 0 -> ignorable
|
||||||
* 1 -> must drop the packet
|
* 1 -> must drop the packet
|
||||||
* 2 -> send ICMP PARM PROB regardless and drop packet
|
* 2 -> send ICMP PARM PROB regardless and drop packet
|
||||||
* 3 -> Send ICMP if not a multicast address and drop packet
|
* 3 -> Send ICMP if not a multicast address and drop packet
|
||||||
* (Type & 0x20) >> 5
|
* (Type & 0x20) >> 5
|
||||||
* 0 -> invariant
|
* 0 -> invariant
|
||||||
* 1 -> can change the routing
|
* 1 -> can change the routing
|
||||||
* (Type & 0x1F) Type
|
* (Type & 0x1F) Type
|
||||||
* 0 -> Pad1 (only 1 byte!)
|
* 0 -> Pad1 (only 1 byte!)
|
||||||
* 1 -> PadN LENGTH info (total length = length + 2)
|
* 1 -> PadN LENGTH info (total length = length + 2)
|
||||||
* C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
|
* C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
|
||||||
* 5 -> RTALERT 2 x x
|
* 5 -> RTALERT 2 x x
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -60,16 +60,16 @@ match(const struct sk_buff *skb,
|
|||||||
unsigned int protoff,
|
unsigned int protoff,
|
||||||
int *hotdrop)
|
int *hotdrop)
|
||||||
{
|
{
|
||||||
struct ipv6_opt_hdr _optsh, *oh;
|
struct ipv6_opt_hdr _optsh, *oh;
|
||||||
const struct ip6t_opts *optinfo = matchinfo;
|
const struct ip6t_opts *optinfo = matchinfo;
|
||||||
unsigned int temp;
|
unsigned int temp;
|
||||||
unsigned int ptr;
|
unsigned int ptr;
|
||||||
unsigned int hdrlen = 0;
|
unsigned int hdrlen = 0;
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
u8 _opttype, *tp = NULL;
|
u8 _opttype, *tp = NULL;
|
||||||
u8 _optlen, *lp = NULL;
|
u8 _optlen, *lp = NULL;
|
||||||
unsigned int optlen;
|
unsigned int optlen;
|
||||||
|
|
||||||
#if HOPBYHOP
|
#if HOPBYHOP
|
||||||
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
|
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
|
||||||
#else
|
#else
|
||||||
@ -77,42 +77,41 @@ match(const struct sk_buff *skb,
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
|
oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
|
||||||
if (oh == NULL){
|
if (oh == NULL) {
|
||||||
*hotdrop = 1;
|
*hotdrop = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdrlen = ipv6_optlen(oh);
|
hdrlen = ipv6_optlen(oh);
|
||||||
if (skb->len - ptr < hdrlen){
|
if (skb->len - ptr < hdrlen) {
|
||||||
/* Packet smaller than it's length field */
|
/* Packet smaller than it's length field */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
|
DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
|
||||||
|
|
||||||
DEBUGP("len %02X %04X %02X ",
|
DEBUGP("len %02X %04X %02X ",
|
||||||
optinfo->hdrlen, hdrlen,
|
optinfo->hdrlen, hdrlen,
|
||||||
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
||||||
((optinfo->hdrlen == hdrlen) ^
|
((optinfo->hdrlen == hdrlen) ^
|
||||||
!!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
|
!!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
|
||||||
|
|
||||||
ret = (oh != NULL)
|
ret = (oh != NULL) &&
|
||||||
&&
|
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
||||||
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
((optinfo->hdrlen == hdrlen) ^
|
||||||
((optinfo->hdrlen == hdrlen) ^
|
!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
|
||||||
!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
|
|
||||||
|
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
hdrlen -= 2;
|
hdrlen -= 2;
|
||||||
if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
|
if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
|
||||||
return ret;
|
return ret;
|
||||||
} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
|
} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
|
||||||
DEBUGP("Not strict - not implemented");
|
DEBUGP("Not strict - not implemented");
|
||||||
} else {
|
} else {
|
||||||
DEBUGP("Strict ");
|
DEBUGP("Strict ");
|
||||||
DEBUGP("#%d ",optinfo->optsnr);
|
DEBUGP("#%d ", optinfo->optsnr);
|
||||||
for(temp=0; temp<optinfo->optsnr; temp++){
|
for (temp = 0; temp < optinfo->optsnr; temp++) {
|
||||||
/* type field exists ? */
|
/* type field exists ? */
|
||||||
if (hdrlen < 1)
|
if (hdrlen < 1)
|
||||||
break;
|
break;
|
||||||
@ -122,10 +121,10 @@ match(const struct sk_buff *skb,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Type check */
|
/* Type check */
|
||||||
if (*tp != (optinfo->opts[temp] & 0xFF00)>>8){
|
if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
|
||||||
DEBUGP("Tbad %02X %02X\n",
|
DEBUGP("Tbad %02X %02X\n",
|
||||||
*tp,
|
*tp,
|
||||||
(optinfo->opts[temp] & 0xFF00)>>8);
|
(optinfo->opts[temp] & 0xFF00) >> 8);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
DEBUGP("Tok ");
|
DEBUGP("Tok ");
|
||||||
@ -169,7 +168,8 @@ match(const struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
if (temp == optinfo->optsnr)
|
if (temp == optinfo->optsnr)
|
||||||
return ret;
|
return ret;
|
||||||
else return 0;
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -178,25 +178,24 @@ match(const struct sk_buff *skb,
|
|||||||
/* Called when user tries to insert an entry of this type. */
|
/* Called when user tries to insert an entry of this type. */
|
||||||
static int
|
static int
|
||||||
checkentry(const char *tablename,
|
checkentry(const char *tablename,
|
||||||
const void *info,
|
const void *info,
|
||||||
void *matchinfo,
|
void *matchinfo,
|
||||||
unsigned int matchinfosize,
|
unsigned int matchinfosize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
const struct ip6t_opts *optsinfo = matchinfo;
|
const struct ip6t_opts *optsinfo = matchinfo;
|
||||||
|
|
||||||
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
|
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
|
||||||
DEBUGP("ip6t_opts: matchsize %u != %u\n",
|
DEBUGP("ip6t_opts: matchsize %u != %u\n",
|
||||||
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
|
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
|
if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
|
||||||
DEBUGP("ip6t_opts: unknown flags %X\n",
|
DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
|
||||||
optsinfo->invflags);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ip6t_match opts_match = {
|
static struct ip6t_match opts_match = {
|
||||||
@ -212,12 +211,12 @@ static struct ip6t_match opts_match = {
|
|||||||
|
|
||||||
static int __init init(void)
|
static int __init init(void)
|
||||||
{
|
{
|
||||||
return ip6t_register_match(&opts_match);
|
return ip6t_register_match(&opts_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit cleanup(void)
|
static void __exit cleanup(void)
|
||||||
{
|
{
|
||||||
ip6t_unregister_match(&opts_match);
|
ip6t_unregister_match(&opts_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(init);
|
module_init(init);
|
||||||
|
@ -27,45 +27,45 @@ match(const struct sk_buff *skb,
|
|||||||
unsigned int protoff,
|
unsigned int protoff,
|
||||||
int *hotdrop)
|
int *hotdrop)
|
||||||
{
|
{
|
||||||
|
unsigned char eui64[8];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
unsigned char eui64[8];
|
if (!(skb->mac.raw >= skb->head &&
|
||||||
int i=0;
|
(skb->mac.raw + ETH_HLEN) <= skb->data) &&
|
||||||
|
offset != 0) {
|
||||||
|
*hotdrop = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !(skb->mac.raw >= skb->head
|
memset(eui64, 0, sizeof(eui64));
|
||||||
&& (skb->mac.raw + ETH_HLEN) <= skb->data)
|
|
||||||
&& offset != 0) {
|
|
||||||
*hotdrop = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(eui64, 0, sizeof(eui64));
|
|
||||||
|
|
||||||
if (eth_hdr(skb)->h_proto == ntohs(ETH_P_IPV6)) {
|
if (eth_hdr(skb)->h_proto == ntohs(ETH_P_IPV6)) {
|
||||||
if (skb->nh.ipv6h->version == 0x6) {
|
if (skb->nh.ipv6h->version == 0x6) {
|
||||||
memcpy(eui64, eth_hdr(skb)->h_source, 3);
|
memcpy(eui64, eth_hdr(skb)->h_source, 3);
|
||||||
memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3);
|
memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3);
|
||||||
eui64[3]=0xff;
|
eui64[3] = 0xff;
|
||||||
eui64[4]=0xfe;
|
eui64[4] = 0xfe;
|
||||||
eui64[0] |= 0x02;
|
eui64[0] |= 0x02;
|
||||||
|
|
||||||
i=0;
|
i = 0;
|
||||||
while ((skb->nh.ipv6h->saddr.s6_addr[8+i] ==
|
while ((skb->nh.ipv6h->saddr.s6_addr[8+i] == eui64[i])
|
||||||
eui64[i]) && (i<8)) i++;
|
&& (i < 8))
|
||||||
|
i++;
|
||||||
|
|
||||||
if ( i == 8 )
|
if (i == 8)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ip6t_eui64_checkentry(const char *tablename,
|
ip6t_eui64_checkentry(const char *tablename,
|
||||||
const void *ip,
|
const void *ip,
|
||||||
void *matchinfo,
|
void *matchinfo,
|
||||||
unsigned int matchsize,
|
unsigned int matchsize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
if (hook_mask
|
if (hook_mask
|
||||||
& ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
|
& ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
|
||||||
|
@ -31,12 +31,12 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
|
|||||||
static inline int
|
static inline int
|
||||||
id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
|
id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
|
||||||
{
|
{
|
||||||
int r=0;
|
int r = 0;
|
||||||
DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
|
DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
|
||||||
min,id,max);
|
min, id, max);
|
||||||
r=(id >= min && id <= max) ^ invert;
|
r = (id >= min && id <= max) ^ invert;
|
||||||
DEBUGP(" result %s\n",r? "PASS" : "FAILED");
|
DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -48,92 +48,91 @@ match(const struct sk_buff *skb,
|
|||||||
unsigned int protoff,
|
unsigned int protoff,
|
||||||
int *hotdrop)
|
int *hotdrop)
|
||||||
{
|
{
|
||||||
struct frag_hdr _frag, *fh;
|
struct frag_hdr _frag, *fh;
|
||||||
const struct ip6t_frag *fraginfo = matchinfo;
|
const struct ip6t_frag *fraginfo = matchinfo;
|
||||||
unsigned int ptr;
|
unsigned int ptr;
|
||||||
|
|
||||||
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
|
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
|
fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
|
||||||
if (fh == NULL){
|
if (fh == NULL) {
|
||||||
*hotdrop = 1;
|
*hotdrop = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGP("INFO %04X ", fh->frag_off);
|
DEBUGP("INFO %04X ", fh->frag_off);
|
||||||
DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
|
DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
|
||||||
DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
|
DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
|
||||||
DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF));
|
DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF));
|
||||||
DEBUGP("ID %u %08X\n", ntohl(fh->identification),
|
DEBUGP("ID %u %08X\n", ntohl(fh->identification),
|
||||||
ntohl(fh->identification));
|
ntohl(fh->identification));
|
||||||
|
|
||||||
DEBUGP("IPv6 FRAG id %02X ",
|
DEBUGP("IPv6 FRAG id %02X ",
|
||||||
(id_match(fraginfo->ids[0], fraginfo->ids[1],
|
(id_match(fraginfo->ids[0], fraginfo->ids[1],
|
||||||
ntohl(fh->identification),
|
ntohl(fh->identification),
|
||||||
!!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
|
!!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
|
||||||
DEBUGP("res %02X %02X%04X %02X ",
|
DEBUGP("res %02X %02X%04X %02X ",
|
||||||
(fraginfo->flags & IP6T_FRAG_RES), fh->reserved,
|
(fraginfo->flags & IP6T_FRAG_RES), fh->reserved,
|
||||||
ntohs(fh->frag_off) & 0x6,
|
ntohs(fh->frag_off) & 0x6,
|
||||||
!((fraginfo->flags & IP6T_FRAG_RES)
|
!((fraginfo->flags & IP6T_FRAG_RES)
|
||||||
&& (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
|
&& (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
|
||||||
DEBUGP("first %02X %02X %02X ",
|
DEBUGP("first %02X %02X %02X ",
|
||||||
(fraginfo->flags & IP6T_FRAG_FST),
|
(fraginfo->flags & IP6T_FRAG_FST),
|
||||||
ntohs(fh->frag_off) & ~0x7,
|
ntohs(fh->frag_off) & ~0x7,
|
||||||
!((fraginfo->flags & IP6T_FRAG_FST)
|
!((fraginfo->flags & IP6T_FRAG_FST)
|
||||||
&& (ntohs(fh->frag_off) & ~0x7)));
|
&& (ntohs(fh->frag_off) & ~0x7)));
|
||||||
DEBUGP("mf %02X %02X %02X ",
|
DEBUGP("mf %02X %02X %02X ",
|
||||||
(fraginfo->flags & IP6T_FRAG_MF),
|
(fraginfo->flags & IP6T_FRAG_MF),
|
||||||
ntohs(fh->frag_off) & IP6_MF,
|
ntohs(fh->frag_off) & IP6_MF,
|
||||||
!((fraginfo->flags & IP6T_FRAG_MF)
|
!((fraginfo->flags & IP6T_FRAG_MF)
|
||||||
&& !((ntohs(fh->frag_off) & IP6_MF))));
|
&& !((ntohs(fh->frag_off) & IP6_MF))));
|
||||||
DEBUGP("last %02X %02X %02X\n",
|
DEBUGP("last %02X %02X %02X\n",
|
||||||
(fraginfo->flags & IP6T_FRAG_NMF),
|
(fraginfo->flags & IP6T_FRAG_NMF),
|
||||||
ntohs(fh->frag_off) & IP6_MF,
|
ntohs(fh->frag_off) & IP6_MF,
|
||||||
!((fraginfo->flags & IP6T_FRAG_NMF)
|
!((fraginfo->flags & IP6T_FRAG_NMF)
|
||||||
&& (ntohs(fh->frag_off) & IP6_MF)));
|
&& (ntohs(fh->frag_off) & IP6_MF)));
|
||||||
|
|
||||||
return (fh != NULL)
|
return (fh != NULL)
|
||||||
&&
|
&&
|
||||||
(id_match(fraginfo->ids[0], fraginfo->ids[1],
|
(id_match(fraginfo->ids[0], fraginfo->ids[1],
|
||||||
ntohl(fh->identification),
|
ntohl(fh->identification),
|
||||||
!!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
|
!!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
|
||||||
&&
|
&&
|
||||||
!((fraginfo->flags & IP6T_FRAG_RES)
|
!((fraginfo->flags & IP6T_FRAG_RES)
|
||||||
&& (fh->reserved || (ntohs(fh->frag_off) & 0x6)))
|
&& (fh->reserved || (ntohs(fh->frag_off) & 0x6)))
|
||||||
&&
|
&&
|
||||||
!((fraginfo->flags & IP6T_FRAG_FST)
|
!((fraginfo->flags & IP6T_FRAG_FST)
|
||||||
&& (ntohs(fh->frag_off) & ~0x7))
|
&& (ntohs(fh->frag_off) & ~0x7))
|
||||||
&&
|
&&
|
||||||
!((fraginfo->flags & IP6T_FRAG_MF)
|
!((fraginfo->flags & IP6T_FRAG_MF)
|
||||||
&& !(ntohs(fh->frag_off) & IP6_MF))
|
&& !(ntohs(fh->frag_off) & IP6_MF))
|
||||||
&&
|
&&
|
||||||
!((fraginfo->flags & IP6T_FRAG_NMF)
|
!((fraginfo->flags & IP6T_FRAG_NMF)
|
||||||
&& (ntohs(fh->frag_off) & IP6_MF));
|
&& (ntohs(fh->frag_off) & IP6_MF));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when user tries to insert an entry of this type. */
|
/* Called when user tries to insert an entry of this type. */
|
||||||
static int
|
static int
|
||||||
checkentry(const char *tablename,
|
checkentry(const char *tablename,
|
||||||
const void *ip,
|
const void *ip,
|
||||||
void *matchinfo,
|
void *matchinfo,
|
||||||
unsigned int matchinfosize,
|
unsigned int matchinfosize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
const struct ip6t_frag *fraginfo = matchinfo;
|
const struct ip6t_frag *fraginfo = matchinfo;
|
||||||
|
|
||||||
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_frag))) {
|
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_frag))) {
|
||||||
DEBUGP("ip6t_frag: matchsize %u != %u\n",
|
DEBUGP("ip6t_frag: matchsize %u != %u\n",
|
||||||
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_frag)));
|
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_frag)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
|
if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
|
||||||
DEBUGP("ip6t_frag: unknown flags %X\n",
|
DEBUGP("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
|
||||||
fraginfo->invflags);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ip6t_match frag_match = {
|
static struct ip6t_match frag_match = {
|
||||||
@ -145,12 +144,12 @@ static struct ip6t_match frag_match = {
|
|||||||
|
|
||||||
static int __init init(void)
|
static int __init init(void)
|
||||||
{
|
{
|
||||||
return ip6t_register_match(&frag_match);
|
return ip6t_register_match(&frag_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit cleanup(void)
|
static void __exit cleanup(void)
|
||||||
{
|
{
|
||||||
ip6t_unregister_match(&frag_match);
|
ip6t_unregister_match(&frag_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(init);
|
module_init(init);
|
||||||
|
@ -36,19 +36,19 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (Type & 0xC0) >> 6
|
* (Type & 0xC0) >> 6
|
||||||
* 0 -> ignorable
|
* 0 -> ignorable
|
||||||
* 1 -> must drop the packet
|
* 1 -> must drop the packet
|
||||||
* 2 -> send ICMP PARM PROB regardless and drop packet
|
* 2 -> send ICMP PARM PROB regardless and drop packet
|
||||||
* 3 -> Send ICMP if not a multicast address and drop packet
|
* 3 -> Send ICMP if not a multicast address and drop packet
|
||||||
* (Type & 0x20) >> 5
|
* (Type & 0x20) >> 5
|
||||||
* 0 -> invariant
|
* 0 -> invariant
|
||||||
* 1 -> can change the routing
|
* 1 -> can change the routing
|
||||||
* (Type & 0x1F) Type
|
* (Type & 0x1F) Type
|
||||||
* 0 -> Pad1 (only 1 byte!)
|
* 0 -> Pad1 (only 1 byte!)
|
||||||
* 1 -> PadN LENGTH info (total length = length + 2)
|
* 1 -> PadN LENGTH info (total length = length + 2)
|
||||||
* C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
|
* C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
|
||||||
* 5 -> RTALERT 2 x x
|
* 5 -> RTALERT 2 x x
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -60,16 +60,16 @@ match(const struct sk_buff *skb,
|
|||||||
unsigned int protoff,
|
unsigned int protoff,
|
||||||
int *hotdrop)
|
int *hotdrop)
|
||||||
{
|
{
|
||||||
struct ipv6_opt_hdr _optsh, *oh;
|
struct ipv6_opt_hdr _optsh, *oh;
|
||||||
const struct ip6t_opts *optinfo = matchinfo;
|
const struct ip6t_opts *optinfo = matchinfo;
|
||||||
unsigned int temp;
|
unsigned int temp;
|
||||||
unsigned int ptr;
|
unsigned int ptr;
|
||||||
unsigned int hdrlen = 0;
|
unsigned int hdrlen = 0;
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
u8 _opttype, *tp = NULL;
|
u8 _opttype, *tp = NULL;
|
||||||
u8 _optlen, *lp = NULL;
|
u8 _optlen, *lp = NULL;
|
||||||
unsigned int optlen;
|
unsigned int optlen;
|
||||||
|
|
||||||
#if HOPBYHOP
|
#if HOPBYHOP
|
||||||
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
|
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
|
||||||
#else
|
#else
|
||||||
@ -77,42 +77,41 @@ match(const struct sk_buff *skb,
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
|
oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
|
||||||
if (oh == NULL){
|
if (oh == NULL) {
|
||||||
*hotdrop = 1;
|
*hotdrop = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdrlen = ipv6_optlen(oh);
|
hdrlen = ipv6_optlen(oh);
|
||||||
if (skb->len - ptr < hdrlen){
|
if (skb->len - ptr < hdrlen) {
|
||||||
/* Packet smaller than it's length field */
|
/* Packet smaller than it's length field */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
|
DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
|
||||||
|
|
||||||
DEBUGP("len %02X %04X %02X ",
|
DEBUGP("len %02X %04X %02X ",
|
||||||
optinfo->hdrlen, hdrlen,
|
optinfo->hdrlen, hdrlen,
|
||||||
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
||||||
((optinfo->hdrlen == hdrlen) ^
|
((optinfo->hdrlen == hdrlen) ^
|
||||||
!!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
|
!!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
|
||||||
|
|
||||||
ret = (oh != NULL)
|
ret = (oh != NULL) &&
|
||||||
&&
|
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
||||||
(!(optinfo->flags & IP6T_OPTS_LEN) ||
|
((optinfo->hdrlen == hdrlen) ^
|
||||||
((optinfo->hdrlen == hdrlen) ^
|
!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
|
||||||
!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
|
|
||||||
|
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
hdrlen -= 2;
|
hdrlen -= 2;
|
||||||
if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
|
if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
|
||||||
return ret;
|
return ret;
|
||||||
} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
|
} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
|
||||||
DEBUGP("Not strict - not implemented");
|
DEBUGP("Not strict - not implemented");
|
||||||
} else {
|
} else {
|
||||||
DEBUGP("Strict ");
|
DEBUGP("Strict ");
|
||||||
DEBUGP("#%d ",optinfo->optsnr);
|
DEBUGP("#%d ", optinfo->optsnr);
|
||||||
for(temp=0; temp<optinfo->optsnr; temp++){
|
for (temp = 0; temp < optinfo->optsnr; temp++) {
|
||||||
/* type field exists ? */
|
/* type field exists ? */
|
||||||
if (hdrlen < 1)
|
if (hdrlen < 1)
|
||||||
break;
|
break;
|
||||||
@ -122,10 +121,10 @@ match(const struct sk_buff *skb,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Type check */
|
/* Type check */
|
||||||
if (*tp != (optinfo->opts[temp] & 0xFF00)>>8){
|
if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
|
||||||
DEBUGP("Tbad %02X %02X\n",
|
DEBUGP("Tbad %02X %02X\n",
|
||||||
*tp,
|
*tp,
|
||||||
(optinfo->opts[temp] & 0xFF00)>>8);
|
(optinfo->opts[temp] & 0xFF00) >> 8);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
DEBUGP("Tok ");
|
DEBUGP("Tok ");
|
||||||
@ -169,7 +168,8 @@ match(const struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
if (temp == optinfo->optsnr)
|
if (temp == optinfo->optsnr)
|
||||||
return ret;
|
return ret;
|
||||||
else return 0;
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -178,25 +178,24 @@ match(const struct sk_buff *skb,
|
|||||||
/* Called when user tries to insert an entry of this type. */
|
/* Called when user tries to insert an entry of this type. */
|
||||||
static int
|
static int
|
||||||
checkentry(const char *tablename,
|
checkentry(const char *tablename,
|
||||||
const void *entry,
|
const void *entry,
|
||||||
void *matchinfo,
|
void *matchinfo,
|
||||||
unsigned int matchinfosize,
|
unsigned int matchinfosize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
const struct ip6t_opts *optsinfo = matchinfo;
|
const struct ip6t_opts *optsinfo = matchinfo;
|
||||||
|
|
||||||
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
|
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
|
||||||
DEBUGP("ip6t_opts: matchsize %u != %u\n",
|
DEBUGP("ip6t_opts: matchsize %u != %u\n",
|
||||||
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
|
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
|
if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
|
||||||
DEBUGP("ip6t_opts: unknown flags %X\n",
|
DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
|
||||||
optsinfo->invflags);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ip6t_match opts_match = {
|
static struct ip6t_match opts_match = {
|
||||||
@ -212,12 +211,12 @@ static struct ip6t_match opts_match = {
|
|||||||
|
|
||||||
static int __init init(void)
|
static int __init init(void)
|
||||||
{
|
{
|
||||||
return ip6t_register_match(&opts_match);
|
return ip6t_register_match(&opts_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit cleanup(void)
|
static void __exit cleanup(void)
|
||||||
{
|
{
|
||||||
ip6t_unregister_match(&opts_match);
|
ip6t_unregister_match(&opts_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(init);
|
module_init(init);
|
||||||
|
@ -50,20 +50,20 @@ ipv6header_match(const struct sk_buff *skb,
|
|||||||
len = skb->len - ptr;
|
len = skb->len - ptr;
|
||||||
temp = 0;
|
temp = 0;
|
||||||
|
|
||||||
while (ip6t_ext_hdr(nexthdr)) {
|
while (ip6t_ext_hdr(nexthdr)) {
|
||||||
struct ipv6_opt_hdr _hdr, *hp;
|
struct ipv6_opt_hdr _hdr, *hp;
|
||||||
int hdrlen;
|
int hdrlen;
|
||||||
|
|
||||||
/* Is there enough space for the next ext header? */
|
/* Is there enough space for the next ext header? */
|
||||||
if (len < (int)sizeof(struct ipv6_opt_hdr))
|
if (len < (int)sizeof(struct ipv6_opt_hdr))
|
||||||
return 0;
|
return 0;
|
||||||
/* No more exthdr -> evaluate */
|
/* No more exthdr -> evaluate */
|
||||||
if (nexthdr == NEXTHDR_NONE) {
|
if (nexthdr == NEXTHDR_NONE) {
|
||||||
temp |= MASK_NONE;
|
temp |= MASK_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* ESP -> evaluate */
|
/* ESP -> evaluate */
|
||||||
if (nexthdr == NEXTHDR_ESP) {
|
if (nexthdr == NEXTHDR_ESP) {
|
||||||
temp |= MASK_ESP;
|
temp |= MASK_ESP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -72,43 +72,43 @@ ipv6header_match(const struct sk_buff *skb,
|
|||||||
BUG_ON(hp == NULL);
|
BUG_ON(hp == NULL);
|
||||||
|
|
||||||
/* Calculate the header length */
|
/* Calculate the header length */
|
||||||
if (nexthdr == NEXTHDR_FRAGMENT) {
|
if (nexthdr == NEXTHDR_FRAGMENT) {
|
||||||
hdrlen = 8;
|
hdrlen = 8;
|
||||||
} else if (nexthdr == NEXTHDR_AUTH)
|
} else if (nexthdr == NEXTHDR_AUTH)
|
||||||
hdrlen = (hp->hdrlen+2)<<2;
|
hdrlen = (hp->hdrlen + 2) << 2;
|
||||||
else
|
else
|
||||||
hdrlen = ipv6_optlen(hp);
|
hdrlen = ipv6_optlen(hp);
|
||||||
|
|
||||||
/* set the flag */
|
/* set the flag */
|
||||||
switch (nexthdr){
|
switch (nexthdr) {
|
||||||
case NEXTHDR_HOP:
|
case NEXTHDR_HOP:
|
||||||
temp |= MASK_HOPOPTS;
|
temp |= MASK_HOPOPTS;
|
||||||
break;
|
break;
|
||||||
case NEXTHDR_ROUTING:
|
case NEXTHDR_ROUTING:
|
||||||
temp |= MASK_ROUTING;
|
temp |= MASK_ROUTING;
|
||||||
break;
|
break;
|
||||||
case NEXTHDR_FRAGMENT:
|
case NEXTHDR_FRAGMENT:
|
||||||
temp |= MASK_FRAGMENT;
|
temp |= MASK_FRAGMENT;
|
||||||
break;
|
break;
|
||||||
case NEXTHDR_AUTH:
|
case NEXTHDR_AUTH:
|
||||||
temp |= MASK_AH;
|
temp |= MASK_AH;
|
||||||
break;
|
break;
|
||||||
case NEXTHDR_DEST:
|
case NEXTHDR_DEST:
|
||||||
temp |= MASK_DSTOPTS;
|
temp |= MASK_DSTOPTS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nexthdr = hp->nexthdr;
|
nexthdr = hp->nexthdr;
|
||||||
len -= hdrlen;
|
len -= hdrlen;
|
||||||
ptr += hdrlen;
|
ptr += hdrlen;
|
||||||
if (ptr > skb->len)
|
if (ptr > skb->len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (nexthdr != NEXTHDR_NONE ) && (nexthdr != NEXTHDR_ESP) )
|
if ((nexthdr != NEXTHDR_NONE) && (nexthdr != NEXTHDR_ESP))
|
||||||
temp |= MASK_PROTO;
|
temp |= MASK_PROTO;
|
||||||
|
|
||||||
if (info->modeflag)
|
if (info->modeflag)
|
||||||
@ -137,8 +137,8 @@ ipv6header_checkentry(const char *tablename,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* invflags is 0 or 0xff in hard mode */
|
/* invflags is 0 or 0xff in hard mode */
|
||||||
if ((!info->modeflag) && info->invflags != 0x00
|
if ((!info->modeflag) && info->invflags != 0x00 &&
|
||||||
&& info->invflags != 0xFF)
|
info->invflags != 0xFF)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -152,7 +152,7 @@ static struct ip6t_match ip6t_ipv6header_match = {
|
|||||||
.me = THIS_MODULE,
|
.me = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ipv6header_init(void)
|
static int __init ipv6header_init(void)
|
||||||
{
|
{
|
||||||
return ip6t_register_match(&ip6t_ipv6header_match);
|
return ip6t_register_match(&ip6t_ipv6header_match);
|
||||||
}
|
}
|
||||||
@ -164,4 +164,3 @@ static void __exit ipv6header_exit(void)
|
|||||||
|
|
||||||
module_init(ipv6header_init);
|
module_init(ipv6header_init);
|
||||||
module_exit(ipv6header_exit);
|
module_exit(ipv6header_exit);
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@ match(const struct sk_buff *skb,
|
|||||||
if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
|
if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(info->match & IP6T_OWNER_UID) {
|
if (info->match & IP6T_OWNER_UID) {
|
||||||
if((skb->sk->sk_socket->file->f_uid != info->uid) ^
|
if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
|
||||||
!!(info->invert & IP6T_OWNER_UID))
|
!!(info->invert & IP6T_OWNER_UID))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info->match & IP6T_OWNER_GID) {
|
if (info->match & IP6T_OWNER_GID) {
|
||||||
if((skb->sk->sk_socket->file->f_gid != info->gid) ^
|
if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
|
||||||
!!(info->invert & IP6T_OWNER_GID))
|
!!(info->invert & IP6T_OWNER_GID))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -53,23 +53,23 @@ match(const struct sk_buff *skb,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
checkentry(const char *tablename,
|
checkentry(const char *tablename,
|
||||||
const void *ip,
|
const void *ip,
|
||||||
void *matchinfo,
|
void *matchinfo,
|
||||||
unsigned int matchsize,
|
unsigned int matchsize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
const struct ip6t_owner_info *info = matchinfo;
|
const struct ip6t_owner_info *info = matchinfo;
|
||||||
|
|
||||||
if (hook_mask
|
if (hook_mask
|
||||||
& ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) {
|
& ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) {
|
||||||
printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
|
printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info)))
|
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (info->match & (IP6T_OWNER_PID|IP6T_OWNER_SID)) {
|
if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
|
||||||
printk("ipt_owner: pid and sid matching "
|
printk("ipt_owner: pid and sid matching "
|
||||||
"not supported anymore\n");
|
"not supported anymore\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -118,7 +118,7 @@ static int match(const struct sk_buff *skb,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
|
static int checkentry(const char *tablename, const void *ip_void,
|
||||||
void *matchinfo, unsigned int matchsize,
|
void *matchinfo, unsigned int matchsize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
|
@ -33,12 +33,12 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
|
|||||||
static inline int
|
static inline int
|
||||||
segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
|
segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
|
||||||
{
|
{
|
||||||
int r=0;
|
int r = 0;
|
||||||
DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
|
DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
|
||||||
min,id,max);
|
invert ? '!' : ' ', min, id, max);
|
||||||
r=(id >= min && id <= max) ^ invert;
|
r = (id >= min && id <= max) ^ invert;
|
||||||
DEBUGP(" result %s\n",r? "PASS" : "FAILED");
|
DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -50,87 +50,93 @@ match(const struct sk_buff *skb,
|
|||||||
unsigned int protoff,
|
unsigned int protoff,
|
||||||
int *hotdrop)
|
int *hotdrop)
|
||||||
{
|
{
|
||||||
struct ipv6_rt_hdr _route, *rh;
|
struct ipv6_rt_hdr _route, *rh;
|
||||||
const struct ip6t_rt *rtinfo = matchinfo;
|
const struct ip6t_rt *rtinfo = matchinfo;
|
||||||
unsigned int temp;
|
unsigned int temp;
|
||||||
unsigned int ptr;
|
unsigned int ptr;
|
||||||
unsigned int hdrlen = 0;
|
unsigned int hdrlen = 0;
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
struct in6_addr *ap, _addr;
|
struct in6_addr *ap, _addr;
|
||||||
|
|
||||||
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
|
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
|
rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
|
||||||
if (rh == NULL){
|
if (rh == NULL) {
|
||||||
*hotdrop = 1;
|
*hotdrop = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdrlen = ipv6_optlen(rh);
|
hdrlen = ipv6_optlen(rh);
|
||||||
if (skb->len - ptr < hdrlen){
|
if (skb->len - ptr < hdrlen) {
|
||||||
/* Pcket smaller than its length field */
|
/* Pcket smaller than its length field */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
|
DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
|
||||||
DEBUGP("TYPE %04X ", rh->type);
|
DEBUGP("TYPE %04X ", rh->type);
|
||||||
DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
|
DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
|
||||||
|
|
||||||
DEBUGP("IPv6 RT segsleft %02X ",
|
DEBUGP("IPv6 RT segsleft %02X ",
|
||||||
(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
|
(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
|
||||||
rh->segments_left,
|
rh->segments_left,
|
||||||
!!(rtinfo->invflags & IP6T_RT_INV_SGS))));
|
!!(rtinfo->invflags & IP6T_RT_INV_SGS))));
|
||||||
DEBUGP("type %02X %02X %02X ",
|
DEBUGP("type %02X %02X %02X ",
|
||||||
rtinfo->rt_type, rh->type,
|
rtinfo->rt_type, rh->type,
|
||||||
(!(rtinfo->flags & IP6T_RT_TYP) ||
|
(!(rtinfo->flags & IP6T_RT_TYP) ||
|
||||||
((rtinfo->rt_type == rh->type) ^
|
((rtinfo->rt_type == rh->type) ^
|
||||||
!!(rtinfo->invflags & IP6T_RT_INV_TYP))));
|
!!(rtinfo->invflags & IP6T_RT_INV_TYP))));
|
||||||
DEBUGP("len %02X %04X %02X ",
|
DEBUGP("len %02X %04X %02X ",
|
||||||
rtinfo->hdrlen, hdrlen,
|
rtinfo->hdrlen, hdrlen,
|
||||||
(!(rtinfo->flags & IP6T_RT_LEN) ||
|
(!(rtinfo->flags & IP6T_RT_LEN) ||
|
||||||
((rtinfo->hdrlen == hdrlen) ^
|
((rtinfo->hdrlen == hdrlen) ^
|
||||||
!!(rtinfo->invflags & IP6T_RT_INV_LEN))));
|
!!(rtinfo->invflags & IP6T_RT_INV_LEN))));
|
||||||
DEBUGP("res %02X %02X %02X ",
|
DEBUGP("res %02X %02X %02X ",
|
||||||
(rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)rh)->reserved,
|
(rtinfo->flags & IP6T_RT_RES),
|
||||||
!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)rh)->reserved)));
|
((struct rt0_hdr *)rh)->reserved,
|
||||||
|
!((rtinfo->flags & IP6T_RT_RES) &&
|
||||||
|
(((struct rt0_hdr *)rh)->reserved)));
|
||||||
|
|
||||||
ret = (rh != NULL)
|
ret = (rh != NULL)
|
||||||
&&
|
&&
|
||||||
(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
|
(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
|
||||||
rh->segments_left,
|
rh->segments_left,
|
||||||
!!(rtinfo->invflags & IP6T_RT_INV_SGS)))
|
!!(rtinfo->invflags & IP6T_RT_INV_SGS)))
|
||||||
&&
|
&&
|
||||||
(!(rtinfo->flags & IP6T_RT_LEN) ||
|
(!(rtinfo->flags & IP6T_RT_LEN) ||
|
||||||
((rtinfo->hdrlen == hdrlen) ^
|
((rtinfo->hdrlen == hdrlen) ^
|
||||||
!!(rtinfo->invflags & IP6T_RT_INV_LEN)))
|
!!(rtinfo->invflags & IP6T_RT_INV_LEN)))
|
||||||
&&
|
&&
|
||||||
(!(rtinfo->flags & IP6T_RT_TYP) ||
|
(!(rtinfo->flags & IP6T_RT_TYP) ||
|
||||||
((rtinfo->rt_type == rh->type) ^
|
((rtinfo->rt_type == rh->type) ^
|
||||||
!!(rtinfo->invflags & IP6T_RT_INV_TYP)));
|
!!(rtinfo->invflags & IP6T_RT_INV_TYP)));
|
||||||
|
|
||||||
if (ret && (rtinfo->flags & IP6T_RT_RES)) {
|
if (ret && (rtinfo->flags & IP6T_RT_RES)) {
|
||||||
u_int32_t *rp, _reserved;
|
u_int32_t *rp, _reserved;
|
||||||
rp = skb_header_pointer(skb,
|
rp = skb_header_pointer(skb,
|
||||||
ptr + offsetof(struct rt0_hdr, reserved),
|
ptr + offsetof(struct rt0_hdr,
|
||||||
sizeof(_reserved), &_reserved);
|
reserved),
|
||||||
|
sizeof(_reserved),
|
||||||
|
&_reserved);
|
||||||
|
|
||||||
ret = (*rp == 0);
|
ret = (*rp == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGP("#%d ",rtinfo->addrnr);
|
DEBUGP("#%d ", rtinfo->addrnr);
|
||||||
if ( !(rtinfo->flags & IP6T_RT_FST) ){
|
if (!(rtinfo->flags & IP6T_RT_FST)) {
|
||||||
return ret;
|
return ret;
|
||||||
} else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) {
|
} else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) {
|
||||||
DEBUGP("Not strict ");
|
DEBUGP("Not strict ");
|
||||||
if ( rtinfo->addrnr > (unsigned int)((hdrlen-8)/16) ){
|
if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
|
||||||
DEBUGP("There isn't enough space\n");
|
DEBUGP("There isn't enough space\n");
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
DEBUGP("#%d ",rtinfo->addrnr);
|
DEBUGP("#%d ", rtinfo->addrnr);
|
||||||
for(temp=0; temp<(unsigned int)((hdrlen-8)/16); temp++){
|
for (temp = 0;
|
||||||
|
temp < (unsigned int)((hdrlen - 8) / 16);
|
||||||
|
temp++) {
|
||||||
ap = skb_header_pointer(skb,
|
ap = skb_header_pointer(skb,
|
||||||
ptr
|
ptr
|
||||||
+ sizeof(struct rt0_hdr)
|
+ sizeof(struct rt0_hdr)
|
||||||
@ -141,24 +147,26 @@ match(const struct sk_buff *skb,
|
|||||||
BUG_ON(ap == NULL);
|
BUG_ON(ap == NULL);
|
||||||
|
|
||||||
if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
|
if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
|
||||||
DEBUGP("i=%d temp=%d;\n",i,temp);
|
DEBUGP("i=%d temp=%d;\n", i, temp);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i==rtinfo->addrnr) break;
|
if (i == rtinfo->addrnr)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
DEBUGP("i=%d #%d\n", i, rtinfo->addrnr);
|
DEBUGP("i=%d #%d\n", i, rtinfo->addrnr);
|
||||||
if (i == rtinfo->addrnr)
|
if (i == rtinfo->addrnr)
|
||||||
return ret;
|
return ret;
|
||||||
else return 0;
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUGP("Strict ");
|
DEBUGP("Strict ");
|
||||||
if ( rtinfo->addrnr > (unsigned int)((hdrlen-8)/16) ){
|
if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
|
||||||
DEBUGP("There isn't enough space\n");
|
DEBUGP("There isn't enough space\n");
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
DEBUGP("#%d ",rtinfo->addrnr);
|
DEBUGP("#%d ", rtinfo->addrnr);
|
||||||
for(temp=0; temp<rtinfo->addrnr; temp++){
|
for (temp = 0; temp < rtinfo->addrnr; temp++) {
|
||||||
ap = skb_header_pointer(skb,
|
ap = skb_header_pointer(skb,
|
||||||
ptr
|
ptr
|
||||||
+ sizeof(struct rt0_hdr)
|
+ sizeof(struct rt0_hdr)
|
||||||
@ -171,9 +179,11 @@ match(const struct sk_buff *skb,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DEBUGP("temp=%d #%d\n", temp, rtinfo->addrnr);
|
DEBUGP("temp=%d #%d\n", temp, rtinfo->addrnr);
|
||||||
if ((temp == rtinfo->addrnr) && (temp == (unsigned int)((hdrlen-8)/16)))
|
if ((temp == rtinfo->addrnr) &&
|
||||||
|
(temp == (unsigned int)((hdrlen - 8) / 16)))
|
||||||
return ret;
|
return ret;
|
||||||
else return 0;
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,32 +193,31 @@ match(const struct sk_buff *skb,
|
|||||||
/* Called when user tries to insert an entry of this type. */
|
/* Called when user tries to insert an entry of this type. */
|
||||||
static int
|
static int
|
||||||
checkentry(const char *tablename,
|
checkentry(const char *tablename,
|
||||||
const void *entry,
|
const void *entry,
|
||||||
void *matchinfo,
|
void *matchinfo,
|
||||||
unsigned int matchinfosize,
|
unsigned int matchinfosize,
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
const struct ip6t_rt *rtinfo = matchinfo;
|
const struct ip6t_rt *rtinfo = matchinfo;
|
||||||
|
|
||||||
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_rt))) {
|
if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_rt))) {
|
||||||
DEBUGP("ip6t_rt: matchsize %u != %u\n",
|
DEBUGP("ip6t_rt: matchsize %u != %u\n",
|
||||||
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_rt)));
|
matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_rt)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
|
if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
|
||||||
DEBUGP("ip6t_rt: unknown flags %X\n",
|
DEBUGP("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
|
||||||
rtinfo->invflags);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
|
||||||
if ( (rtinfo->flags & (IP6T_RT_RES|IP6T_RT_FST_MASK)) &&
|
(!(rtinfo->flags & IP6T_RT_TYP) ||
|
||||||
(!(rtinfo->flags & IP6T_RT_TYP) ||
|
(rtinfo->rt_type != 0) ||
|
||||||
(rtinfo->rt_type != 0) ||
|
(rtinfo->invflags & IP6T_RT_INV_TYP))) {
|
||||||
(rtinfo->invflags & IP6T_RT_INV_TYP)) ) {
|
DEBUGP("`--rt-type 0' required before `--rt-0-*'");
|
||||||
DEBUGP("`--rt-type 0' required before `--rt-0-*'");
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ip6t_match rt_match = {
|
static struct ip6t_match rt_match = {
|
||||||
@ -220,12 +229,12 @@ static struct ip6t_match rt_match = {
|
|||||||
|
|
||||||
static int __init init(void)
|
static int __init init(void)
|
||||||
{
|
{
|
||||||
return ip6t_register_match(&rt_match);
|
return ip6t_register_match(&rt_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit cleanup(void)
|
static void __exit cleanup(void)
|
||||||
{
|
{
|
||||||
ip6t_unregister_match(&rt_match);
|
ip6t_unregister_match(&rt_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(init);
|
module_init(init);
|
||||||
|
@ -81,7 +81,7 @@ static int krxtimod(void *arg)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
unsigned long jif;
|
unsigned long jif;
|
||||||
signed long timeout;
|
long timeout;
|
||||||
|
|
||||||
/* deal with the server being asked to die */
|
/* deal with the server being asked to die */
|
||||||
if (krxtimod_die) {
|
if (krxtimod_die) {
|
||||||
|
@ -361,7 +361,7 @@ static void rxrpc_proc_peers_stop(struct seq_file *p, void *v)
|
|||||||
static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
|
static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link);
|
struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link);
|
||||||
signed long timeout;
|
long timeout;
|
||||||
|
|
||||||
/* display header on line 1 */
|
/* display header on line 1 */
|
||||||
if (v == SEQ_START_TOKEN) {
|
if (v == SEQ_START_TOKEN) {
|
||||||
@ -373,8 +373,8 @@ static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
|
|||||||
/* display one peer per line on subsequent lines */
|
/* display one peer per line on subsequent lines */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
if (!list_empty(&peer->timeout.link))
|
if (!list_empty(&peer->timeout.link))
|
||||||
timeout = (signed long) peer->timeout.timo_jif -
|
timeout = (long) peer->timeout.timo_jif -
|
||||||
(signed long) jiffies;
|
(long) jiffies;
|
||||||
|
|
||||||
seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
|
seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
|
||||||
peer->trans->port,
|
peer->trans->port,
|
||||||
@ -468,7 +468,7 @@ static void rxrpc_proc_conns_stop(struct seq_file *p, void *v)
|
|||||||
static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
|
static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
struct rxrpc_connection *conn;
|
struct rxrpc_connection *conn;
|
||||||
signed long timeout;
|
long timeout;
|
||||||
|
|
||||||
conn = list_entry(v, struct rxrpc_connection, proc_link);
|
conn = list_entry(v, struct rxrpc_connection, proc_link);
|
||||||
|
|
||||||
@ -484,8 +484,8 @@ static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
|
|||||||
/* display one conn per line on subsequent lines */
|
/* display one conn per line on subsequent lines */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
if (!list_empty(&conn->timeout.link))
|
if (!list_empty(&conn->timeout.link))
|
||||||
timeout = (signed long) conn->timeout.timo_jif -
|
timeout = (long) conn->timeout.timo_jif -
|
||||||
(signed long) jiffies;
|
(long) jiffies;
|
||||||
|
|
||||||
seq_printf(m,
|
seq_printf(m,
|
||||||
"%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
|
"%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
|
||||||
|
@ -228,14 +228,13 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
|
|||||||
}
|
}
|
||||||
sch_tree_unlock(sch);
|
sch_tree_unlock(sch);
|
||||||
|
|
||||||
for (i=0; i<=TC_PRIO_MAX; i++) {
|
for (i=0; i<q->bands; i++) {
|
||||||
int band = q->prio2band[i];
|
if (q->queues[i] == &noop_qdisc) {
|
||||||
if (q->queues[band] == &noop_qdisc) {
|
|
||||||
struct Qdisc *child;
|
struct Qdisc *child;
|
||||||
child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
||||||
if (child) {
|
if (child) {
|
||||||
sch_tree_lock(sch);
|
sch_tree_lock(sch);
|
||||||
child = xchg(&q->queues[band], child);
|
child = xchg(&q->queues[i], child);
|
||||||
|
|
||||||
if (child != &noop_qdisc)
|
if (child != &noop_qdisc)
|
||||||
qdisc_destroy(child);
|
qdisc_destroy(child);
|
||||||
|
@ -144,6 +144,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
|
|||||||
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
|
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
|
||||||
(iph->protocol == IPPROTO_TCP ||
|
(iph->protocol == IPPROTO_TCP ||
|
||||||
iph->protocol == IPPROTO_UDP ||
|
iph->protocol == IPPROTO_UDP ||
|
||||||
|
iph->protocol == IPPROTO_SCTP ||
|
||||||
|
iph->protocol == IPPROTO_DCCP ||
|
||||||
iph->protocol == IPPROTO_ESP))
|
iph->protocol == IPPROTO_ESP))
|
||||||
h2 ^= *(((u32*)iph) + iph->ihl);
|
h2 ^= *(((u32*)iph) + iph->ihl);
|
||||||
break;
|
break;
|
||||||
@ -155,6 +157,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
|
|||||||
h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
|
h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
|
||||||
if (iph->nexthdr == IPPROTO_TCP ||
|
if (iph->nexthdr == IPPROTO_TCP ||
|
||||||
iph->nexthdr == IPPROTO_UDP ||
|
iph->nexthdr == IPPROTO_UDP ||
|
||||||
|
iph->nexthdr == IPPROTO_SCTP ||
|
||||||
|
iph->nexthdr == IPPROTO_DCCP ||
|
||||||
iph->nexthdr == IPPROTO_ESP)
|
iph->nexthdr == IPPROTO_ESP)
|
||||||
h2 ^= *(u32*)&iph[1];
|
h2 ^= *(u32*)&iph[1];
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user