Commit dfc97803 authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5

into kernel.bkbits.net:/home/davem/net-2.5
parents 5edf8b9a 60c6580a
...@@ -501,6 +501,15 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -501,6 +501,15 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
real_dev->ifindex); real_dev->ifindex);
#endif #endif
if (register_netdevice(new_dev))
goto out_free_newdev_priv;
/* NOTE: We have a reference to the real device,
* so hold on to the reference. May fail if we are being removed
*/
if (!try_module_get(THIS_MODULE))
goto out_free_unregister;
/* So, got the sucker initialized, now lets place /* So, got the sucker initialized, now lets place
* it into our local structure. * it into our local structure.
*/ */
...@@ -514,7 +523,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -514,7 +523,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
if (!grp) { /* need to add a new group */ if (!grp) { /* need to add a new group */
grp = kmalloc(sizeof(struct vlan_group), GFP_KERNEL); grp = kmalloc(sizeof(struct vlan_group), GFP_KERNEL);
if (!grp) if (!grp)
goto out_free_newdev_priv; goto out_free_put;
/* printk(KERN_ALERT "VLAN REGISTER: Allocated new group.\n"); */ /* printk(KERN_ALERT "VLAN REGISTER: Allocated new group.\n"); */
memset(grp, 0, sizeof(struct vlan_group)); memset(grp, 0, sizeof(struct vlan_group));
...@@ -535,24 +544,18 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -535,24 +544,18 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
if (real_dev->features & NETIF_F_HW_VLAN_FILTER) if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
real_dev->vlan_rx_add_vid(real_dev, VLAN_ID); real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);
register_netdevice(new_dev);
rtnl_unlock(); rtnl_unlock();
/* NOTE: We have a reference to the real device,
* so hold on to the reference.
*/
if (!try_module_get(THIS_MODULE))
goto out_module_dying;
#ifdef VLAN_DEBUG #ifdef VLAN_DEBUG
printk(VLAN_DBG "Allocated new device successfully, returning.\n"); printk(VLAN_DBG "Allocated new device successfully, returning.\n");
#endif #endif
return new_dev; return new_dev;
out_free_put:
module_put(THIS_MODULE);
out_module_dying: out_free_unregister:
rtnl_lock(); unregister_netdev(new_dev);
unregister_netdevice(new_dev);
out_free_newdev_priv: out_free_newdev_priv:
kfree(new_dev->priv); kfree(new_dev->priv);
......
...@@ -33,6 +33,7 @@ static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb) ...@@ -33,6 +33,7 @@ static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb)
int br_dev_queue_push_xmit(struct sk_buff *skb) int br_dev_queue_push_xmit(struct sk_buff *skb)
{ {
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
/* FIXME: skb bas not been linearized: is this valid?? --RR */
if (skb->nf_bridge) if (skb->nf_bridge)
memcpy(skb->data - 16, skb->nf_bridge->hh, 16); memcpy(skb->data - 16, skb->nf_bridge->hh, 16);
#endif #endif
......
...@@ -467,6 +467,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, ...@@ -467,6 +467,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
struct sk_buff *skb = *pskb; struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge; struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge;
/* FIXME: skb as not been linearized. Is this still true? --RR */
/* Be very paranoid. */ /* Be very paranoid. */
if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) {
printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: "
......
...@@ -175,6 +175,10 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb, ...@@ -175,6 +175,10 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
char *base; char *base;
struct ebt_table_info *private = table->private; struct ebt_table_info *private = table->private;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
read_lock_bh(&table->lock); read_lock_bh(&table->lock);
cb_base = COUNTER_BASE(private->counters, private->nentries, cb_base = COUNTER_BASE(private->counters, private->nentries,
smp_processor_id()); smp_processor_id());
......
...@@ -477,11 +477,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, ...@@ -477,11 +477,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
unsigned int verdict; unsigned int verdict;
int ret = 0; int ret = 0;
/* This stopgap cannot be removed until all the hooks are audited. */
if (skb_is_nonlinear(skb) && skb_linearize(skb, GFP_ATOMIC) != 0) {
kfree_skb(skb);
return -ENOMEM;
}
if (skb->ip_summed == CHECKSUM_HW) { if (skb->ip_summed == CHECKSUM_HW) {
if (outdev == NULL) { if (outdev == NULL) {
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
......
...@@ -262,12 +262,10 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -262,12 +262,10 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
if (!create) if (!create)
return NULL; return NULL;
MOD_INC_USE_COUNT;
dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL); dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL);
if (dev == NULL) { if (dev == NULL)
MOD_DEC_USE_COUNT;
return NULL; return NULL;
}
memset(dev, 0, sizeof(*dev) + sizeof(*t)); memset(dev, 0, sizeof(*dev) + sizeof(*t));
dev->priv = (void*)(dev+1); dev->priv = (void*)(dev+1);
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
...@@ -287,6 +285,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -287,6 +285,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
goto failed; goto failed;
memcpy(nt->parms.name, dev->name, IFNAMSIZ); memcpy(nt->parms.name, dev->name, IFNAMSIZ);
} }
SET_MODULE_OWNER(dev);
if (register_netdevice(dev) < 0) if (register_netdevice(dev) < 0)
goto failed; goto failed;
...@@ -297,16 +296,13 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -297,16 +296,13 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
failed: failed:
kfree(dev); kfree(dev);
MOD_DEC_USE_COUNT;
return NULL; return NULL;
} }
static void ipgre_tunnel_destructor(struct net_device *dev) static void ipgre_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipgre_fb_tunnel_dev) { if (dev != &ipgre_fb_tunnel_dev)
kfree(dev); kfree(dev);
MOD_DEC_USE_COUNT;
}
} }
static void ipgre_tunnel_uninit(struct net_device *dev) static void ipgre_tunnel_uninit(struct net_device *dev)
...@@ -920,8 +916,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -920,8 +916,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
struct ip_tunnel_parm p; struct ip_tunnel_parm p;
struct ip_tunnel *t; struct ip_tunnel *t;
MOD_INC_USE_COUNT;
switch (cmd) { switch (cmd) {
case SIOCGETTUNNEL: case SIOCGETTUNNEL:
t = NULL; t = NULL;
...@@ -1035,7 +1029,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1035,7 +1029,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
} }
done: done:
MOD_DEC_USE_COUNT;
return err; return err;
} }
...@@ -1115,7 +1108,6 @@ static int ipgre_open(struct net_device *dev) ...@@ -1115,7 +1108,6 @@ static int ipgre_open(struct net_device *dev)
{ {
struct ip_tunnel *t = (struct ip_tunnel*)dev->priv; struct ip_tunnel *t = (struct ip_tunnel*)dev->priv;
MOD_INC_USE_COUNT;
if (MULTICAST(t->parms.iph.daddr)) { if (MULTICAST(t->parms.iph.daddr)) {
struct flowi fl = { .oif = t->parms.link, struct flowi fl = { .oif = t->parms.link,
.nl_u = { .ip4_u = .nl_u = { .ip4_u =
...@@ -1124,16 +1116,12 @@ static int ipgre_open(struct net_device *dev) ...@@ -1124,16 +1116,12 @@ static int ipgre_open(struct net_device *dev)
.tos = RT_TOS(t->parms.iph.tos) } }, .tos = RT_TOS(t->parms.iph.tos) } },
.proto = IPPROTO_GRE }; .proto = IPPROTO_GRE };
struct rtable *rt; struct rtable *rt;
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl))
MOD_DEC_USE_COUNT;
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
}
dev = rt->u.dst.dev; dev = rt->u.dst.dev;
ip_rt_put(rt); ip_rt_put(rt);
if (__in_dev_get(dev) == NULL) { if (__in_dev_get(dev) == NULL)
MOD_DEC_USE_COUNT;
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
}
t->mlink = dev->ifindex; t->mlink = dev->ifindex;
ip_mc_inc_group(__in_dev_get(dev), t->parms.iph.daddr); ip_mc_inc_group(__in_dev_get(dev), t->parms.iph.daddr);
} }
...@@ -1150,7 +1138,6 @@ static int ipgre_close(struct net_device *dev) ...@@ -1150,7 +1138,6 @@ static int ipgre_close(struct net_device *dev)
in_dev_put(in_dev); in_dev_put(in_dev);
} }
} }
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -1244,30 +1231,12 @@ static int ipgre_tunnel_init(struct net_device *dev) ...@@ -1244,30 +1231,12 @@ static int ipgre_tunnel_init(struct net_device *dev)
return 0; return 0;
} }
#ifdef MODULE
static int ipgre_fb_tunnel_open(struct net_device *dev)
{
MOD_INC_USE_COUNT;
return 0;
}
static int ipgre_fb_tunnel_close(struct net_device *dev)
{
MOD_DEC_USE_COUNT;
return 0;
}
#endif
int __init ipgre_fb_tunnel_init(struct net_device *dev) int __init ipgre_fb_tunnel_init(struct net_device *dev)
{ {
struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
struct iphdr *iph; struct iphdr *iph;
ipgre_tunnel_init_gen(dev); ipgre_tunnel_init_gen(dev);
#ifdef MODULE
dev->open = ipgre_fb_tunnel_open;
dev->stop = ipgre_fb_tunnel_close;
#endif
iph = &ipgre_fb_tunnel.parms.iph; iph = &ipgre_fb_tunnel.parms.iph;
iph->version = 4; iph->version = 4;
...@@ -1291,11 +1260,7 @@ static struct inet_protocol ipgre_protocol = { ...@@ -1291,11 +1260,7 @@ static struct inet_protocol ipgre_protocol = {
* And now the modules code and kernel interface. * And now the modules code and kernel interface.
*/ */
#ifdef MODULE
int init_module(void)
#else
int __init ipgre_init(void) int __init ipgre_init(void)
#endif
{ {
printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); printk(KERN_INFO "GRE over IPv4 tunneling driver\n");
...@@ -1305,13 +1270,12 @@ int __init ipgre_init(void) ...@@ -1305,13 +1270,12 @@ int __init ipgre_init(void)
} }
ipgre_fb_tunnel_dev.priv = (void*)&ipgre_fb_tunnel; ipgre_fb_tunnel_dev.priv = (void*)&ipgre_fb_tunnel;
SET_MODULE_OWNER(&ipgre_fb_tunnel_dev);
register_netdev(&ipgre_fb_tunnel_dev); register_netdev(&ipgre_fb_tunnel_dev);
return 0; return 0;
} }
#ifdef MODULE void ipgre_fini(void)
void cleanup_module(void)
{ {
if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
printk(KERN_INFO "ipgre close: can't remove protocol\n"); printk(KERN_INFO "ipgre close: can't remove protocol\n");
...@@ -1319,5 +1283,8 @@ void cleanup_module(void) ...@@ -1319,5 +1283,8 @@ void cleanup_module(void)
unregister_netdev(&ipgre_fb_tunnel_dev); unregister_netdev(&ipgre_fb_tunnel_dev);
} }
#ifdef MODULE
module_init(ipgre_init);
#endif #endif
module_exit(ipgre_fini);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -231,12 +231,10 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -231,12 +231,10 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
if (!create) if (!create)
return NULL; return NULL;
MOD_INC_USE_COUNT;
dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL); dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL);
if (dev == NULL) { if (dev == NULL)
MOD_DEC_USE_COUNT;
return NULL; return NULL;
}
memset(dev, 0, sizeof(*dev) + sizeof(*t)); memset(dev, 0, sizeof(*dev) + sizeof(*t));
dev->priv = (void*)(dev+1); dev->priv = (void*)(dev+1);
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
...@@ -256,6 +254,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -256,6 +254,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
goto failed; goto failed;
memcpy(nt->parms.name, dev->name, IFNAMSIZ); memcpy(nt->parms.name, dev->name, IFNAMSIZ);
} }
SET_MODULE_OWNER(dev);
if (register_netdevice(dev) < 0) if (register_netdevice(dev) < 0)
goto failed; goto failed;
...@@ -266,16 +265,13 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -266,16 +265,13 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
failed: failed:
kfree(dev); kfree(dev);
MOD_DEC_USE_COUNT;
return NULL; return NULL;
} }
static void ipip_tunnel_destructor(struct net_device *dev) static void ipip_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipip_fb_tunnel_dev) { if (dev != &ipip_fb_tunnel_dev)
kfree(dev); kfree(dev);
MOD_DEC_USE_COUNT;
}
} }
static void ipip_tunnel_uninit(struct net_device *dev) static void ipip_tunnel_uninit(struct net_device *dev)
...@@ -682,8 +678,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -682,8 +678,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
struct ip_tunnel_parm p; struct ip_tunnel_parm p;
struct ip_tunnel *t; struct ip_tunnel *t;
MOD_INC_USE_COUNT;
switch (cmd) { switch (cmd) {
case SIOCGETTUNNEL: case SIOCGETTUNNEL:
t = NULL; t = NULL;
...@@ -782,7 +776,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -782,7 +776,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
} }
done: done:
MOD_DEC_USE_COUNT;
return err; return err;
} }
...@@ -858,29 +851,11 @@ static int ipip_tunnel_init(struct net_device *dev) ...@@ -858,29 +851,11 @@ static int ipip_tunnel_init(struct net_device *dev)
return 0; return 0;
} }
#ifdef MODULE
static int ipip_fb_tunnel_open(struct net_device *dev)
{
MOD_INC_USE_COUNT;
return 0;
}
static int ipip_fb_tunnel_close(struct net_device *dev)
{
MOD_DEC_USE_COUNT;
return 0;
}
#endif
int __init ipip_fb_tunnel_init(struct net_device *dev) int __init ipip_fb_tunnel_init(struct net_device *dev)
{ {
struct iphdr *iph; struct iphdr *iph;
ipip_tunnel_init_gen(dev); ipip_tunnel_init_gen(dev);
#ifdef MODULE
dev->open = ipip_fb_tunnel_open;
dev->stop = ipip_fb_tunnel_close;
#endif
iph = &ipip_fb_tunnel.parms.iph; iph = &ipip_fb_tunnel.parms.iph;
iph->version = 4; iph->version = 4;
...@@ -910,6 +885,7 @@ int __init ipip_init(void) ...@@ -910,6 +885,7 @@ int __init ipip_init(void)
} }
ipip_fb_tunnel_dev.priv = (void*)&ipip_fb_tunnel; ipip_fb_tunnel_dev.priv = (void*)&ipip_fb_tunnel;
SET_MODULE_OWNER(&ipip_fb_tunnel_dev);
register_netdev(&ipip_fb_tunnel_dev); register_netdev(&ipip_fb_tunnel_dev);
return 0; return 0;
} }
......
...@@ -253,6 +253,10 @@ unsigned int arpt_do_table(struct sk_buff **pskb, ...@@ -253,6 +253,10 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
const char *indev, *outdev; const char *indev, *outdev;
void *table_base; void *table_base;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
indev = in ? in->name : nulldevname; indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname; outdev = out ? out->name : nulldevname;
......
...@@ -818,6 +818,10 @@ unsigned int ip_conntrack_in(unsigned int hooknum, ...@@ -818,6 +818,10 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
if ((*pskb)->nfct) if ((*pskb)->nfct)
return NF_ACCEPT; return NF_ACCEPT;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* Gather fragments. */ /* Gather fragments. */
if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
*pskb = ip_ct_gather_frags(*pskb); *pskb = ip_ct_gather_frags(*pskb);
......
...@@ -192,6 +192,10 @@ static unsigned int ip_refrag(unsigned int hooknum, ...@@ -192,6 +192,10 @@ static unsigned int ip_refrag(unsigned int hooknum,
{ {
struct rtable *rt = (struct rtable *)(*pskb)->dst; struct rtable *rt = (struct rtable *)(*pskb)->dst;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* We've seen it coming out the other side: confirm */ /* We've seen it coming out the other side: confirm */
if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT) if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
return NF_DROP; return NF_DROP;
...@@ -213,6 +217,10 @@ static unsigned int ip_conntrack_local(unsigned int hooknum, ...@@ -213,6 +217,10 @@ static unsigned int ip_conntrack_local(unsigned int hooknum,
const struct net_device *out, const struct net_device *out,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr) if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) { || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
......
...@@ -75,6 +75,10 @@ fw_in(unsigned int hooknum, ...@@ -75,6 +75,10 @@ fw_in(unsigned int hooknum,
int ret = FW_BLOCK; int ret = FW_BLOCK;
u_int16_t redirpt; u_int16_t redirpt;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* Assume worse case: any hook could change packet */ /* Assume worse case: any hook could change packet */
(*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED; (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
if ((*pskb)->ip_summed == CHECKSUM_HW) if ((*pskb)->ip_summed == CHECKSUM_HW)
...@@ -189,6 +193,10 @@ static unsigned int fw_confirm(unsigned int hooknum, ...@@ -189,6 +193,10 @@ static unsigned int fw_confirm(unsigned int hooknum,
const struct net_device *out, const struct net_device *out,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
return ip_conntrack_confirm(*pskb); return ip_conntrack_confirm(*pskb);
} }
......
...@@ -71,6 +71,10 @@ ip_nat_fn(unsigned int hooknum, ...@@ -71,6 +71,10 @@ ip_nat_fn(unsigned int hooknum,
/* maniptype == SRC for postrouting. */ /* maniptype == SRC for postrouting. */
enum ip_nat_manip_type maniptype = HOOK2MANIP(hooknum); enum ip_nat_manip_type maniptype = HOOK2MANIP(hooknum);
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* We never see fragments: conntrack defrags on pre-routing /* We never see fragments: conntrack defrags on pre-routing
and local-out, and ip_nat_out protects post-routing. */ and local-out, and ip_nat_out protects post-routing. */
IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off
...@@ -170,6 +174,10 @@ ip_nat_out(unsigned int hooknum, ...@@ -170,6 +174,10 @@ ip_nat_out(unsigned int hooknum,
const struct net_device *out, const struct net_device *out,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr) if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
...@@ -205,6 +213,10 @@ ip_nat_local_fn(unsigned int hooknum, ...@@ -205,6 +213,10 @@ ip_nat_local_fn(unsigned int hooknum,
u_int32_t saddr, daddr; u_int32_t saddr, daddr;
unsigned int ret; unsigned int ret;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr) if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
......
...@@ -271,6 +271,10 @@ ipt_do_table(struct sk_buff **pskb, ...@@ -271,6 +271,10 @@ ipt_do_table(struct sk_buff **pskb,
void *table_base; void *table_base;
struct ipt_entry *e, *back; struct ipt_entry *e, *back;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* Initialization */ /* Initialization */
ip = (*pskb)->nh.iph; ip = (*pskb)->nh.iph;
protohdr = (u_int32_t *)ip + ip->ihl; protohdr = (u_int32_t *)ip + ip->ihl;
......
...@@ -107,6 +107,10 @@ ipt_local_out_hook(unsigned int hook, ...@@ -107,6 +107,10 @@ ipt_local_out_hook(unsigned int hook,
const struct net_device *out, const struct net_device *out,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr) if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) { || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
......
...@@ -145,6 +145,10 @@ ipt_local_hook(unsigned int hook, ...@@ -145,6 +145,10 @@ ipt_local_hook(unsigned int hook,
u_int32_t saddr, daddr; u_int32_t saddr, daddr;
unsigned long nfmark; unsigned long nfmark;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr) if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) { || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
......
...@@ -111,7 +111,7 @@ static void inet6_sock_destruct(struct sock *sk) ...@@ -111,7 +111,7 @@ static void inet6_sock_destruct(struct sock *sk)
#ifdef INET_REFCNT_DEBUG #ifdef INET_REFCNT_DEBUG
atomic_dec(&inet6_sock_nr); atomic_dec(&inet6_sock_nr);
#endif #endif
MOD_DEC_USE_COUNT; module_put(THIS_MODULE);
} }
static __inline__ kmem_cache_t *inet6_sk_slab(int protocol) static __inline__ kmem_cache_t *inet6_sk_slab(int protocol)
...@@ -242,7 +242,10 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -242,7 +242,10 @@ static int inet6_create(struct socket *sock, int protocol)
atomic_inc(&inet6_sock_nr); atomic_inc(&inet6_sock_nr);
atomic_inc(&inet_sock_nr); atomic_inc(&inet_sock_nr);
#endif #endif
MOD_INC_USE_COUNT; if (!try_module_get(THIS_MODULE)) {
inet_sock_release(sk);
return -EBUSY;
}
if (inet->num) { if (inet->num) {
/* It assumes that any protocol which allows /* It assumes that any protocol which allows
...@@ -255,7 +258,7 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -255,7 +258,7 @@ static int inet6_create(struct socket *sock, int protocol)
if (sk->prot->init) { if (sk->prot->init) {
int err = sk->prot->init(sk); int err = sk->prot->init(sk);
if (err != 0) { if (err != 0) {
MOD_DEC_USE_COUNT; module_put(THIS_MODULE);
inet_sock_release(sk); inet_sock_release(sk);
return err; return err;
} }
......
...@@ -196,7 +196,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval, ...@@ -196,7 +196,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
#ifdef INET_REFCNT_DEBUG #ifdef INET_REFCNT_DEBUG
atomic_dec(&inet6_sock_nr); atomic_dec(&inet6_sock_nr);
#endif #endif
MOD_DEC_USE_COUNT; module_put(THIS_MODULE);
retv = 0; retv = 0;
break; break;
} }
......
...@@ -343,6 +343,10 @@ ip6t_do_table(struct sk_buff **pskb, ...@@ -343,6 +343,10 @@ ip6t_do_table(struct sk_buff **pskb,
void *table_base; void *table_base;
struct ip6t_entry *e, *back; struct ip6t_entry *e, *back;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* Initialization */ /* Initialization */
ipv6 = (*pskb)->nh.ipv6h; ipv6 = (*pskb)->nh.ipv6h;
protohdr = (u_int32_t *)((char *)ipv6 + IPV6_HDR_LEN); protohdr = (u_int32_t *)((char *)ipv6 + IPV6_HDR_LEN);
......
...@@ -154,6 +154,10 @@ ip6t_local_hook(unsigned int hook, ...@@ -154,6 +154,10 @@ ip6t_local_hook(unsigned int hook,
} }
#endif #endif
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* save source/dest address, nfmark, hoplimit, flowlabel, priority, */ /* save source/dest address, nfmark, hoplimit, flowlabel, priority, */
memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr)); memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr)); memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
......
...@@ -170,12 +170,10 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -170,12 +170,10 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
if (!create) if (!create)
return NULL; return NULL;
MOD_INC_USE_COUNT;
dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL); dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL);
if (dev == NULL) { if (dev == NULL)
MOD_DEC_USE_COUNT;
return NULL; return NULL;
}
memset(dev, 0, sizeof(*dev) + sizeof(*t)); memset(dev, 0, sizeof(*dev) + sizeof(*t));
dev->priv = (void*)(dev+1); dev->priv = (void*)(dev+1);
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
...@@ -195,6 +193,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -195,6 +193,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
goto failed; goto failed;
memcpy(nt->parms.name, dev->name, IFNAMSIZ); memcpy(nt->parms.name, dev->name, IFNAMSIZ);
} }
SET_MODULE_OWNER(dev);
if (register_netdevice(dev) < 0) if (register_netdevice(dev) < 0)
goto failed; goto failed;
...@@ -205,16 +204,13 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -205,16 +204,13 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
failed: failed:
kfree(dev); kfree(dev);
MOD_DEC_USE_COUNT;
return NULL; return NULL;
} }
static void ipip6_tunnel_destructor(struct net_device *dev) static void ipip6_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipip6_fb_tunnel_dev) { if (dev != &ipip6_fb_tunnel_dev)
kfree(dev); kfree(dev);
MOD_DEC_USE_COUNT;
}
} }
static void ipip6_tunnel_uninit(struct net_device *dev) static void ipip6_tunnel_uninit(struct net_device *dev)
...@@ -622,8 +618,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -622,8 +618,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
struct ip_tunnel_parm p; struct ip_tunnel_parm p;
struct ip_tunnel *t; struct ip_tunnel *t;
MOD_INC_USE_COUNT;
switch (cmd) { switch (cmd) {
case SIOCGETTUNNEL: case SIOCGETTUNNEL:
t = NULL; t = NULL;
...@@ -721,7 +715,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -721,7 +715,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
} }
done: done:
MOD_DEC_USE_COUNT;
return err; return err;
} }
...@@ -798,29 +791,11 @@ static int ipip6_tunnel_init(struct net_device *dev) ...@@ -798,29 +791,11 @@ static int ipip6_tunnel_init(struct net_device *dev)
return 0; return 0;
} }
#ifdef MODULE
static int ipip6_fb_tunnel_open(struct net_device *dev)
{
MOD_INC_USE_COUNT;
return 0;
}
static int ipip6_fb_tunnel_close(struct net_device *dev)
{
MOD_DEC_USE_COUNT;
return 0;
}
#endif
int __init ipip6_fb_tunnel_init(struct net_device *dev) int __init ipip6_fb_tunnel_init(struct net_device *dev)
{ {
struct iphdr *iph; struct iphdr *iph;
ipip6_tunnel_init_gen(dev); ipip6_tunnel_init_gen(dev);
#ifdef MODULE
dev->open = ipip6_fb_tunnel_open;
dev->stop = ipip6_fb_tunnel_close;
#endif
iph = &ipip6_fb_tunnel.parms.iph; iph = &ipip6_fb_tunnel.parms.iph;
iph->version = 4; iph->version = 4;
...@@ -857,6 +832,7 @@ int __init sit_init(void) ...@@ -857,6 +832,7 @@ int __init sit_init(void)
ipip6_fb_tunnel_dev.priv = (void*)&ipip6_fb_tunnel; ipip6_fb_tunnel_dev.priv = (void*)&ipip6_fb_tunnel;
strcpy(ipip6_fb_tunnel_dev.name, ipip6_fb_tunnel.parms.name); strcpy(ipip6_fb_tunnel_dev.name, ipip6_fb_tunnel.parms.name);
SET_MODULE_OWNER(&ipip6_fb_tunnel_dev);
register_netdev(&ipip6_fb_tunnel_dev); register_netdev(&ipip6_fb_tunnel_dev);
return 0; return 0;
} }
...@@ -193,6 +193,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) ...@@ -193,6 +193,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p); D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p);
if (p->set_tc_index) { if (p->set_tc_index) {
/* FIXME: Safe with non-linear skbs? --RR */
switch (skb->protocol) { switch (skb->protocol) {
case __constant_htons(ETH_P_IP): case __constant_htons(ETH_P_IP):
skb->tc_index = ipv4_get_dsfield(skb->nh.iph); skb->tc_index = ipv4_get_dsfield(skb->nh.iph);
......
...@@ -222,6 +222,11 @@ used on the egress (might slow things for an iota) ...@@ -222,6 +222,11 @@ used on the egress (might slow things for an iota)
*/ */
if (dev->qdisc_ingress) { if (dev->qdisc_ingress) {
/* FIXME: Push down to ->enqueue functions --RR */
if (skb_is_nonlinear(*pskb)
&& skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
spin_lock(&dev->queue_lock); spin_lock(&dev->queue_lock);
if ((q = dev->qdisc_ingress) != NULL) if ((q = dev->qdisc_ingress) != NULL)
fwres = q->enqueue(skb, q); fwres = q->enqueue(skb, q);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment