📄 shaper.c
字号:
/* * Bring the interface up. We just disallow this until a * bind. */static int shaper_open(struct device *dev){ struct shaper *shaper=dev->priv; /* * Can't open until attached. * Also can't open until speed is set, or we'll get * a division by zero. */ if(shaper->dev==NULL) return -ENODEV; if(shaper->bitspersec==0) return -EINVAL; MOD_INC_USE_COUNT; return 0;}/* * Closing a shaper flushes the queues. */ static int shaper_close(struct device *dev){ struct shaper *shaper=dev->priv; shaper_flush(shaper); start_bh_atomic(); del_timer(&shaper->timer); end_bh_atomic(); MOD_DEC_USE_COUNT; return 0;}/* * Revectored calls. We alter the parameters and call the functions * for our attached device. This enables us to bandwidth allocate after * ARP and other resolutions and not before. */static int shaper_start_xmit(struct sk_buff *skb, struct device *dev){ struct shaper *sh=dev->priv; return shaper_qframe(sh, skb);}static struct net_device_stats *shaper_get_stats(struct device *dev){ return NULL;}static int shaper_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len){ struct shaper *sh=dev->priv; int v; if(sh_debug) printk("Shaper header\n"); skb->dev=sh->dev; v=sh->hard_header(skb,sh->dev,type,daddr,saddr,len); skb->dev=dev; return v;}static int shaper_rebuild_header(struct sk_buff *skb){ struct shaper *sh=skb->dev->priv; struct device *dev=skb->dev; int v; if(sh_debug) printk("Shaper rebuild header\n"); skb->dev=sh->dev; v=sh->rebuild_header(skb); skb->dev=dev; return v;}#if 0static int shaper_cache(struct neighbour *neigh, struct hh_cache *hh){ struct shaper *sh=neigh->dev->priv; struct device *tmp; int ret; if(sh_debug) printk("Shaper header cache bind\n"); tmp=neigh->dev; neigh->dev=sh->dev; ret=sh->hard_header_cache(neigh,hh); neigh->dev=tmp; return ret;}static void shaper_cache_update(struct hh_cache *hh, struct device *dev, unsigned char *haddr){ struct shaper *sh=dev->priv; if(sh_debug) printk("Shaper cache update\n"); sh->header_cache_update(hh, sh->dev, haddr);}#endifstatic int shaper_neigh_setup(struct neighbour *n){ if (n->nud_state == NUD_NONE) { n->ops = &arp_broken_ops; n->output = n->ops->output; } return 0;}static int shaper_neigh_setup_dev(struct device *dev, struct neigh_parms *p){ if (p->tbl->family == AF_INET) { p->neigh_setup = shaper_neigh_setup; p->ucast_probes = 0; p->mcast_probes = 0; } return 0;}static int shaper_attach(struct device *shdev, struct shaper *sh, struct device *dev){ sh->dev = dev; sh->hard_start_xmit=dev->hard_start_xmit; sh->get_stats=dev->get_stats; if(dev->hard_header) { sh->hard_header=dev->hard_header; shdev->hard_header = shaper_header; } else shdev->hard_header = NULL; if(dev->rebuild_header) { sh->rebuild_header = dev->rebuild_header; shdev->rebuild_header = shaper_rebuild_header; } else shdev->rebuild_header = NULL; #if 0 if(dev->hard_header_cache) { sh->hard_header_cache = dev->hard_header_cache; shdev->hard_header_cache= shaper_cache; } else { shdev->hard_header_cache= NULL; } if(dev->header_cache_update) { sh->header_cache_update = dev->header_cache_update; shdev->header_cache_update = shaper_cache_update; } else shdev->header_cache_update= NULL;#else shdev->header_cache_update = NULL; shdev->hard_header_cache = NULL;#endif shdev->neigh_setup = shaper_neigh_setup_dev; shdev->hard_header_len=dev->hard_header_len; shdev->type=dev->type; shdev->addr_len=dev->addr_len; shdev->mtu=dev->mtu; sh->bitspersec=0; return 0;}static int shaper_ioctl(struct device *dev, struct ifreq *ifr, int cmd){ struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_data; struct shaper *sh=dev->priv; switch(ss->ss_cmd) { case SHAPER_SET_DEV: { struct device *them=dev_get(ss->ss_name); if(them==NULL) return -ENODEV; if(sh->dev) return -EBUSY; return shaper_attach(dev,dev->priv, them); } case SHAPER_GET_DEV: if(sh->dev==NULL) return -ENODEV; strcpy(ss->ss_name, sh->dev->name); return 0; case SHAPER_SET_SPEED: shaper_setspeed(sh,ss->ss_speed); return 0; case SHAPER_GET_SPEED: ss->ss_speed=sh->bitspersec; return 0; default: return -EINVAL; }}static struct shaper *shaper_alloc(struct device *dev){ struct shaper *sh=kmalloc(sizeof(struct shaper), GFP_KERNEL); if(sh==NULL) return NULL; memset(sh,0,sizeof(*sh)); skb_queue_head_init(&sh->sendq); init_timer(&sh->timer); sh->timer.function=shaper_timer; sh->timer.data=(unsigned long)sh; return sh;}/* * Add a shaper device to the system */ __initfunc(int shaper_probe(struct device *dev)){ /* * Set up the shaper. */ dev->priv = shaper_alloc(dev); if(dev->priv==NULL) return -ENOMEM; dev->open = shaper_open; dev->stop = shaper_close; dev->hard_start_xmit = shaper_start_xmit; dev->get_stats = shaper_get_stats; dev->set_multicast_list = NULL; /* * Intialise the packet queues */ dev_init_buffers(dev); /* * Handlers for when we attach to a device. */ dev->hard_header = shaper_header; dev->rebuild_header = shaper_rebuild_header;#if 0 dev->hard_header_cache = shaper_cache; dev->header_cache_update= shaper_cache_update;#endif dev->neigh_setup = shaper_neigh_setup_dev; dev->do_ioctl = shaper_ioctl; dev->hard_header_len = 0; dev->type = ARPHRD_ETHER; /* initially */ dev->set_mac_address = NULL; dev->mtu = 1500; dev->addr_len = 0; dev->tx_queue_len = 10; dev->flags = 0; /* * Shaper is ok */ return 0;} #ifdef MODULEstatic char devicename[9];static struct device dev_shape = { devicename, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, shaper_probe };int init_module(void){ int err=dev_alloc_name(&dev_shape,"shaper%d"); if(err<0) return err; printk(SHAPER_BANNER); if (register_netdev(&dev_shape) != 0) return -EIO; printk("Traffic shaper initialised.\n"); return 0;}void cleanup_module(void){ /* * No need to check MOD_IN_USE, as sys_delete_module() checks. * To be unloadable we must be closed and detached so we don't * need to flush things. */ unregister_netdev(&dev_shape); /* * Free up the private structure, or leak memory :-) */ kfree(dev_shape.priv); dev_shape.priv = NULL;}#elsestatic struct device dev_sh0 = { "shaper0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, shaper_probe };static struct device dev_sh1 = { "shaper1", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, shaper_probe };static struct device dev_sh2 = { "shaper2", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, shaper_probe };static struct device dev_sh3 = { "shaper3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, shaper_probe };void shaper_init(void){ register_netdev(&dev_sh0); register_netdev(&dev_sh1); register_netdev(&dev_sh2); register_netdev(&dev_sh3);}#endif /* MODULE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -