; ; base modifications ... ; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/skbuff.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/skbuff.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/skbuff.h 2004-10-23 05:06:23.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/skbuff.h 2004-12-10 22:53:32.000000000 +0100 @@ -23,7 +23,7 @@ #include #include #include -#include +//#include #include #include #include @@ -246,6 +246,10 @@ struct sk_buff { security; void (*destructor)(struct sk_buff *skb); +#ifdef CONFIG_VSERVER_NGNET + __u16 nfvnet; + __u16 nfxid; +#endif #ifdef CONFIG_NETFILTER unsigned long nfmark; __u32 nfcache; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/types.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/types.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/types.h 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/types.h 2004-12-10 22:53:32.000000000 +0100 @@ -37,6 +37,7 @@ typedef __kernel_gid32_t gid_t; typedef __kernel_uid16_t uid16_t; typedef __kernel_gid16_t gid16_t; typedef unsigned int xid_t; +typedef __u16 nfxid_t; typedef unsigned int nid_t; #ifdef CONFIG_UID16 diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/loopback.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/loopback.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/loopback.c 2004-10-23 05:06:09.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/loopback.c 2004-12-10 22:53:32.000000000 +0100 @@ -57,6 +57,7 @@ #include #include #include +#include static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); @@ -132,6 +133,13 @@ static int loopback_xmit(struct sk_buff skb->protocol=eth_type_trans(skb,dev); skb->dev=dev; +#ifdef CONFIG_VSERVER_NGNET + if (skb->sk) + skb->nfxid = skb->sk->sk_xid; + vxdprintk(VXD_CBIT(net, 2), + "loopback_xmit(%p) [%p,%d,#%u]", + skb, skb->sk, skb->nfvnet, skb->nfxid); +#endif #ifndef LOOPBACK_MUST_CHECKSUM skb->ip_summed = CHECKSUM_UNNECESSARY; #endif diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/net_init.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/net_init.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/net_init.c 2004-12-04 03:28:07.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/net_init.c 2004-12-10 22:53:32.000000000 +0100 @@ -94,6 +94,9 @@ struct net_device *alloc_netdev(int size dev = (struct net_device *)(((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); dev->padded = (char *)dev - (char *)p; +#ifdef CONFIG_VSERVER_NGNET + dev->nfxid = current->xid; +#endif if (sizeof_priv) dev->priv = netdev_priv(dev); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/inetdevice.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/inetdevice.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/inetdevice.h 2004-12-04 03:28:15.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/inetdevice.h 2004-12-10 22:53:32.000000000 +0100 @@ -101,7 +101,11 @@ struct in_ifaddr extern int register_inetaddr_notifier(struct notifier_block *nb); extern int unregister_inetaddr_notifier(struct notifier_block *nb); +#ifdef CONFIG_VSERVER_NGNET +extern struct net_device *ip_dev_find(u32 addr, nfxid_t nfxid); +#else extern struct net_device *ip_dev_find(u32 addr); +#endif extern int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b); extern int devinet_ioctl(unsigned int cmd, void __user *); extern void devinet_init(void); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netdevice.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netdevice.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netdevice.h 2004-12-04 03:28:15.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netdevice.h 2004-12-10 22:53:32.000000000 +0100 @@ -302,7 +302,9 @@ struct net_device /* Interface index. Unique device identifier */ int ifindex; int iflink; - +#ifdef CONFIG_VSERVER_NGNET + nfxid_t nfxid; +#endif struct net_device_stats* (*get_stats)(struct net_device *dev); struct iw_statistics* (*get_wireless_stats)(struct net_device *dev); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/flow.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/flow.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/flow.h 2004-08-14 12:56:01.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/flow.h 2004-12-10 22:53:32.000000000 +0100 @@ -77,6 +77,10 @@ struct flowi { #define fl_icmp_type uli_u.icmpt.type #define fl_icmp_code uli_u.icmpt.code #define fl_ipsec_spi uli_u.spi + +#ifdef CONFIG_VSERVER_NGNET + nfxid_t nfxid; +#endif } __attribute__((__aligned__(BITS_PER_LONG/8))); #define FLOW_DIR_IN 0 diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/route.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/route.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/route.h 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/route.h 2004-12-10 22:53:32.000000000 +0100 @@ -212,6 +212,10 @@ static inline int ip_route_connect(struc .dport = dport } } }; int err; +#ifdef CONFIG_VSERVER_NGNET + fl.nfxid = current->xid; + if (!dst || !src) { +#else struct nx_info *nx_info = current->nx_info; if (sk) @@ -229,6 +233,7 @@ static inline int ip_route_connect(struc fl.fl4_dst = nx_info->ipv4[0]; } if (!fl.fl4_dst || !fl.fl4_src) { +#endif err = __ip_route_output_key(rp, &fl); if (err) return err; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/dev.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/dev.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/dev.c 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/dev.c 2004-12-10 22:53:32.000000000 +0100 @@ -113,6 +113,8 @@ #include #endif /* CONFIG_NET_RADIO */ #include +#include +#include #include /* This define, if set, will randomly drop a packet when congestion @@ -197,7 +199,9 @@ static struct hlist_head dev_index_head[ static inline struct hlist_head *dev_name_hash(const char *name) { unsigned hash = full_name_hash(name, strnlen(name, IFNAMSIZ)); - return &dev_name_head[hash & ((1<next) + for (dev = __vx_dev_base; dev; dev = dev->next) if (dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len)) break; @@ -600,7 +604,7 @@ struct net_device *dev_getfirstbyhwtype( struct net_device *dev; rtnl_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for (dev = __vx_dev_base; dev; dev = dev->next) { if (dev->type == type) { dev_hold(dev); break; @@ -628,7 +632,7 @@ struct net_device * dev_get_by_flags(uns struct net_device *dev; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for (dev = __vx_dev_base; dev != NULL; dev = dev->next) { if (((dev->flags ^ if_flags) & mask) == 0) { dev_hold(dev); break; @@ -689,7 +693,7 @@ int dev_alloc_name(struct net_device *de if (!inuse) return -ENOMEM; - for (d = dev_base; d; d = d->next) { + for (d = __vx_dev_base; d; d = d->next) { if (!sscanf(d->name, name, &i)) continue; if (i < 0 || i >= max_netdevices) @@ -750,10 +754,13 @@ int dev_change_name(struct net_device *d else strlcpy(dev->name, newname, IFNAMSIZ); + if (!(dev->priv_flags & IFF_VNET)) err = class_device_rename(&dev->class_dev, dev->name); if (!err) { hlist_del(&dev->name_hlist); hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); + if (dev->priv_flags & IFF_VNET) + return err; notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); } @@ -962,7 +969,8 @@ int register_netdevice_notifier(struct n rtnl_lock(); err = notifier_chain_register(&netdev_chain, nb); if (!err) { - for (dev = dev_base; dev; dev = dev->next) { + /* FIXME requires virtualization ? */ + for (dev = __vx_dev_base; dev; dev = dev->next) { nb->notifier_call(nb, NETDEV_REGISTER, dev); if (dev->flags & IFF_UP) @@ -1305,7 +1313,15 @@ int dev_queue_xmit(struct sk_buff *skb) if (dev->xmit_lock_owner != cpu) { HARD_TX_LOCK(dev, cpu); - + #ifdef CONFIG_VSERVER_NGNET + vxdprintk(VXD_CBIT(net, 2), + "dev_queue_xmit(%p,%d,#%u) [%p,#%d]", + skb, skb->nfvnet, skb->nfxid, skb->sk, + skb->sk?skb->sk->sk_xid:0); + /* FIXME pre tagged skb marking has to be kept? */ + if (skb->sk && !skb->nfxid) + skb->nfxid = skb->sk->sk_xid; + #endif if (!netif_queue_stopped(dev)) { if (netdev_nit) dev_queue_xmit_nit(skb, dev); @@ -1434,6 +1450,12 @@ int netif_rx(struct sk_buff *skb) struct softnet_data *queue; unsigned long flags; +#ifdef CONFIG_VSERVER_NGNET + vxdprintk(VXD_CBIT(net, 3), + "netif_rx(%p,%d,#%u) [%p,#%d]", + skb, skb->nfvnet, skb->nfxid, + skb->sk, skb->sk?skb->sk->sk_xid:0); +#endif #ifdef CONFIG_NETPOLL if (skb->dev->netpoll_rx && netpoll_rx(skb)) { kfree_skb(skb); @@ -1562,6 +1584,8 @@ static void net_tx_action(struct softirq static __inline__ int deliver_skb(struct sk_buff *skb, struct packet_type *pt_prev) { + vxdprintk(VXD_CBIT(net, 1), + "deliver_skb(%p,#%d)", skb, skb->nfxid); atomic_inc(&skb->users); return pt_prev->func(skb, skb->dev, pt_prev); } @@ -1636,6 +1660,13 @@ int netif_receive_skb(struct sk_buff *sk int ret = NET_RX_DROP; unsigned short type; +#ifdef CONFIG_VSERVER_NGNET + vxdprintk(VXD_CBIT(net, 3), + "netif_receive_skb(%p,%d,#%u) [%p,#%d] (%d)", + skb, skb->nfvnet, skb->nfxid, + skb->sk, skb->sk?skb->sk->sk_xid:0, + skb->pkt_type); +#endif #ifdef CONFIG_NETPOLL if (skb->dev->netpoll_rx && skb->dev->poll && netpoll_rx(skb)) { kfree_skb(skb); @@ -1664,6 +1695,9 @@ int netif_receive_skb(struct sk_buff *sk } #endif + vxdprintk(VXD_CBIT(net, 1), + "deliver check ...(#%d) dev: %p,%s", + skb->nfxid, skb->dev, (skb->dev?skb->dev->name:NULL)); list_for_each_entry_rcu(ptype, &ptype_all, list) { if (!ptype->dev || ptype->dev == skb->dev) { if (pt_prev) @@ -1900,7 +1934,7 @@ static int dev_ifconf(char __user *arg) */ total = 0; - for (dev = dev_base; dev; dev = dev->next) { + for (dev = __vx_dev_base; dev; dev = dev->next) { if (vx_flags(VXF_HIDE_NETIF, 0) && !dev_in_nx_info(dev, current->nx_info)) continue; @@ -1940,7 +1974,7 @@ static __inline__ struct net_device *dev struct net_device *dev; loff_t i; - for (i = 0, dev = dev_base; dev && i < pos; ++i, dev = dev->next); + for (i = 0, dev = __vx_dev_base; dev && i < pos; ++i, dev = dev->next); return i == pos ? dev : NULL; } @@ -1954,7 +1988,7 @@ void *dev_seq_start(struct seq_file *seq void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { ++*pos; - return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next; + return v == SEQ_START_TOKEN ? __vx_dev_base : ((struct net_device *)v)->next; } void dev_seq_stop(struct seq_file *seq, void *v) @@ -2721,6 +2755,7 @@ int register_netdevice(struct net_device { struct hlist_head *head; struct hlist_node *p; + struct net_device ***__dev_tail = __vx_dev_tail_ptr; int ret; BUG_ON(dev_boot_phase); @@ -2808,14 +2843,21 @@ int register_netdevice(struct net_device dev->next = NULL; dev_init_scheduler(dev); write_lock_bh(&dev_base_lock); - *dev_tail = dev; - dev_tail = &dev->next; + **__dev_tail = dev; + *__dev_tail = &dev->next; hlist_add_head(&dev->name_hlist, head); hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex)); dev_hold(dev); dev->reg_state = NETREG_REGISTERING; write_unlock_bh(&dev_base_lock); +/* + if (dev->priv_flags & IFF_VNET) { + dev->reg_state = NETREG_REGISTERED; + ret = 0; + goto out; + } +*/ /* Notify protocols, that a new device appeared. */ notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); @@ -2934,14 +2976,18 @@ void netdev_run_todo(void) switch(dev->reg_state) { case NETREG_REGISTERING: + if (dev->priv_flags & IFF_VNET) + goto skip_sysfs_register; err = netdev_register_sysfs(dev); if (err) printk(KERN_ERR "%s: failed sysfs registration (%d)\n", dev->name, err); + skip_sysfs_register: dev->reg_state = NETREG_REGISTERED; break; case NETREG_UNREGISTERING: + if (!(dev->priv_flags & IFF_VNET)) netdev_unregister_sysfs(dev); dev->reg_state = NETREG_UNREGISTERED; @@ -3040,13 +3086,13 @@ int unregister_netdevice(struct net_devi dev_close(dev); /* And unlink it from device chain. */ - for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) { + for (dp = &__vx_dev_base; (d = *dp) != NULL; dp = &d->next) { if (d == dev) { write_lock_bh(&dev_base_lock); hlist_del(&dev->name_hlist); hlist_del(&dev->index_hlist); - if (dev_tail == &dev->next) - dev_tail = dp; + if (__vx_dev_tail == &dev->next) + __vx_dev_tail = dp; *dp = d->next; write_unlock_bh(&dev_base_lock); break; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/netfilter.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/netfilter.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/netfilter.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/netfilter.c 2004-12-10 22:53:32.000000000 +0100 @@ -630,6 +630,9 @@ int ip_route_me_harder(struct sk_buff ** #ifdef CONFIG_IP_ROUTE_FWMARK fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark; #endif +#ifdef CONFIG_VSERVER_NGNET + fl.nfxid = (*pskb)->nfxid; +#endif fl.proto = iph->protocol; if (ip_route_output_key(&rt, &fl) != 0) return -1; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/rtnetlink.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/rtnetlink.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/rtnetlink.c 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/rtnetlink.c 2004-12-10 22:53:32.000000000 +0100 @@ -51,6 +51,8 @@ #include #include +#include + DECLARE_MUTEX(rtnl_sem); void rtnl_lock(void) @@ -248,7 +250,7 @@ int rtnetlink_dump_ifinfo(struct sk_buff struct net_device *dev; read_lock(&dev_base_lock); - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { + for (dev=__vx_dev_base, idx=0; dev; dev = dev->next, idx++) { if (idx < s_idx) continue; if (vx_info_flags(skb->sk->sk_vx_info, VXF_HIDE_NETIF, 0) && diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/skbuff.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/skbuff.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/core/skbuff.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/core/skbuff.c 2004-12-10 22:53:32.000000000 +0100 @@ -320,6 +320,10 @@ struct sk_buff *skb_clone(struct sk_buff nf_bridge_get(skb->nf_bridge); #endif #endif /*CONFIG_NETFILTER*/ +#ifdef CONFIG_VSERVER_NGNET + C(nfvnet); + C(nfxid); +#endif #if defined(CONFIG_HIPPI) C(private); #endif diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/af_inet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/af_inet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/af_inet.c 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/af_inet.c 2004-12-10 22:53:32.000000000 +0100 @@ -274,6 +274,7 @@ static int inet_create(struct socket *so if (!answer) goto out_rcu_unlock; err = -EPERM; + /* make an exception for ping */ if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP)) goto override; if (answer->capability > 0 && !capable(answer->capability)) @@ -415,10 +416,13 @@ int inet_bind(struct socket *sock, struc unsigned short snum; int chk_addr_ret; int err; +#ifdef CONFIG_VSERVER_NGNET +#else __u32 s_addr; /* Address used for validation */ __u32 s_addr1; /* Address used for socket */ __u32 s_addr2; /* Broadcast address for the socket */ struct nx_info *nxi = sk->sk_nx_info; +#endif /* If the socket has its own bind function then use it. (RAW) */ if (sk->sk_prot->bind) { @@ -429,6 +433,9 @@ int inet_bind(struct socket *sock, struc if (addr_len < sizeof(struct sockaddr_in)) goto out; +#ifdef CONFIG_VSERVER_NGNET + chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); +#else s_addr = addr->sin_addr.s_addr; s_addr1 = s_addr; s_addr2 = 0xffffffffl; @@ -463,6 +470,7 @@ int inet_bind(struct socket *sock, struc vxdprintk(VXD_CBIT(net, 3), "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d", sk, VXD_QUAD(s_addr), VXD_QUAD(s_addr1), VXD_QUAD(s_addr2)); +#endif /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since @@ -474,7 +482,11 @@ int inet_bind(struct socket *sock, struc err = -EADDRNOTAVAIL; if (!sysctl_ip_nonlocal_bind && !inet->freebind && +#ifdef CONFIG_VSERVER_NGNET + addr->sin_addr.s_addr != INADDR_ANY && +#else s_addr != INADDR_ANY && +#endif chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) @@ -499,8 +511,12 @@ int inet_bind(struct socket *sock, struc if (sk->sk_state != TCP_CLOSE || inet->num) goto out_release_sock; +#ifdef CONFIG_VSERVER_NGNET + inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; +#else inet->rcv_saddr = inet->saddr = s_addr1; inet->rcv_saddr2 = s_addr2; +#endif if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) inet->saddr = 0; /* Use device */ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/igmp.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/igmp.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/igmp.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/igmp.c 2004-12-10 22:53:32.000000000 +0100 @@ -1311,7 +1311,11 @@ static struct in_device * ip_mc_find_dev return idev; } if (imr->imr_address.s_addr) { +#ifdef CONFIG_VSERVER_NGNET + dev = ip_dev_find(imr->imr_address.s_addr, current->xid); +#else dev = ip_dev_find(imr->imr_address.s_addr); +#endif if (!dev) return NULL; __dev_put(dev); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/devinet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/devinet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/devinet.c 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/devinet.c 2004-12-10 22:53:32.000000000 +0100 @@ -832,7 +832,7 @@ no_in_dev: */ read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for (dev = __vx_dev_base; dev; dev = dev->next) { if ((in_dev = __in_dev_get(dev)) == NULL) continue; @@ -911,7 +911,7 @@ u32 inet_confirm_addr(const struct net_d read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for (dev = __vx_dev_base; dev; dev = dev->next) { if ((in_dev = __in_dev_get(dev))) { addr = confirm_addr_indev(in_dev, dst, local, scope); if (addr) @@ -987,7 +987,7 @@ static int inetdev_event(struct notifier case NETDEV_UP: if (dev->mtu < 68) break; - if (dev == &loopback_dev) { + if (dev == __vx_loopback_ptr) { struct in_ifaddr *ifa; if ((ifa = inet_alloc_ifa()) != NULL) { ifa->ifa_local = @@ -1064,6 +1064,7 @@ static int inet_fill_ifaddr(struct sk_bu if (ifa->ifa_label[0]) RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label); nlh->nlmsg_len = skb->tail - b; + // skb->nfxid = ifa->ifa_dev->dev->nfxid; return skb->len; nlmsg_failure: @@ -1083,7 +1084,7 @@ static int inet_dump_ifaddr(struct sk_bu s_ip_idx = ip_idx = cb->args[1]; read_lock(&dev_base_lock); - for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + for (dev = __vx_dev_base, idx = 0; dev; dev = dev->next, idx++) { if (idx < s_idx) continue; if (idx > s_idx) @@ -1160,7 +1161,7 @@ void inet_forward_change(void) ipv4_devconf_dflt.forwarding = on; read_lock(&dev_base_lock); - for (dev = dev_base; dev; dev = dev->next) { + for (dev = __vx_dev_base; dev; dev = dev->next) { struct in_device *in_dev; rcu_read_lock(); in_dev = __in_dev_get(dev); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/route.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/route.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/route.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/route.c 2004-12-10 22:53:32.000000000 +0100 @@ -1346,8 +1346,10 @@ static void ipv4_dst_ifdown(struct dst_e { struct rtable *rt = (struct rtable *) dst; struct in_device *idev = rt->idev; - if (idev && idev->dev != &loopback_dev) { - struct in_device *loopback_idev = in_dev_get(&loopback_dev); + struct net_device *loopback = __vx_loopback_ptr; + + if (idev && idev->dev != loopback) { + struct in_device *loopback_idev = in_dev_get(loopback); if (loopback_idev) { rt->idev = loopback_idev; in_dev_put(idev); @@ -1501,7 +1503,7 @@ static int ip_route_input_mc(struct sk_b #endif rth->rt_iif = rth->fl.iif = dev->ifindex; - rth->u.dst.dev = &loopback_dev; + rth->u.dst.dev = __vx_loopback_ptr; dev_hold(rth->u.dst.dev); rth->idev = in_dev_get(rth->u.dst.dev); rth->fl.oif = 0; @@ -1549,6 +1551,7 @@ static int ip_route_input_slow(struct sk struct fib_result res; struct in_device *in_dev = in_dev_get(dev); struct in_device *out_dev = NULL; + struct net_device *loopback = __vx_loopback_ptr; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = daddr, .saddr = saddr, @@ -1558,6 +1561,9 @@ static int ip_route_input_slow(struct sk .fwmark = skb->nfmark #endif } }, +#ifdef CONFIG_VSERVER_NGNET + .nfxid = skb->nfxid, +#endif .iif = dev->ifindex }; unsigned flags = 0; u32 itag = 0; @@ -1569,6 +1575,7 @@ static int ip_route_input_slow(struct sk /* IP on this device is disabled. */ + vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow()"); if (!in_dev) goto out; @@ -1593,6 +1600,7 @@ static int ip_route_input_slow(struct sk if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr)) goto martian_destination; + vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow() -1-"); /* * Now we are ready to route packet. */ @@ -1602,6 +1610,7 @@ static int ip_route_input_slow(struct sk goto no_route; } free_res = 1; + vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow() -2-"); RT_CACHE_STAT_INC(in_slow_tot); @@ -1611,8 +1620,10 @@ static int ip_route_input_slow(struct sk if (res.type == RTN_LOCAL) { int result; result = fib_validate_source(saddr, daddr, tos, - loopback_dev.ifindex, + loopback->ifindex, dev, &spec_dst, &itag); + vxdprintk(VXD_CBIT(net, 1), + "ip_route_input_slow() -3-"); if (result < 0) goto martian_source; if (result) @@ -1701,7 +1712,8 @@ done: in_dev_put(out_dev); if (free_res) fib_res_put(&res); -out: return err; +out: vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow() = %d", err); + return err; brd_input: if (skb->protocol != htons(ETH_P_IP)) @@ -1745,7 +1757,7 @@ local_input: #endif rth->rt_iif = rth->fl.iif = dev->ifindex; - rth->u.dst.dev = &loopback_dev; + rth->u.dst.dev = loopback; dev_hold(rth->u.dst.dev); rth->idev = in_dev_get(rth->u.dst.dev); rth->rt_gateway = daddr; @@ -1820,6 +1832,7 @@ int ip_route_input(struct sk_buff *skb, unsigned hash; int iif = dev->ifindex; + vxdprintk(VXD_CBIT(net, 1), "ip_route_input()"); tos &= IPTOS_RT_MASK; hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos); @@ -1887,6 +1900,7 @@ int ip_route_input(struct sk_buff *skb, static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) { u32 tos = oldflp->fl4_tos & (IPTOS_RT_MASK | RTO_ONLINK); + struct net_device *loopback = __vx_loopback_ptr; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = oldflp->fl4_dst, .saddr = oldflp->fl4_src, @@ -1898,7 +1912,11 @@ static int ip_route_output_slow(struct r .fwmark = oldflp->fl4_fwmark #endif } }, - .iif = loopback_dev.ifindex, +#ifdef CONFIG_VSERVER_NGNET + // .nfxid = current->xid, + .nfxid = oldflp->nfxid, +#endif + .iif = loopback->ifindex, .oif = oldflp->oif }; struct fib_result res; unsigned flags = 0; @@ -1909,6 +1927,7 @@ static int ip_route_output_slow(struct r int free_res = 0; int err; + vxdprintk(VXD_CBIT(net, 1), "ip_route_output_slow()"); res.fi = NULL; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; @@ -1922,7 +1941,7 @@ static int ip_route_output_slow(struct r goto out; /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ - dev_out = ip_dev_find(oldflp->fl4_src); + dev_out = ip_dev_find(oldflp->fl4_src, oldflp->nfxid); if (dev_out == NULL) goto out; @@ -1958,6 +1977,7 @@ static int ip_route_output_slow(struct r dev_put(dev_out); dev_out = NULL; } + vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow() -1-"); if (oldflp->oif) { dev_out = dev_get_by_index(oldflp->oif); err = -ENODEV; @@ -1983,6 +2003,7 @@ static int ip_route_output_slow(struct r RT_SCOPE_HOST); } } + vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow() -2-"); if (!fl.fl4_dst) { fl.fl4_dst = fl.fl4_src; @@ -1990,13 +2011,14 @@ static int ip_route_output_slow(struct r fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK); if (dev_out) dev_put(dev_out); - dev_out = &loopback_dev; + dev_out = loopback; dev_hold(dev_out); - fl.oif = loopback_dev.ifindex; + fl.oif = loopback->ifindex; res.type = RTN_LOCAL; flags |= RTCF_LOCAL; goto make_route; } + vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow() -3-"); if (fib_lookup(&fl, &res)) { res.fi = NULL; @@ -2031,13 +2053,14 @@ static int ip_route_output_slow(struct r goto out; } free_res = 1; + vxdprintk(VXD_CBIT(net, 1), "ip_route_input_slow() -4-"); if (res.type == RTN_LOCAL) { if (!fl.fl4_src) fl.fl4_src = fl.fl4_dst; if (dev_out) dev_put(dev_out); - dev_out = &loopback_dev; + dev_out = loopback; dev_hold(dev_out); fl.oif = dev_out->ifindex; if (res.fi) @@ -2119,6 +2142,9 @@ make_route: #ifdef CONFIG_IP_ROUTE_FWMARK rth->fl.fl4_fwmark= oldflp->fl4_fwmark; #endif +#ifdef CONFIG_IP_ROUTE_FWMARK + rth->fl.nfxid = oldflp->nfxid; +#endif rth->rt_dst = fl.fl4_dst; rth->rt_src = fl.fl4_src; rth->rt_iif = oldflp->oif ? : dev_out->ifindex; @@ -2167,7 +2193,8 @@ done: dev_put(dev_out); if (in_dev) in_dev_put(in_dev); -out: return err; +out: vxdprintk(VXD_CBIT(net, 1), "ip_route_output_slow() = %d", err); + return err; e_inval: err = -EINVAL; @@ -2182,6 +2209,7 @@ int __ip_route_output_key(struct rtable unsigned hash; struct rtable *rth; + vxdprintk(VXD_CBIT(net, 1), "__ip_route_output_key(#%d)", flp->nfxid); hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5), flp->fl4_tos); rcu_read_lock_bh(); @@ -2194,6 +2222,9 @@ int __ip_route_output_key(struct rtable #ifdef CONFIG_IP_ROUTE_FWMARK rth->fl.fl4_fwmark == flp->fl4_fwmark && #endif +#ifdef CONFIG_VSERVER_NGNET + rth->fl.nfxid == flp->nfxid && +#endif !((rth->fl.fl4_tos ^ flp->fl4_tos) & (IPTOS_RT_MASK | RTO_ONLINK))) { rth->u.dst.lastuse = jiffies; @@ -2215,6 +2246,7 @@ int ip_route_output_flow(struct rtable * { int err; + vxdprintk(VXD_CBIT(net, 1), "ip_route_output_flow()"); if ((err = __ip_route_output_key(rp, flp)) != 0) return err; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/tcp_diag.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/tcp_diag.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/tcp_diag.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/tcp_diag.c 2004-12-10 22:53:32.000000000 +0100 @@ -188,8 +188,12 @@ nlmsg_failure: return -1; } +#ifdef CONFIG_VSERVER_NGNET extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, - int dif); + int dif, xid_t nfxid); +#else +extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); +#endif #ifdef CONFIG_IP_TCPDIAG_IPV6 extern struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport, struct in6_addr *daddr, u16 dport, @@ -211,9 +215,15 @@ static int tcpdiag_get_exact(struct sk_b struct sk_buff *rep; if (req->tcpdiag_family == AF_INET) { +#ifdef CONFIG_VSERVER_NGNET + sk = tcp_v4_lookup(req->id.tcpdiag_dst[0], req->id.tcpdiag_dport, + req->id.tcpdiag_src[0], req->id.tcpdiag_sport, + req->id.tcpdiag_if, in_skb->nfxid); +#else sk = tcp_v4_lookup(req->id.tcpdiag_dst[0], req->id.tcpdiag_dport, req->id.tcpdiag_src[0], req->id.tcpdiag_sport, req->id.tcpdiag_if); +#endif } #ifdef CONFIG_IP_TCPDIAG_IPV6 else if (req->tcpdiag_family == AF_INET6) { diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv6/addrconf.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv6/addrconf.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv6/addrconf.c 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv6/addrconf.c 2004-12-10 22:53:33.000000000 +0100 @@ -2659,10 +2659,13 @@ static int inet6_dump_addr(struct sk_buf struct ifmcaddr6 *ifmca; struct ifacaddr6 *ifaca; +#ifdef CONFIG_VSERVER_NGNET +#else /* no ipv6 inside a vserver for now */ if (skb->sk && skb->sk->sk_vx_info) return skb->len; +#endif s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; read_lock(&dev_base_lock); @@ -2882,10 +2885,13 @@ static int inet6_dump_ifinfo(struct sk_b struct net_device *dev; struct inet6_dev *idev; +#ifdef CONFIG_VSERVER_NGNET +#else /* no ipv6 inside a vserver for now */ if (skb->sk && skb->sk->sk_vx_info) return skb->len; +#endif read_lock(&dev_base_lock); for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { if (idx < s_idx) diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/netlink/af_netlink.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/netlink/af_netlink.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/netlink/af_netlink.c 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/netlink/af_netlink.c 2004-12-10 22:53:33.000000000 +0100 @@ -668,6 +668,10 @@ int netlink_sendskb(struct sock *sk, str } #endif + /* netlink origin xid */ +#ifdef CONFIG_VSERVER_NGNET + skb->nfxid = current->xid; +#endif skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, len); sock_put(sk); @@ -1108,6 +1112,11 @@ static int netlink_dump(struct sock *sk) if (!skb) return -ENOBUFS; + vxdprintk(VXD_CBIT(net, 1), "netlink_dump() xid=%d", current->xid); +#ifdef CONFIG_VSERVER_NGNET + skb->nfxid = current->xid; +#endif + spin_lock(&nlk->cb_lock); cb = nlk->cb; ; ; *_ngnet modifications below ... ; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/ip_fib_ngnet.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/ip_fib_ngnet.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/ip_fib_ngnet.h 2004-10-23 05:06:24.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/ip_fib_ngnet.h 2004-12-10 22:53:32.000000000 +0100 @@ -14,11 +14,14 @@ */ #ifndef _NET_IP_FIB_H -#define _NET_IP_FIB_H +#warn direct include depreciated +#endif #include #include #include +#include +#include /* WARNING: The ordering of these elements must match ordering * of RTA_* rtnetlink attribute numbers. @@ -81,6 +84,7 @@ struct fib_info { #ifdef CONFIG_IP_ROUTE_MULTIPATH int fib_power; #endif + nfxid_t fib_nfxid; struct fib_nh fib_nh[0]; #define fib_dev fib_nh[0].nh_dev }; @@ -125,12 +129,12 @@ struct fib_table { int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); int (*tb_insert)(struct fib_table *table, struct rtmsg *r, struct kern_rta *rta, struct nlmsghdr *n, - struct netlink_skb_parms *req); + struct netlink_skb_parms *req, nfxid_t nfxid); int (*tb_delete)(struct fib_table *table, struct rtmsg *r, struct kern_rta *rta, struct nlmsghdr *n, - struct netlink_skb_parms *req); + struct netlink_skb_parms *req, nfxid_t nfxid); int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, - struct netlink_callback *cb); + struct netlink_callback *cb, nfxid_t nfxid); int (*tb_flush)(struct fib_table *table); void (*tb_select_default)(struct fib_table *table, const struct flowi *flp, struct fib_result *res); @@ -143,30 +147,36 @@ struct fib_table { extern struct fib_table *ip_fib_local_table; extern struct fib_table *ip_fib_main_table; -static inline struct fib_table *fib_get_table(int id) +static inline struct fib_table *fib_get_table(int id, nfxid_t nfxid) { - if (id != RT_TABLE_LOCAL) - return ip_fib_main_table; - return ip_fib_local_table; + return __vx_fib_get_table(id, nfxid); } -static inline struct fib_table *fib_new_table(int id) +static inline struct fib_table *fib_new_table(int id, nfxid_t nfxid) { - return fib_get_table(id); + return __vx_fib_get_table(id, nfxid); } static inline int fib_lookup(const struct flowi *flp, struct fib_result *res) { - if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) && - ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res)) + struct fib_table *fib_local = __vx_fib_local_table(flp->nfxid); + struct fib_table *fib_main = __vx_fib_main_table(flp->nfxid); + + if (fib_local->tb_lookup(fib_local, flp, res) && + fib_main->tb_lookup(fib_main, flp, res)) { + vxdprintk(VXD_CBIT(net, 1), + "fib_lookup() unreachable"); return -ENETUNREACH; + } return 0; } static inline void fib_select_default(const struct flowi *flp, struct fib_result *res) { + struct fib_table *fib_main = __vx_fib_main_table(flp->nfxid); + if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) - ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res); + fib_main->tb_select_default(fib_main, flp, res); } #else /* CONFIG_IP_MULTIPLE_TABLES */ @@ -200,7 +210,6 @@ extern void fib_select_default(const str /* Exported by fib_frontend.c */ extern void ip_fib_init(void); -extern void fib_flush(void); extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); @@ -211,7 +220,7 @@ extern void fib_select_multipath(const s /* Exported by fib_semantics.c */ extern int ip_fib_check_default(u32 gw, struct net_device *dev); -extern int fib_sync_down(u32 local, struct net_device *dev, int force); +extern int fib_sync_down(u32 local, struct net_device *dev, int force, nfxid_t nfxid); extern int fib_sync_up(struct net_device *dev); extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm, struct kern_rta *rta, struct rtentry *r); @@ -219,6 +228,7 @@ extern u32 __fib_res_prefsrc(struct fib /* Exported by fib_hash.c */ extern struct fib_table *fib_hash_init(int id); +extern void fib_table_free(struct fib_table *tb); #ifdef CONFIG_IP_MULTIPLE_TABLES /* Exported by fib_rules.c */ @@ -267,4 +277,3 @@ static inline void fib_res_put(struct fi #endif } -#endif /* _NET_FIB_H */ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_frontend_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_frontend_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_frontend_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_frontend_ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -75,7 +75,7 @@ struct fib_table *__fib_new_table(int id #endif /* CONFIG_IP_MULTIPLE_TABLES */ -void fib_flush(void) +static void fib_flush(nfxid_t nfxid) { int flushed = 0; #ifdef CONFIG_IP_MULTIPLE_TABLES @@ -83,13 +83,16 @@ void fib_flush(void) int id; for (id = RT_TABLE_MAX; id>0; id--) { - if ((tb = fib_get_table(id))==NULL) + if ((tb = fib_get_table(id, nfxid))==NULL) continue; flushed += tb->tb_flush(tb); } #else /* CONFIG_IP_MULTIPLE_TABLES */ - flushed += ip_fib_main_table->tb_flush(ip_fib_main_table); - flushed += ip_fib_local_table->tb_flush(ip_fib_local_table); + struct fib_table *fib_main = __vx_fib_main_table(nfxid); + struct fib_table *fib_local = __vx_fib_local_table(nfxid); + + flushed += fib_main->tb_flush(fib_main); + flushed += fib_local->tb_flush(fib_local); #endif /* CONFIG_IP_MULTIPLE_TABLES */ if (flushed) @@ -100,18 +103,20 @@ void fib_flush(void) * Find the first device with a given source address. */ -struct net_device * ip_dev_find(u32 addr) +struct net_device * ip_dev_find(u32 addr, nfxid_t nfxid) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } }, + .nfxid = nfxid }; struct fib_result res; struct net_device *dev = NULL; + struct fib_table *fib_local = __vx_fib_local_table(fl.nfxid); #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif - if (!ip_fib_local_table || - ip_fib_local_table->tb_lookup(ip_fib_local_table, &fl, &res)) + if (!fib_local || + fib_local->tb_lookup(fib_local, &fl, &res)) return NULL; if (res.type != RTN_LOCAL) goto out; @@ -126,9 +131,11 @@ out: unsigned inet_addr_type(u32 addr) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } }, + .nfxid = current->xid }; struct fib_result res; unsigned ret = RTN_BROADCAST; + struct fib_table *fib_local = __vx_fib_local_table(fl.nfxid); if (ZERONET(addr) || BADCLASS(addr)) return RTN_BROADCAST; @@ -139,10 +146,9 @@ unsigned inet_addr_type(u32 addr) res.r = NULL; #endif - if (ip_fib_local_table) { + if (fib_local) { ret = RTN_UNICAST; - if (!ip_fib_local_table->tb_lookup(ip_fib_local_table, - &fl, &res)) { + if (!fib_local->tb_lookup(fib_local, &fl, &res)) { ret = res.type; fib_res_put(&res); } @@ -166,7 +172,8 @@ int fib_validate_source(u32 src, u32 dst { .daddr = src, .saddr = dst, .tos = tos } }, - .iif = oif }; + .iif = oif, + .nfxid = dev->nfxid }; struct fib_result res; int no_addr, rpf; int ret; @@ -244,6 +251,7 @@ int ip_rt_ioctl(unsigned int cmd, void _ struct nlmsghdr nlh; struct rtmsg rtm; } req; + nfxid_t nfxid = current->xid; switch (cmd) { case SIOCADDRT: /* Add a route */ @@ -256,15 +264,19 @@ int ip_rt_ioctl(unsigned int cmd, void _ err = fib_convert_rtentry(cmd, &req.nlh, &req.rtm, &rta, &r); if (err == 0) { if (cmd == SIOCDELRT) { - struct fib_table *tb = fib_get_table(req.rtm.rtm_table); + struct fib_table *tb = fib_get_table( + req.rtm.rtm_table, nfxid); err = -ESRCH; if (tb) - err = tb->tb_delete(tb, &req.rtm, &rta, &req.nlh, NULL); + err = tb->tb_delete(tb, &req.rtm, &rta, + &req.nlh, NULL, nfxid); } else { - struct fib_table *tb = fib_new_table(req.rtm.rtm_table); + struct fib_table *tb = fib_new_table( + req.rtm.rtm_table, nfxid); err = -ENOBUFS; if (tb) - err = tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL); + err = tb->tb_insert(tb, &req.rtm, &rta, + &req.nlh, NULL, nfxid); } if (rta.rta_mx) kfree(rta.rta_mx); @@ -305,13 +317,17 @@ int inet_rtm_delroute(struct sk_buff *sk struct fib_table * tb; struct rtattr **rta = arg; struct rtmsg *r = NLMSG_DATA(nlh); + nfxid_t nfxid = skb->nfxid; + vxdprintk(VXD_CBIT(net, 1), + "inet_rtm_delroute(%p,#%d)", skb, nfxid); if (inet_check_attr(r, rta)) return -EINVAL; - tb = fib_get_table(r->rtm_table); + tb = fib_get_table(r->rtm_table, nfxid); if (tb) - return tb->tb_delete(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb)); + return tb->tb_delete(tb, r, (struct kern_rta*)rta, + nlh, &NETLINK_CB(skb), nfxid); return -ESRCH; } @@ -320,13 +336,17 @@ int inet_rtm_newroute(struct sk_buff *sk struct fib_table * tb; struct rtattr **rta = arg; struct rtmsg *r = NLMSG_DATA(nlh); + nfxid_t nfxid = skb->nfxid; + vxdprintk(VXD_CBIT(net, 1), + "inet_rtm_newroute(%p,#%d)", skb, nfxid); if (inet_check_attr(r, rta)) return -EINVAL; - tb = fib_new_table(r->rtm_table); + tb = fib_new_table(r->rtm_table, nfxid); if (tb) - return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb)); + return tb->tb_insert(tb, r, (struct kern_rta*)rta, + nlh, &NETLINK_CB(skb), nfxid); return -ENOBUFS; } @@ -335,7 +355,10 @@ int inet_dump_fib(struct sk_buff *skb, s int t; int s_t; struct fib_table *tb; + nfxid_t nfxid = skb->nfxid; + vxdprintk(VXD_CBIT(net, 1), + "inet_dump_fib(%p,#%d)", skb, nfxid); if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) && ((struct rtmsg*)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED) return ip_rt_dump(skb, cb); @@ -348,9 +371,9 @@ int inet_dump_fib(struct sk_buff *skb, s if (t < s_t) continue; if (t > s_t) memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); - if ((tb = fib_get_table(t))==NULL) + if ((tb = fib_get_table(t, nfxid))==NULL) continue; - if (tb->tb_dump(tb, skb, cb) < 0) + if (tb->tb_dump(tb, skb, cb, nfxid) < 0) break; } @@ -366,7 +389,8 @@ int inet_dump_fib(struct sk_buff *skb, s only when netlink is already locked. */ -static void fib_magic(int cmd, int type, u32 dst, int dst_len, struct in_ifaddr *ifa) +static void fib_magic(int cmd, int type, u32 dst, int dst_len, + struct in_ifaddr *ifa, nfxid_t nfxid) { struct fib_table * tb; struct { @@ -379,9 +403,9 @@ static void fib_magic(int cmd, int type, memset(&rta, 0, sizeof(rta)); if (type == RTN_UNICAST) - tb = fib_new_table(RT_TABLE_MAIN); + tb = fib_new_table(RT_TABLE_MAIN, nfxid); else - tb = fib_new_table(RT_TABLE_LOCAL); + tb = fib_new_table(RT_TABLE_LOCAL, nfxid); if (tb == NULL) return; @@ -403,9 +427,11 @@ static void fib_magic(int cmd, int type, rta.rta_oif = &ifa->ifa_dev->dev->ifindex; if (cmd == RTM_NEWROUTE) - tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL); + tb->tb_insert(tb, &req.rtm, &rta, + &req.nlh, NULL, nfxid); else - tb->tb_delete(tb, &req.rtm, &rta, &req.nlh, NULL); + tb->tb_delete(tb, &req.rtm, &rta, + &req.nlh, NULL, nfxid); } static void fib_add_ifaddr(struct in_ifaddr *ifa) @@ -416,6 +442,7 @@ static void fib_add_ifaddr(struct in_ifa u32 mask = ifa->ifa_mask; u32 addr = ifa->ifa_local; u32 prefix = ifa->ifa_address&mask; + nfxid_t nfxid = dev->nfxid; if (ifa->ifa_flags&IFA_F_SECONDARY) { prim = inet_ifa_byprefix(in_dev, prefix, mask); @@ -425,24 +452,27 @@ static void fib_add_ifaddr(struct in_ifa } } - fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim); + fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim, nfxid); if (!(dev->flags&IFF_UP)) return; /* Add broadcast address, if it is explicitly assigned. */ if (ifa->ifa_broadcast && ifa->ifa_broadcast != 0xFFFFFFFF) - fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); + fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, + 32, prim, nfxid); if (!ZERONET(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) && (prefix != addr || ifa->ifa_prefixlen < 32)) { fib_magic(RTM_NEWROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : - RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim); + RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim, nfxid); /* Add network specific broadcasts, when it takes a sense */ if (ifa->ifa_prefixlen < 31) { - fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, 32, prim); - fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix|~mask, 32, prim); + fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, + 32, prim, nfxid); + fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix|~mask, + 32, prim, nfxid); } } } @@ -460,10 +490,11 @@ static void fib_del_ifaddr(struct in_ifa #define BRD0_OK 4 #define BRD1_OK 8 unsigned ok = 0; + nfxid_t nfxid = dev->nfxid; if (!(ifa->ifa_flags&IFA_F_SECONDARY)) fib_magic(RTM_DELROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : - RTN_UNICAST, any, ifa->ifa_prefixlen, prim); + RTN_UNICAST, any, ifa->ifa_prefixlen, prim, nfxid); else { prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); if (prim == NULL) { @@ -490,13 +521,15 @@ static void fib_del_ifaddr(struct in_ifa } if (!(ok&BRD_OK)) - fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); + fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, + 32, prim, nfxid); if (!(ok&BRD1_OK)) - fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim); + fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim, nfxid); if (!(ok&BRD0_OK)) - fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim); + fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim, nfxid); if (!(ok&LOCAL_OK)) { - fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim); + fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, + 32, prim, nfxid); /* Check, that this local address finally disappeared. */ if (inet_addr_type(ifa->ifa_local) != RTN_LOCAL) { @@ -506,8 +539,8 @@ static void fib_del_ifaddr(struct in_ifa First of all, we scan fib_info list searching for stray nexthop entries, then ignite fib_flush. */ - if (fib_sync_down(ifa->ifa_local, NULL, 0)) - fib_flush(); + if (fib_sync_down(ifa->ifa_local, NULL, 0, nfxid)) + fib_flush(nfxid); } } #undef LOCAL_OK @@ -518,8 +551,8 @@ static void fib_del_ifaddr(struct in_ifa static void fib_disable_ip(struct net_device *dev, int force) { - if (fib_sync_down(0, dev, force)) - fib_flush(); + if (fib_sync_down(0, dev, force, dev->nfxid)) + fib_flush(dev->nfxid); rt_cache_flush(0); arp_ifdown(dev); } @@ -556,6 +589,9 @@ static int fib_netdev_event(struct notif struct net_device *dev = ptr; struct in_device *in_dev = __in_dev_get(dev); + vxdprintk(VXD_CBIT(net, 1), + "fib_netdev_event() dev=%p[#%d,%s], e=%lu, xid=%d", + dev, dev->nfxid, dev->name, event, current->xid); if (event == NETDEV_UNREGISTER) { fib_disable_ip(dev, 2); return NOTIFY_DONE; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_hash_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_hash_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_hash_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_hash_ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -43,7 +43,7 @@ #include #include -#include "fib_lookup.h" +#include "fib_lookup_ngnet.h" static kmem_cache_t *fn_hash_kmem; static kmem_cache_t *fn_alias_kmem; @@ -52,6 +52,7 @@ struct fib_node { struct hlist_node fn_hash; struct list_head fn_alias; u32 fn_key; + uint16_t fn_nfxid; }; struct fn_zone { @@ -246,7 +247,10 @@ fn_hash_lookup(struct fib_table *tb, con int err; struct fn_zone *fz; struct fn_hash *t = (struct fn_hash*)tb->tb_data; + nfxid_t nfxid = flp->nfxid; + vxdprintk(VXD_CBIT(net, 1), + "fn_hash_lookup(%08x,#%d)", flp->fl4_dst, flp->nfxid); read_lock(&fib_hash_lock); for (fz = t->fn_zone_list; fz; fz = fz->fz_next) { struct hlist_head *head; @@ -258,6 +262,8 @@ fn_hash_lookup(struct fib_table *tb, con hlist_for_each_entry(f, node, head, fn_hash) { if (f->fn_key != k) continue; + if (f->fn_nfxid != nfxid) + continue; err = fib_semantic_match(&f->fn_alias, flp, res, @@ -307,6 +313,7 @@ fn_hash_select_default(struct fib_table struct fib_info *last_resort; struct fn_hash *t = (struct fn_hash*)tb->tb_data; struct fn_zone *fz = t->fn_zones[0]; + nfxid_t nfxid = flp->nfxid; if (fz == NULL) return; @@ -315,10 +322,14 @@ fn_hash_select_default(struct fib_table last_resort = NULL; order = -1; + vxdprintk(VXD_CBIT(net, 1), + "fn_hash_select_default(%08x,#%d)", flp->fl4_dst, flp->nfxid); read_lock(&fib_hash_lock); hlist_for_each_entry(f, node, &fz->fz_hash[0], fn_hash) { struct fib_alias *fa; + if (f->fn_nfxid != nfxid) + continue; list_for_each_entry(fa, &f->fn_alias, fa_list) { struct fib_info *next_fi = fa->fa_info; @@ -390,13 +401,15 @@ static inline void fib_insert_node(struc } /* Return the node in FZ matching KEY. */ -static struct fib_node *fib_find_node(struct fn_zone *fz, u32 key) +static struct fib_node *fib_find_node(struct fn_zone *fz, u32 key, nfxid_t nfxid) { struct hlist_head *head = &fz->fz_hash[fn_hash(key, fz)]; struct hlist_node *node; struct fib_node *f; hlist_for_each_entry(f, node, head, fn_hash) { + if (f->fn_nfxid != nfxid) + continue; if (f->fn_key == key) return f; } @@ -426,7 +439,7 @@ static struct fib_alias *fib_find_alias( static int fn_hash_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, - struct nlmsghdr *n, struct netlink_skb_parms *req) + struct nlmsghdr *n, struct netlink_skb_parms *req, nfxid_t nfxid) { struct fn_hash *table = (struct fn_hash *) tb->tb_data; struct fib_node *new_f, *f; @@ -454,7 +467,7 @@ fn_hash_insert(struct fib_table *tb, str key = fz_key(dst, fz); } - if ((fi = fib_create_info(r, rta, n, &err)) == NULL) + if ((fi = fib_create_info(r, rta, n, &err, nfxid)) == NULL) return err; if (fz->fz_nent > (fz->fz_divisor<<1) && @@ -462,7 +475,7 @@ fn_hash_insert(struct fib_table *tb, str (z==32 || (1< fz->fz_divisor)) fn_rehash_zone(fz); - f = fib_find_node(fz, key); + f = fib_find_node(fz, key, nfxid); fa = fib_find_alias(f, tos, fi->fib_priority); /* Now fa, if non-NULL, points to the first fib alias @@ -541,6 +554,7 @@ fn_hash_insert(struct fib_table *tb, str INIT_HLIST_NODE(&new_f->fn_hash); INIT_LIST_HEAD(&new_f->fn_alias); new_f->fn_key = key; + new_f->fn_nfxid = nfxid; f = new_f; } @@ -578,7 +592,7 @@ out: static int fn_hash_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, - struct nlmsghdr *n, struct netlink_skb_parms *req) + struct nlmsghdr *n, struct netlink_skb_parms *req, nfxid_t nfxid) { struct fn_hash *table = (struct fn_hash*)tb->tb_data; struct fib_node *f; @@ -602,7 +616,7 @@ fn_hash_delete(struct fib_table *tb, str key = fz_key(dst, fz); } - f = fib_find_node(fz, key); + f = fib_find_node(fz, key, nfxid); fa = fib_find_alias(f, tos, 0); if (!fa) return -ESRCH; @@ -711,7 +725,8 @@ static inline int fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, struct fib_table *tb, struct fn_zone *fz, - struct hlist_head *head) + struct hlist_head *head, + nfxid_t nfxid) { struct hlist_node *node; struct fib_node *f; @@ -722,6 +737,8 @@ fn_hash_dump_bucket(struct sk_buff *skb, hlist_for_each_entry(f, node, head, fn_hash) { struct fib_alias *fa; + if (f->fn_nfxid != nfxid) + continue; list_for_each_entry(fa, &f->fn_alias, fa_list) { if (i < s_i) continue; @@ -750,7 +767,8 @@ fn_hash_dump_bucket(struct sk_buff *skb, static inline int fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb, struct fib_table *tb, - struct fn_zone *fz) + struct fn_zone *fz, + nfxid_t nfxid) { int h, s_h; @@ -763,7 +781,8 @@ fn_hash_dump_zone(struct sk_buff *skb, s if (fz->fz_hash == NULL || hlist_empty(&fz->fz_hash[h])) continue; - if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h])<0) { + if (fn_hash_dump_bucket(skb, cb, tb, fz, + &fz->fz_hash[h], nfxid)<0) { cb->args[2] = h; return -1; } @@ -772,7 +791,8 @@ fn_hash_dump_zone(struct sk_buff *skb, s return skb->len; } -static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) +static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, + struct netlink_callback *cb, nfxid_t nfxid) { int m, s_m; struct fn_zone *fz; @@ -785,7 +805,7 @@ static int fn_hash_dump(struct fib_table if (m > s_m) memset(&cb->args[2], 0, sizeof(cb->args) - 2*sizeof(cb->args[0])); - if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) { + if (fn_hash_dump_zone(skb, cb, tb, fz, nfxid) < 0) { cb->args[1] = m; read_unlock(&fib_hash_lock); return -1; @@ -823,11 +843,7 @@ static void rtmsg_fib(int event, struct netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT); } -#ifdef CONFIG_IP_MULTIPLE_TABLES struct fib_table * fib_hash_init(int id) -#else -struct fib_table * __init fib_hash_init(int id) -#endif { struct fib_table *tb; @@ -859,6 +875,12 @@ struct fib_table * __init fib_hash_init( return tb; } +void fib_table_free(struct fib_table *tb) +{ + fn_hash_flush(tb); + kfree(tb); +} + /* ------------------------------------------------------------------------ */ #ifdef CONFIG_PROC_FS @@ -868,12 +890,14 @@ struct fib_iter_state { struct hlist_head *hash_head; struct fib_node *fn; struct fib_alias *fa; + xid_t xid; }; static struct fib_alias *fib_get_first(struct seq_file *seq) { struct fib_iter_state *iter = seq->private; - struct fn_hash *table = (struct fn_hash *) ip_fib_main_table->tb_data; + struct fib_table *fib_main = __vx_fib_main_table(iter->xid); + struct fn_hash *table = (struct fn_hash *) fib_main->tb_data; iter->bucket = 0; iter->hash_head = NULL; @@ -898,6 +922,8 @@ static struct fib_alias *fib_get_first(s hlist_for_each_entry(fn,node,iter->hash_head,fn_hash) { struct fib_alias *fa; + if (fn->fn_nfxid != iter->xid) + continue; list_for_each_entry(fa,&fn->fn_alias,fa_list) { iter->fn = fn; iter->fa = fa; @@ -935,6 +961,8 @@ static struct fib_alias *fib_get_next(st hlist_for_each_entry_continue(fn, node, fn_hash) { iter->fn = fn; + if (fn->fn_nfxid != iter->xid) + continue; list_for_each_entry(fa, &fn->fn_alias, fa_list) { iter->fa = fa; goto out; @@ -958,6 +986,8 @@ static struct fib_alias *fib_get_next(st iter->hash_head++; hlist_for_each_entry(fn, node, iter->hash_head, fn_hash) { + if (fn->fn_nfxid != iter->xid) + continue; list_for_each_entry(fa, &fn->fn_alias, fa_list) { iter->fn = fn; iter->fa = fa; @@ -975,6 +1005,8 @@ static struct fib_alias *fib_get_next(st iter->hash_head = iter->zone->fz_hash; hlist_for_each_entry(fn, node, iter->hash_head, fn_hash) { + if (fn->fn_nfxid != iter->xid) + continue; list_for_each_entry(fa, &fn->fn_alias, fa_list) { iter->fn = fn; iter->fa = fa; @@ -988,10 +1020,11 @@ out: static void *fib_seq_start(struct seq_file *seq, loff_t *pos) { + struct fib_iter_state *iter = seq->private; void *v = NULL; read_lock(&fib_hash_lock); - if (ip_fib_main_table) + if (__vx_fib_main_table(iter->xid)) v = *pos ? fib_get_next(seq) : SEQ_START_TOKEN; return v; } @@ -1022,6 +1055,8 @@ static unsigned fib_flag_trans(int type, return flags; } +extern int dev_in_nx_info(struct net_device *, struct nx_info *); + /* * This outputs /proc/net/route. * @@ -1052,7 +1087,8 @@ static int fib_seq_show(struct seq_file prefix = f->fn_key; mask = FZ_MASK(iter->zone); flags = fib_flag_trans(fa->fa_type, mask, fi); - if (fi) + if (fi && (!vx_flags(VXF_HIDE_NETIF, 0) || + dev_in_nx_info(fi->fib_dev, current->nx_info))) snprintf(bf, sizeof(bf), "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u", fi->fib_dev ? fi->fib_dev->name : "*", prefix, @@ -1092,6 +1128,7 @@ static int fib_seq_open(struct inode *in seq = file->private_data; seq->private = s; memset(s, 0, sizeof(*s)); + s->xid = current->xid; out: return rc; out_kfree: diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_lookup_ngnet.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_lookup_ngnet.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_lookup_ngnet.h 2004-10-23 05:06:25.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_lookup_ngnet.h 2004-12-10 22:53:32.000000000 +0100 @@ -24,7 +24,7 @@ extern void fib_release_info(struct fib_ extern struct fib_info *fib_create_info(const struct rtmsg *r, struct kern_rta *rta, const struct nlmsghdr *, - int *err); + int *err, nfxid_t nfxid); extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *, struct kern_rta *rta, struct fib_info *fi); extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_rules_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_rules_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_rules_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_rules_ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -326,7 +326,7 @@ FRprintk("tb %d r %d ", r->r_table, r->r return -EACCES; } - if ((tb = fib_get_table(r->r_table)) == NULL) + if ((tb = fib_get_table(r->r_table, flp->nfxid)) == NULL) continue; err = tb->tb_lookup(tb, flp, res); if (err == 0) { @@ -351,7 +351,7 @@ void fib_select_default(const struct flo if (res->r && res->r->r_action == RTN_UNICAST && FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) { struct fib_table *tb; - if ((tb = fib_get_table(res->r->r_table)) != NULL) + if ((tb = fib_get_table(res->r->r_table, flp->nfxid)) != NULL) tb->tb_select_default(tb, flp, res); } } diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_semantics_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_semantics_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_semantics_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_semantics_ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -43,7 +43,7 @@ #include #include -#include "fib_lookup.h" +#include "fib_lookup_ngnet.h" #define FSprintk(a...) @@ -216,7 +216,10 @@ static struct fib_info *fib_find_info(co hash = fib_info_hashfn(nfi); head = &fib_info_hash[hash]; + // printk("fib_find_info(%p,#%d)\n", nfi, nfi->fib_nfxid); hlist_for_each_entry(fi, node, head, fib_hash) { + if (fi->fib_nfxid != nfi->fib_nfxid) + continue; if (fi->fib_nhs != nfi->fib_nhs) continue; if (nfi->fib_protocol == fi->fib_protocol && @@ -449,7 +452,8 @@ static int fib_check_nh(const struct rtm struct flowi fl = { .nl_u = { .ip4_u = { .daddr = nh->nh_gw, .scope = r->rtm_scope + 1 } }, - .oif = nh->nh_oif }; + .oif = nh->nh_oif, + .nfxid = -2 }; /* It is not necessary, but requires a bit of thinking */ if (fl.fl4_scope < RT_SCOPE_LINK) @@ -571,7 +575,7 @@ static void fib_hash_move(struct hlist_h struct fib_info * fib_create_info(const struct rtmsg *r, struct kern_rta *rta, - const struct nlmsghdr *nlh, int *errp) + const struct nlmsghdr *nlh, int *errp, nfxid_t nfxid) { int err; struct fib_info *fi = NULL; @@ -627,7 +631,7 @@ fib_create_info(const struct rtmsg *r, s memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct fib_nh)); fi->fib_protocol = r->rtm_protocol; - + fi->fib_nfxid = nfxid; fi->fib_nhs = nhs; change_nexthops(fi) { nh->nh_parent = fi; @@ -1059,7 +1063,7 @@ fib_convert_rtentry(int cmd, struct nlms - device went down -> we must shutdown all nexthops going via it. */ -int fib_sync_down(u32 local, struct net_device *dev, int force) +int fib_sync_down(u32 local, struct net_device *dev, int force, nfxid_t nfxid) { int ret = 0; int scope = RT_SCOPE_NOWHERE; @@ -1074,7 +1078,11 @@ int fib_sync_down(u32 local, struct net_ struct fib_info *fi; hlist_for_each_entry(fi, node, head, fib_lhash) { + if (fi->fib_nfxid != nfxid) + continue; if (fi->fib_prefsrc == local) { + vxdprintk(VXD_CBIT(net, 1), + "tear down %p(%08x)", fi, local); fi->fib_flags |= RTNH_F_DEAD; ret++; } diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/icmp_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/icmp_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/icmp_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/icmp_ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -344,10 +344,13 @@ int icmp_glue_bits(void *from, char *to, } static void icmp_push_reply(struct icmp_bxm *icmp_param, - struct ipcm_cookie *ipc, struct rtable *rt) + struct ipcm_cookie *ipc, + struct rtable *rt, nfxid_t nfxid) { struct sk_buff *skb; + vxdprintk(VXD_CBIT(net, 1), + "icmp_push_reply(%d)\n", nfxid); ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, icmp_param->data_len+icmp_param->head_len, icmp_param->head_len, @@ -366,6 +369,7 @@ static void icmp_push_reply(struct icmp_ icmp_param->head_len, csum); icmph->checksum = csum_fold(csum); skb->ip_summed = CHECKSUM_NONE; + skb->nfxid = nfxid; ip_push_pending_frames(icmp_socket->sk); } } @@ -404,13 +408,14 @@ static void icmp_reply(struct icmp_bxm * { .daddr = daddr, .saddr = rt->rt_spec_dst, .tos = RT_TOS(skb->nh.iph->tos) } }, - .proto = IPPROTO_ICMP }; + .proto = IPPROTO_ICMP, + .nfxid = skb->nfxid }; if (ip_route_output_key(&rt, &fl)) goto out_unlock; } if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type, icmp_param->data.icmph.code)) - icmp_push_reply(icmp_param, &ipc, rt); + icmp_push_reply(icmp_param, &ipc, rt, skb->nfxid); ip_rt_put(rt); out_unlock: icmp_xmit_unlock(); @@ -571,7 +576,7 @@ void icmp_send(struct sk_buff *skb_in, i icmp_param.data_len = room; icmp_param.head_len = sizeof(struct icmphdr); - icmp_push_reply(&icmp_param, &ipc, rt); + icmp_push_reply(&icmp_param, &ipc, rt, skb_in->nfxid); ende: ip_rt_put(rt); out_unlock: @@ -692,8 +697,8 @@ static void icmp_unreach(struct sk_buff read_lock(&raw_v4_lock); if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) { while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, - iph->saddr, - skb->dev->ifindex)) != NULL) { + iph->saddr, skb->dev->ifindex, + skb->nfxid)) != NULL) { raw_err(raw_sk, skb, info); raw_sk = sk_next(raw_sk); iph = (struct iphdr *)skb->data; @@ -769,6 +774,8 @@ out_err: static void icmp_echo(struct sk_buff *skb) { + vxdprintk(VXD_CBIT(net, 1), + "icmp_echo(%p,%d,#%d)", skb, skb->nfvnet, skb->nfxid); if (!sysctl_icmp_echo_ignore_all) { struct icmp_bxm icmp_param; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ip_input.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ip_input.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ip_input.c 2004-10-23 05:06:25.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ip_input.c 2004-12-10 22:53:32.000000000 +0100 @@ -361,11 +361,15 @@ int ip_rcv(struct sk_buff *skb, struct n { struct iphdr *iph; + vxdprintk(VXD_CBIT(net, 1), + "ip_rcv(%p[%d,#%u],%p:%s)", + skb, skb->nfvnet, skb->nfxid, dev, dev->name); /* When the interface is in promisc. mode, drop all the crap * that it receives, do not try to analyse it. */ if (skb->pkt_type == PACKET_OTHERHOST) goto drop; + vxdprintk(VXD_CBIT(net, 1), "ip_rcv() -0.1-"); IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES); @@ -373,12 +377,14 @@ int ip_rcv(struct sk_buff *skb, struct n IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); goto out; } + vxdprintk(VXD_CBIT(net, 1), "ip_rcv() -0.2-"); if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto inhdr_error; iph = skb->nh.iph; + vxdprintk(VXD_CBIT(net, 1), "ip_rcv() -1-"); /* * RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum. * @@ -401,6 +407,7 @@ int ip_rcv(struct sk_buff *skb, struct n if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) goto inhdr_error; + vxdprintk(VXD_CBIT(net, 1), "ip_rcv() -2-"); { __u32 len = ntohs(iph->tot_len); if (skb->len < len || len < (iph->ihl<<2)) @@ -417,6 +424,7 @@ int ip_rcv(struct sk_buff *skb, struct n } } + vxdprintk(VXD_CBIT(net, 1), "ip_rcv() -3-"); return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ip_output.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ip_output.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ip_output.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ip_output.c 2004-12-10 22:53:32.000000000 +0100 @@ -84,6 +84,7 @@ #include #include #include +#include /* * Shall we try to damage output packets if routing dev changes? @@ -163,6 +164,8 @@ int ip_build_and_send_pkt(struct sk_buff ip_send_check(iph); skb->priority = sk->sk_priority; + skb->nfvnet = VNET_UNTAGGED; + skb->nfxid = current->xid; /* Send it out. */ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, @@ -372,6 +375,8 @@ packet_routed: ip_send_check(iph); skb->priority = sk->sk_priority; + skb->nfvnet = VNET_UNTAGGED; + skb->nfxid = current->xid; return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); @@ -1183,6 +1188,8 @@ int ip_push_pending_frames(struct sock * ip_send_check(iph); skb->priority = sk->sk_priority; + skb->nfvnet = VNET_UNTAGGED; + skb->nfxid = current->xid; skb->dst = dst_clone(&rt->u.dst); /* Netfilter gets whole the not fragmented skb. */ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ip_sockglue.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ip_sockglue.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ip_sockglue.c 2004-08-14 12:55:09.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ip_sockglue.c 2004-12-10 22:53:32.000000000 +0100 @@ -568,7 +568,7 @@ int ip_setsockopt(struct sock *sk, int l err = 0; break; } - dev = ip_dev_find(mreq.imr_address.s_addr); + dev = ip_dev_find(mreq.imr_address.s_addr, current->xid); if (dev) { mreq.imr_ifindex = dev->ifindex; dev_put(dev); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ipconfig.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ipconfig.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/ipconfig.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/ipconfig.c 2004-12-10 22:53:32.000000000 +0100 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -178,18 +179,19 @@ static struct net_device *ic_dev __initd static int __init ic_open_devs(void) { struct ic_device *d, **last; - struct net_device *dev; + struct net_device *dev, *loopback; unsigned short oflags; last = &ic_first_dev; rtnl_shlock(); /* bring loopback device up first */ - if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0) - printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name); + loopback = __vx_loopback_ptr; + if (dev_change_flags(loopback, loopback->flags | IFF_UP) < 0) + printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback->name); - for (dev = dev_base; dev; dev = dev->next) { - if (dev == &loopback_dev) + for (dev = __vx_dev_base; dev; dev = dev->next) { + if (dev == loopback) continue; if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : (!(dev->flags & IFF_LOOPBACK) && diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/raw_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/raw_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/raw_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/raw_ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -79,6 +79,7 @@ #include #include #include +#include struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE]; rwlock_t raw_v4_lock = RW_LOCK_UNLOCKED; @@ -102,7 +103,7 @@ static void raw_v4_unhash(struct sock *s struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, unsigned long raddr, unsigned long laddr, - int dif) + int dif, nfxid_t nfxid) { struct hlist_node *node; @@ -113,6 +135,7 @@ struct sock *__raw_v4_lookup(struct sock if (inet->num == num && !(inet->daddr && inet->daddr != raddr) && + vx_sk_check(sk, nfxid) && !(inet->rcv_saddr && inet->rcv_saddr != laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) goto found; /* gotcha */ @@ -161,7 +184,7 @@ void raw_v4_input(struct sk_buff *skb, s goto out; sk = __raw_v4_lookup(__sk_head(head), iph->protocol, iph->saddr, iph->daddr, - skb->dev->ifindex); + skb->dev->ifindex, skb->nfxid); while (sk) { if (iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) { @@ -173,7 +196,7 @@ void raw_v4_input(struct sk_buff *skb, s } sk = __raw_v4_lookup(sk_next(sk), iph->protocol, iph->saddr, iph->daddr, - skb->dev->ifindex); + skb->dev->ifindex, skb->nfxid); } out: read_unlock(&raw_v4_lock); @@ -309,6 +332,9 @@ static int raw_send_hdrinc(struct sock * iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); } + skb->nfvnet = VNET_UNTAGGED; + skb->nfxid = current->xid; + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); if (err > 0) @@ -742,7 +768,8 @@ static struct sock *raw_get_first(struct struct hlist_node *node; sk_for_each(sk, node, &raw_v4_htable[state->bucket]) - if (sk->sk_family == PF_INET) + if (sk->sk_family == PF_INET && + vx_check(sk->sk_xid, VX_WATCH|VX_IDENT)) goto found; } sk = NULL; @@ -758,7 +785,8 @@ static struct sock *raw_get_next(struct sk = sk_next(sk); try_again: ; - } while (sk && sk->sk_family != PF_INET); + } while (sk && (sk->sk_family != PF_INET || + !vx_check(sk->sk_xid, VX_WATCH|VX_IDENT))); if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) { sk = sk_head(&raw_v4_htable[state->bucket]); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/tcp_ipv4_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/tcp_ipv4_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/tcp_ipv4_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/tcp_ipv4_ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -74,6 +74,7 @@ #include #include #include +#include extern int sysctl_ip_dynaddr; int sysctl_tcp_tw_reuse; @@ -188,6 +189,7 @@ static inline int tcp_bind_conflict(stru sk_for_each_bound(sk2, node, &tb->owners) { if (sk != sk2 && + (sk->sk_xid == sk2->sk_xid) && !tcp_v6_ipv6only(sk2) && (!sk->sk_bound_dev_if || !sk2->sk_bound_dev_if || @@ -412,7 +414,7 @@ void tcp_unhash(struct sock *sk) * during the search since they can never be otherwise. */ static struct sock *__tcp_v4_lookup_listener(struct hlist_head *head, u32 daddr, - unsigned short hnum, int dif) + unsigned short hnum, int dif, nfxid_t nfxid) { struct sock *result = NULL, *sk; struct hlist_node *node; @@ -422,6 +424,8 @@ static struct sock *__tcp_v4_lookup_list sk_for_each(sk, node, head) { struct inet_opt *inet = inet_sk(sk); + if (!vx_sk_check(sk, nfxid)) + continue; if (inet->num == hnum && !ipv6_only_sock(sk)) { __u32 rcv_saddr = inet->rcv_saddr; @@ -449,7 +453,7 @@ static struct sock *__tcp_v4_lookup_list /* Optimize the common listener case. */ static inline struct sock *tcp_v4_lookup_listener(u32 daddr, - unsigned short hnum, int dif) + unsigned short hnum, int dif, nfxid_t nfxid) { struct sock *sk = NULL; struct hlist_head *head; @@ -459,12 +463,15 @@ static inline struct sock *tcp_v4_lookup if (!hlist_empty(head)) { struct inet_opt *inet = inet_sk((sk = __sk_head(head))); + if (!vx_sk_check(sk, nfxid)) + goto no_sherry; if (inet->num == hnum && !sk->sk_node.next && (!inet->rcv_saddr || inet->rcv_saddr == daddr) && (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && !sk->sk_bound_dev_if) goto sherry_cache; - sk = __tcp_v4_lookup_listener(head, daddr, hnum, dif); + no_sherry: + sk = __tcp_v4_lookup_listener(head, daddr, hnum, dif, nfxid); } if (sk) { sherry_cache: @@ -482,7 +489,7 @@ sherry_cache: static inline struct sock *__tcp_v4_lookup_established(u32 saddr, u16 sport, u32 daddr, u16 hnum, - int dif) + int dif, nfxid_t nfxid) { struct tcp_ehash_bucket *head; TCP_V4_ADDR_COOKIE(acookie, saddr, daddr) @@ -496,12 +503,16 @@ static inline struct sock *__tcp_v4_look head = &tcp_ehash[hash]; read_lock(&head->lock); sk_for_each(sk, node, &head->chain) { + if (!vx_sk_check(sk, nfxid)) + continue; if (TCP_IPV4_MATCH(sk, acookie, saddr, daddr, ports, dif)) goto hit; /* You sunk my battleship! */ } /* Must check for a TIME_WAIT'er before going to listener hash. */ sk_for_each(sk, node, &(head + tcp_ehash_size)->chain) { + if (!vx_sk_check(sk, nfxid)) + continue; if (TCP_IPV4_TW_MATCH(sk, acookie, saddr, daddr, ports, dif)) goto hit; } @@ -515,21 +526,23 @@ hit: } static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport, - u32 daddr, u16 hnum, int dif) + u32 daddr, u16 hnum, + int dif, nfxid_t nfxid) { struct sock *sk = __tcp_v4_lookup_established(saddr, sport, - daddr, hnum, dif); + daddr, hnum, + dif, nfxid); - return sk ? : tcp_v4_lookup_listener(daddr, hnum, dif); + return sk ? : tcp_v4_lookup_listener(daddr, hnum, dif, nfxid); } inline struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, - u16 dport, int dif) + u16 dport, int dif, nfxid_t nfxid) { struct sock *sk; local_bh_disable(); - sk = __tcp_v4_lookup(saddr, sport, daddr, ntohs(dport), dif); + sk = __tcp_v4_lookup(saddr, sport, daddr, ntohs(dport), dif, nfxid); local_bh_enable(); return sk; @@ -567,6 +580,8 @@ static int __tcp_v4_check_established(st sk_for_each(sk2, node, &(head + tcp_ehash_size)->chain) { tw = (struct tcp_tw_bucket *)sk2; + if (!vx_sk_check(sk, vx_sk_xid(sk2))) + continue; if (TCP_IPV4_TW_MATCH(sk2, acookie, saddr, daddr, ports, dif)) { struct tcp_opt *tp = tcp_sk(sk); @@ -603,6 +618,8 @@ static int __tcp_v4_check_established(st /* And established part... */ sk_for_each(sk2, node, &head->chain) { + if (!vx_sk_check(sk, vx_sk_xid(sk2))) + continue; if (TCP_IPV4_MATCH(sk2, acookie, saddr, daddr, ports, dif)) goto not_unique; } @@ -1005,7 +1022,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 } sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, - th->source, tcp_v4_iif(skb)); + th->source, tcp_v4_iif(skb), skb->nfxid); if (!sk) { ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); return; @@ -1623,11 +1640,9 @@ static struct sock *tcp_v4_hnd_req(struc if (req) return tcp_check_req(sk, skb, req, prev); - nsk = __tcp_v4_lookup_established(skb->nh.iph->saddr, - th->source, - skb->nh.iph->daddr, - ntohs(th->dest), - tcp_v4_iif(skb)); + nsk = __tcp_v4_lookup_established(skb->nh.iph->saddr, th->source, + skb->nh.iph->daddr, ntohs(th->dest), + tcp_v4_iif(skb), skb->nfxid); if (nsk) { if (nsk->sk_state != TCP_TIME_WAIT) { @@ -1772,7 +1787,7 @@ int tcp_v4_rcv(struct sk_buff *skb) sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source, skb->nh.iph->daddr, ntohs(th->dest), - tcp_v4_iif(skb)); + tcp_v4_iif(skb), skb->nfxid); if (!sk) goto no_tcp_socket; @@ -1837,8 +1852,7 @@ do_time_wait: skb, th, skb->len)) { case TCP_TW_SYN: { struct sock *sk2 = tcp_v4_lookup_listener(skb->nh.iph->daddr, - ntohs(th->dest), - tcp_v4_iif(skb)); + ntohs(th->dest), tcp_v4_iif(skb), skb->nfxid); if (sk2) { tcp_tw_deschedule((struct tcp_tw_bucket *)sk); tcp_tw_put((struct tcp_tw_bucket *)sk); @@ -2187,6 +2201,10 @@ get_req: } get_sk: sk_for_each_from(sk, node) { + vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)", + sk, sk->sk_xid, current->xid); + if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) + continue; if (sk->sk_family == st->family) { cur = sk; goto out; @@ -2235,18 +2253,26 @@ static void *established_get_first(struc read_lock(&tcp_ehash[st->bucket].lock); sk_for_each(sk, node, &tcp_ehash[st->bucket].chain) { - if (sk->sk_family != st->family) { + vxdprintk(VXD_CBIT(net, 6), + "sk,egf: %p [#%d] (from %d)", + sk, sk->sk_xid, current->xid); + if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) + continue; + if (sk->sk_family != st->family) continue; - } rc = sk; goto out; } st->state = TCP_SEQ_STATE_TIME_WAIT; tw_for_each(tw, node, &tcp_ehash[st->bucket + tcp_ehash_size].chain) { - if (tw->tw_family != st->family) { + vxdprintk(VXD_CBIT(net, 6), + "tw: %p [#%d] (from %d)", + tw, tw->tw_xid, current->xid); + if (!vx_check(tw->tw_xid, VX_IDENT|VX_WATCH)) + continue; + if (tw->tw_family != st->family) continue; - } rc = tw; goto out; } @@ -2270,7 +2296,8 @@ static void *established_get_next(struct tw = cur; tw = tw_next(tw); get_tw: - while (tw && tw->tw_family != st->family) { + while (tw && (tw->tw_family != st->family || + !vx_check(tw->tw_xid, VX_IDENT|VX_WATCH))) { tw = tw_next(tw); } if (tw) { @@ -2290,6 +2317,11 @@ get_tw: sk = sk_next(sk); sk_for_each_from(sk, node) { + vxdprintk(VXD_CBIT(net, 6), + "sk,egn: %p [#%d] (from %d)", + sk, sk->sk_xid, current->xid); + if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) + continue; if (sk->sk_family == st->family) goto found; } diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/udp_ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/udp_ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/udp_ngnet.c 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/udp_ngnet.c 2004-12-10 22:53:33.000000000 +0100 @@ -216,10 +216,22 @@ static void udp_v4_unhash(struct sock *s write_unlock_bh(&udp_hash_lock); } +static inline int udp_in_list(struct nx_info *nx_info, u32 addr) +{ + int n = nx_info->nbipv4; + int i; + + for (i=0; iipv4[i] == addr) + return 1; + return 0; +} + /* UDP is nearly always wildcards out the wazoo, it makes no sense to try * harder than this. -DaveM */ -struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif) +struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, + int dif, unsigned long nfxid) { struct sock *sk, *result = NULL; struct hlist_node *node; @@ -229,6 +241,8 @@ struct sock *udp_v4_lookup_longway(u32 s sk_for_each(sk, node, &udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]) { struct inet_opt *inet = inet_sk(sk); + if (!vx_sk_check(sk, nfxid)) + continue; if (inet->num == hnum && !ipv6_only_sock(sk)) { int score = (sk->sk_family == PF_INET ? 1 : 0); if (inet->rcv_saddr) { @@ -263,12 +277,13 @@ struct sock *udp_v4_lookup_longway(u32 s return result; } -__inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif) +__inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, + int dif, unsigned long nfxid) { struct sock *sk; read_lock(&udp_hash_lock); - sk = udp_v4_lookup_longway(saddr, sport, daddr, dport, dif); + sk = udp_v4_lookup_longway(saddr, sport, daddr, dport, dif, nfxid); if (sk) sock_hold(sk); read_unlock(&udp_hash_lock); @@ -325,7 +340,8 @@ void udp_err(struct sk_buff *skb, u32 in int harderr; int err; - sk = udp_v4_lookup(iph->daddr, uh->dest, iph->saddr, uh->source, skb->dev->ifindex); + sk = udp_v4_lookup(iph->daddr, uh->dest, iph->saddr, uh->source, + skb->dev->ifindex, skb->nfxid); if (sk == NULL) { ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); return; /* No socket for error */ @@ -1143,7 +1160,8 @@ int udp_rcv(struct sk_buff *skb) if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) return udp_v4_mcast_deliver(skb, uh, saddr, daddr); - sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex); + sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, + skb->dev->ifindex, skb->nfxid); if (sk != NULL) { int ret = udp_queue_rcv_skb(sk, skb); @@ -1380,8 +1398,10 @@ static struct sock *udp_get_first(struct for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { struct hlist_node *node; + sk_for_each(sk, node, &udp_hash[state->bucket]) { - if (sk->sk_family == state->family) + if (sk->sk_family == state->family && + vx_check(sk->sk_xid, VX_WATCH|VX_IDENT)) goto found; } } @@ -1398,7 +1418,8 @@ static struct sock *udp_get_next(struct sk = sk_next(sk); try_again: ; - } while (sk && sk->sk_family != state->family); + } while (sk && (sk->sk_family != state->family || + !vx_check(sk->sk_xid, VX_WATCH|VX_IDENT))); if (!sk && ++state->bucket < UDP_HTABLE_SIZE) { sk = sk_head(&udp_hash[state->bucket]); ; ; additions and simple stuff ... ; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/Makefile linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/Makefile --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/Makefile 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/Makefile 2004-12-10 22:53:32.000000000 +0100 @@ -5,12 +5,21 @@ obj-y := utils.o route.o inetpeer.o protocol.o \ ip_input.o ip_fragment.o ip_forward.o ip_options.o \ ip_output.o ip_sockglue.o \ - tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \ - datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \ - sysctl_net_ipv4.o fib_frontend.o fib_semantics.o fib_hash.o + tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_minisocks.o \ + datagram.o arp.o devinet.o af_inet.o igmp.o \ + sysctl_net_ipv4.o -obj-$(CONFIG_PROC_FS) += proc.o +ifdef CONFIG_VSERVER_NGNET +obj-y += raw_ngnet.o tcp_ipv4_ngnet.o udp_ngnet.o icmp_ngnet.o \ + fib_frontend_ngnet.o fib_semantics_ngnet.o fib_hash_ngnet.o +obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules_ngnet.o +else +obj-y += raw.o tcp_ipv4.o udp.o icmp.o \ + fib_frontend.o fib_semantics.o fib_hash.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o +endif + +obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_IP_MROUTE) += ipmr.o obj-$(CONFIG_NET_IPIP) += ipip.o obj-$(CONFIG_NET_IPGRE) += ip_gre.o diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/Kconfig linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/Kconfig --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/Kconfig 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/Kconfig 2004-12-10 22:53:32.000000000 +0100 @@ -168,6 +168,16 @@ config IP_NF_MATCH_MARK To compile it as a module, choose M here. If unsure, say N. +config IP_NF_MATCH_VNET + tristate "netfilter VNET match support" + depends on IP_NF_IPTABLES && VSERVER_NGNET + help + Netfilter vnet matching allows you to match packets based on the + `nfvnet' value in the packet. This can be set by the VNET target + (see below). + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_MULTIPORT tristate "Multiple port match support" depends on IP_NF_IPTABLES @@ -559,6 +569,26 @@ config IP_NF_NAT_AMANDA default IP_NF_NAT if IP_NF_AMANDA=y default m if IP_NF_AMANDA=m +# vnet + specific targets +config IP_NF_VNET + tristate "Packet virtualization" + depends on IP_NF_IPTABLES && VSERVER_NGNET + help + This option adds a `vnet' table to iptables: see the man page for + iptables(8). This table is used for packet virtualization. + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_TARGET_VNET + tristate "VNET target support" + depends on IP_NF_VNET + help + This option adds a `VNET' target, which allows you to create rules + in the `mangle' table which alter the netfilter vnet (nfvnet) field + associated with the packet prior to routing. + + To compile it as a module, choose M here. If unsure, say N. + # mangle + specific targets config IP_NF_MANGLE tristate "Packet mangling" diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/Makefile linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/Makefile --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/Makefile 2004-12-04 03:28:16.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/Makefile 2004-12-10 22:53:32.000000000 +0100 @@ -40,6 +40,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_table # the three instances of ip_tables obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o +obj-$(CONFIG_IP_NF_VNET) += iptable_vnet.o obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o @@ -49,6 +50,7 @@ obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_l obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o +obj-$(CONFIG_IP_NF_MATCH_VNET) += ipt_vnet.o obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o @@ -76,6 +78,7 @@ obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TO obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o +obj-$(CONFIG_IP_NF_TARGET_VNET) += ipt_VNET.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/Documentation/vserver/debug.txt linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/Documentation/vserver/debug.txt --- linux-2.6.10-rc3-vs1.9.3.11-ng0/Documentation/vserver/debug.txt 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/Documentation/vserver/debug.txt 2004-12-10 22:53:32.000000000 +0100 @@ -157,6 +157,33 @@ debug_net: "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d" +debug_net(ngn): + + + 0 1 + + 1 2 "vnet_target(%d,#%u) [%d]" + + 2 4 "loopback_xmit(%p) [%p,#%d]" + "dev_queue_xmit(%p) [%p,#%d]" + + 3 8 "netif_rx(%p,#%d) [%p,#%d]" + "netif_receive_skb(%p,#%d) [%p,#%d]" + + 4 16 "ip_route_connect(%p) %p,%p;%lx" + + 5 32 "vnet_open(%p{%s}) [%p,%s]" + "vnet_close(%p{%s}) [%p,%s]" + "vnet_start_xmit(%p[#%ld],%p{%s})" + + 6 64 "sk: %p [#%d] (from %d)" + "sk,req: %p [#%d] (from %d)" + "sk,egf: %p [#%d] (from %d)" + "sk,egn: %p [#%d] (from %d)" + "tw: %p [#%d] (from %d)" + + 7 128 "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d" + "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d" debug_limit: diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/Kconfig linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/Kconfig --- linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/Kconfig 2004-12-04 03:28:06.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/Kconfig 2004-12-10 22:53:32.000000000 +0100 @@ -104,6 +104,12 @@ config TUN If you don't know what to use this for, you don't need it. +config VNET + tristate "Virtual Network device driver support" + depends on NETDEVICES && VSERVER_NGNET + ---help--- + VNET provides packet reception and transmission + config ETHERTAP tristate "Ethertap network tap" depends on NETDEVICES && EXPERIMENTAL && NETLINK_DEV diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/Makefile linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/Makefile --- linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/Makefile 2004-12-04 03:28:06.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/Makefile 2004-12-10 22:53:32.000000000 +0100 @@ -175,6 +175,7 @@ obj-$(CONFIG_MACSONIC) += macsonic.o obj-$(CONFIG_MACMACE) += macmace.o obj-$(CONFIG_MAC89x0) += mac89x0.o obj-$(CONFIG_TUN) += tun.o +obj-$(CONFIG_VNET) += vnet.o obj-$(CONFIG_DL2K) += dl2k.o obj-$(CONFIG_R8169) += r8169.o obj-$(CONFIG_AMD8111_ETH) += amd8111e.o diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/vnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/vnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/drivers/net/vnet.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/drivers/net/vnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,589 @@ + +/* + * linux/drivers/net/vnet.c + * + * Written by Herbert Pötzl, 22/08/2004 + * + * based on the shaper.c code by Alan Cox. + * + * Copyright 2004 by Herbert Pötzl. + * Redistribution of this file is permitted under the + * GNU General Public License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include /* remove asap!! */ + +#include +#include + + +LIST_HEAD(vnets); + +DECLARE_RWSEM(vnets_rwsem); + +static struct hlist_head vnet_head[1 << VNET_HASHBITS]; + +static rwlock_t vnet_lock = RW_LOCK_UNLOCKED; + + +/* + * Transmit from a vnet + */ + +static void vnet_real_xmit(struct vnet *vn, struct sk_buff *skb) +{ + struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); + struct net_device *dev = vn->dev; + + vxdprintk(VXD_CBIT(net, 1), + "vnet_real_xmit(%p) [%d,#%u]", + skb, skb->nfvnet, skb->nfxid); + + /* FIXME is clone really necessary here? */ + if(newskb) { + newskb->dev = dev; + newskb->priority = 2; + + dev_queue_xmit(newskb); + + vn->stats.tx_bytes += skb->len; + vn->stats.tx_packets++; + + dev_kfree_skb(skb); + } +} + +static void vnet_vnet_xmit(struct vnet *vn, struct sk_buff *skb, int vnet) +{ + struct net_device *vndev; + struct vnet *dvn = vnet_get(vnet); + + if (!dvn) { + dev_kfree_skb(skb); + return; + } + + skb_orphan(skb); + vndev = dvn->vndev; + + skb->protocol = eth_type_trans(skb, vndev); + skb->dev = vndev; + + vxdprintk(VXD_CBIT(net, 1), + "vnet_vnet_xmit(%p) [%d,#%u]->[%d]", + skb, skb->nfvnet, skb->nfxid, vnet); + + /* auto tag vnet input */ + skb->nfvnet = vnet; + skb->nfxid = dvn->nfxid; + // skb->nfvnet = 0; + // skb->nfxid = 0; + +#ifndef LOOPBACK_MUST_CHECKSUM + skb->ip_summed = CHECKSUM_UNNECESSARY; +#endif + vndev->last_rx = jiffies; + + vn->stats.tx_bytes += skb->len; + vn->stats.tx_packets++; + + dvn->stats.rx_bytes += skb->len; + dvn->stats.rx_packets++; + + vnet_put(dvn); + netif_rx(skb); +} + +static void vnet_loopback_xmit(struct vnet *vn, struct sk_buff *skb) +{ + struct net_device *vndev = vn->vndev; + + skb_orphan(skb); + + skb->protocol = eth_type_trans(skb, vndev); + skb->dev = vndev; + + /* auto tag loopback input */ + skb->nfvnet = vn->vnet; + + vxdprintk(VXD_CBIT(net, 1), + "vnet_loopback_xmit(%p) [%d,#%u]", + skb, skb->nfvnet, skb->nfxid); +#ifndef LOOPBACK_MUST_CHECKSUM + skb->ip_summed = CHECKSUM_UNNECESSARY; +#endif + vndev->last_rx = jiffies; + + vn->stats.rx_bytes += skb->len; + vn->stats.rx_packets++; + vn->stats.tx_bytes += skb->len; + vn->stats.tx_packets++; + + netif_rx(skb); +} + + + +/* + * Bring the interface up. We just disallow this until a + * bind. + */ + +static int vnet_open(struct net_device *vndev) +{ + struct vnet *vn = vndev->priv; + struct net_device *dev = vn->dev; + + vxdprintk(VXD_CBIT(net, 5), + "vnet_open(%p{%s}) [%p,%s]", + vndev, vndev->name, dev, dev?dev->name:NULL); + + if (!dev) + return -ENODEV; + return 0; +} + +/* + * Closing a vnet flushes the queues. + */ + +static int vnet_close(struct net_device *vndev) +{ + struct vnet *vn = vndev->priv; + struct net_device *dev = vn->dev; + + vxdprintk(VXD_CBIT(net, 5), + "vnet_close(%p{%s}) [%p,%s]", + vndev, vndev->name, dev, dev?dev->name:NULL); + return 0; +} + +static int vnet_start_xmit(struct sk_buff *skb, struct net_device *vndev) +{ + struct vnet *vn = vndev->priv; + + vxdprintk(VXD_CBIT(net, 5), + "vnet_start_xmit(%p[%d,#%d],%p{%s})", + skb, skb->nfvnet, skb->nfxid, vndev, vndev->name); + + if (skb->nfxid != vn->nfxid) { + vxwprintk(1, "packet from #%d on vnet %d:#%d", + skb->nfxid, vn->vnet, vn->nfxid); + goto drop; + } + + /* send packet via loopback */ + if (vndev->flags & IFF_LOOPBACK) { + vnet_loopback_xmit(vn, skb); + return 0; + } + + /* drop packet on vnet mismatch */ + if (skb->nfvnet && skb->nfvnet != vn->vnet) + goto drop; + + /* + if (skb->nh.iph->daddr == 0x0300a8c0) { + vnet_vnet_xmit(vn, skb, 21); + return 0; + } + */ + + /* send packet via real device */ + vnet_real_xmit(vn, skb); + return 0; + +drop: + dev_kfree_skb(skb); + vn->stats.tx_carrier_errors++; + return 0; +} + +static struct net_device_stats *vnet_get_stats(struct net_device *vndev) +{ + struct vnet *vn = vndev->priv; + + return &vn->stats; +} + + + +static int vnet_header(struct sk_buff *skb, struct net_device *vndev, + unsigned short type, void *daddr, void *saddr, unsigned len) +{ + struct vnet *vn = vndev->priv; + struct net_device *dev = vn->dev; + int v; + + skb->dev = dev; + v = dev->hard_header(skb, dev, type, daddr, saddr, len); + skb->dev = vndev; + return v; +} + +static int vnet_rebuild_header(struct sk_buff *skb) +{ + struct vnet *vn = skb->dev->priv; + struct net_device *dev = vn->dev; + struct net_device *vndev = skb->dev; + int v; + + skb->dev = dev; + v = dev->rebuild_header(skb); + skb->dev = vndev; + return v; +} + +#ifdef CONFIG_INET + +static int vnet_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 vnet_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) +{ + if (p->tbl->family == AF_INET) { + p->neigh_setup = vnet_neigh_setup; + p->ucast_probes = 0; + p->mcast_probes = 0; + } + return 0; +} + +#else /* !(CONFIG_INET) */ + +static int vnet_neigh_setup_dev(struct net_device *vndev, struct neigh_parms *p) +{ + return 0; +} + +#endif + +static int vnet_set_address(struct net_device *vndev, void *p) +{ + struct sockaddr *sa = p; + + if (!is_valid_ether_addr(sa->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(vndev->dev_addr, sa->sa_data, ETH_ALEN); + return 0; +} + + +#if 0 +static int vnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct vnetconf *vc= (struct vnetconf *)&ifr->ifr_ifru; + struct vnet *vn = dev->priv; + + if(vc->vc_cmd == VNET_SET_DEV) + { + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + } + + switch(vc->vc_cmd) + { + case VNET_SET_DEV: + { + struct net_device *them = __dev_get_by_name(vc->vc_name); + if (!them) + return -ENODEV; + if (vn->dev) + return -EBUSY; + return vnet_attach(dev, dev->priv, them); + } + case VNET_GET_DEV: + if (!vn->dev) + return -ENODEV; + strcpy(vc->vc_name, vn->dev->name); + return 0; + default: + return -EINVAL; + } +} +#endif + +static void vnet_init_priv(struct net_device *vndev) +{ + struct vnet *vn = vndev->priv; + + atomic_set(&vn->refcnt, 0); + INIT_HLIST_NODE(&vn->vnet_hlist); + + vn->vndev = vndev; + vn->vnet = ~0; + vn->nfxid = 0; +} + +/* + * Add a vnet device to the system + */ + +static void vnet_setup(struct net_device *vndev) +{ + vnet_init_priv(vndev); + + vndev->open = vnet_open; + vndev->stop = vnet_close; + vndev->hard_start_xmit = vnet_start_xmit; + vndev->get_stats = vnet_get_stats; + vndev->set_mac_address = vnet_set_address; + vndev->set_multicast_list = NULL; + + /* + * Handlers for when we attach to a device. + */ + + vndev->hard_header = vnet_header; + vndev->rebuild_header = vnet_rebuild_header; + + // vndev->neigh_setup = vnet_neigh_setup_dev; + // dev->do_ioctl = vnet_ioctl; + vndev->hard_header_len = 0; + vndev->type = ARPHRD_ETHER; /* initially */ + vndev->mtu = 1500; + vndev->addr_len = 0; + vndev->tx_queue_len = 10; + vndev->flags = 0; + vndev->priv_flags = IFF_VNET; + +} + + +struct net_device *vnet_create_dev(const char *name, nfxid_t nfxid) +{ + struct net_device *vndev; + + vndev = alloc_netdev(sizeof(struct vnet), name, vnet_setup); + if (!vndev) + goto out; + + vndev->nfxid = nfxid; + if (register_netdev(vndev)) { + free_netdev(vndev); + vndev = NULL; + } else { + struct vnet *vn = vndev->priv; + + down_write(&vnets_rwsem); + list_add_tail(&vn->vnet_list, &vnets); + up_write(&vnets_rwsem); + } +out: + /* auto free vndev */ + dev_put(vndev); + return vndev; +} + +void vnet_destroy_dev(struct net_device *vndev) +{ + struct vnet *vn = vndev->priv; + + down_write(&vnets_rwsem); + list_del(&vn->vnet_list); + up_write(&vnets_rwsem); + + rtnl_lock(); + /* give up reference to real dev */ + dev_put(vn->dev); + // dev_change_flags(vndev, vndev->flags & ~IFF_UP); + // dev_close(vndev); + + /* unregister vndev */ + unregister_netdevice(vndev); + rtnl_unlock(); + + free_netdev(vndev); +} + + +int vnet_attach_dev(struct net_device *vndev, struct net_device *dev) +{ + struct vnet *vn = vndev->priv; + + vn->dev = dev; + + if (dev->hard_header) + vndev->hard_header = vnet_header; + else + vndev->hard_header = NULL; + + if (dev->rebuild_header) + vndev->rebuild_header = vnet_rebuild_header; + else + vndev->rebuild_header = NULL; + + vndev->header_cache_update = NULL; + vndev->hard_header_cache = NULL; + + vndev->neigh_setup = vnet_neigh_setup_dev; + + vndev->hard_header_len = dev->hard_header_len; + vndev->type = dev->type; + vndev->addr_len = dev->addr_len; + memcpy(vndev->dev_addr, dev->dev_addr, dev->addr_len); + vndev->mtu = dev->mtu; + vndev->flags |= (dev->flags & + (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST)); + return 0; +} + +int vnet_config(struct net_device *vndev, int vnet, nfxid_t nfxid) +{ + struct vnet *vn = vndev->priv; + struct hlist_head *hash = &vnet_head[vnet & + ((1 << VNET_HASHBITS)-1)]; + + if (~vn->vnet) + hlist_del_init(&vn->vnet_hlist); + vn->vnet = vnet; + vn->nfxid = nfxid; + + hlist_add_head_rcu(&vn->vnet_hlist, hash); + return 0; +} + + +/* locate vnet devices */ + + +struct vnet *__vnet_get(struct hlist_head *hash, int vnet) +{ + struct hlist_node *p; + + hlist_for_each(p, hash) { + struct vnet *vn + = hlist_entry(p, struct vnet, vnet_hlist); + if (vn->vnet == vnet) + return vn; + } + return NULL; +} + +struct vnet *vnet_get(int vnet) +{ + struct vnet *vn; + struct hlist_head *hash = &vnet_head[vnet & + ((1 << VNET_HASHBITS)-1)]; + + read_lock(&vnet_lock); + vn = __vnet_get(hash, vnet); + if (vn) + atomic_inc(&vn->refcnt); + read_unlock(&vnet_lock); + return vn; +} + +xid_t vnet_get_xid(struct net_device *vndev) +{ + struct vnet *vn = vndev->priv; + + return vn->nfxid; +} + + +#ifdef CONFIG_PROC_FS + +static void *vnet_seq_start(struct seq_file *s, loff_t *pos) +{ + struct list_head *p; + loff_t l = *pos; + + down_read(&vnets_rwsem); + list_for_each(p, &vnets) + if (!l--) + return list_entry(p, struct vnet, vnet_list); + return NULL; +} + +static void *vnet_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + struct list_head *p = ((struct vnet *)v)->vnet_list.next; + + ++*pos; + return p==&vnets ? NULL : + list_entry(p, struct vnet, vnet_list); +} + +static void vnet_seq_stop(struct seq_file *s, void *v) +{ + up_read(&vnets_rwsem); +} + +static int vnet_seq_show(struct seq_file *s, void *v) +{ + struct vnet *vn = v; + struct net_device *dev = vn->dev; + struct net_device *vndev = vn->vndev; + + if (&vn->vnet_list == vnets.next) + seq_puts(s, "#vnet\t#xid\treal\tvnet dev\n"); + + seq_printf(s, "%5d\t%5d\t%s\t%s\t%04x %d\n", + vn->vnet, vn->nfxid, dev->name, + vndev->name, vndev->flags, + atomic_read(&vndev->refcnt)); + return 0; +} + +static struct seq_operations vnet_seq_op = { + .start = vnet_seq_start, + .next = vnet_seq_next, + .stop = vnet_seq_stop, + .show = vnet_seq_show, +}; + +static int vnet_proc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &vnet_seq_op); +} +static struct file_operations proc_vnet_operations = { + .open = vnet_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + + +#endif + +static int __init vnet_init_module(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_entry("vnet", 0, NULL); + if (entry) + entry->proc_fops = &proc_vnet_operations; + return 0; +} + +module_init(vnet_init_module); +// module_exit(dummy_cleanup_module); + + +MODULE_LICENSE("GPL"); + diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/if_vnet.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/if_vnet.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/if_vnet.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/if_vnet.h 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,44 @@ +#ifndef __LINUX_VNET_H +#define __LINUX_VNET_H + +#ifdef __KERNEL__ + +#define VNET_HASHBITS 8 + +struct vnet +{ + struct hlist_node vnet_hlist; + struct list_head vnet_list; + atomic_t refcnt; + + struct net_device *dev; + struct net_device *vndev; + struct net_device_stats stats; + + uint16_t vnet; + nfxid_t nfxid; +}; + +#define VNET_UNTAGGED ((uint16_t)~0) + +struct vnet *vnet_get(int vnet); + +static inline void vnet_put(struct vnet *vn) +{ + if (vn) + atomic_dec(&vn->refcnt); +} + +int vnet_attach_dev(struct net_device *vndev, struct net_device *dev); + +int vnet_config(struct net_device *vndev, int vnet, nfxid_t nfxid); + +struct net_device *vnet_create_dev(const char *name, nfxid_t nfxid); + +void vnet_destroy_dev(struct net_device *dev); + +xid_t vnet_get_xid(struct net_device *dev); + +#endif + +#endif /* __LINUX_VNET_H */ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netfilter_ipv4/ipt_VNET.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netfilter_ipv4/ipt_VNET.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netfilter_ipv4/ipt_VNET.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netfilter_ipv4/ipt_VNET.h 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,8 @@ +#ifndef _IPT_VNET_H_target +#define _IPT_VNET_H_target + +struct ipt_vnet_target_info { + uint16_t vnet; +}; + +#endif /*_IPT_VNET_H_target*/ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netfilter_ipv4/ipt_vnet.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netfilter_ipv4/ipt_vnet.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netfilter_ipv4/ipt_vnet.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netfilter_ipv4/ipt_vnet.h 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,9 @@ +#ifndef _IPT_VNET_H +#define _IPT_VNET_H + +struct ipt_vnet_info { + uint16_t vnet; + uint16_t flags; +}; + +#endif /*_IPT_VNET_H*/ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vs_ngnet.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vs_ngnet.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vs_ngnet.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vs_ngnet.h 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,170 @@ +#ifndef _VX_VS_NGNET_H +#define _VX_VS_NGNET_H + + +#include +#include "vserver/debug.h" + +extern struct fib_table *ip_fib_local_table; +extern struct fib_table *ip_fib_main_table; + + +/* device hashes */ + +#ifdef CONFIG_VSERVER_NGNET + +#define __vx_dev_base_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.dev_base : &dev_base) + +#define __vx_dev_base (*__vx_dev_base_ptr) + +#define __vx_dev_tail_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.dev_tail : &dev_tail) + +#define __vx_dev_tail (*__vx_dev_tail_ptr) + +#define __vx_ifindex_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.ifindex : &ifindex) + +#define __vx_loopback_ptr (current->vx_info ? \ + current->vx_info->ngnet.loopback : &loopback_dev) + +static inline +struct hlist_head *__vx_dev_name_hash(struct hlist_head *head, + unsigned mask, unsigned hash) +{ + struct vx_info *vxi = current->vx_info; + + if (vxi) + return vx_dev_name_hash(vxi, hash); + return &head[hash & mask]; +} + +/* +static inline +struct hlist_head *__vx_dev_index_hash(struct hlist_head *head, + unsigned mask, int ifindex) +{ + struct vx_info *vxi = current->vx_info; + + if (vxi) + return vx_dev_index_hash(vxi, ifindex); + return &head[ifindex & mask]; +} +*/ + + +static inline +struct fib_table *__vx_fib_get_table(int id, nfxid_t nfxid) +{ + struct fib_table *rt; + struct vx_info *vxi = locate_vx_info(nfxid); + +#ifdef CONFIG_IP_MULTIPLE_TABLES + +#else + if (vxi) { + if (id == /* RT_TABLE_LOCAL */255) + rt = vxi->ngnet.fib_local; + else + rt = vxi->ngnet.fib_main; + put_vx_info(vxi); + } else { + if (id == /* RT_TABLE_LOCAL */255) + rt = ip_fib_local_table; + else + rt = ip_fib_main_table; + } +#endif + vxdprintk(VXD_CBIT(net, 1), + "__vx_fib_get_table(%d,#%d) = %p", id, nfxid, rt); + // dump_stack(); + return rt; +} + +#define __vx_fib_main_table(x) __vx_fib_get_table(RT_TABLE_MAIN, x) + +#define __vx_fib_local_table(x) __vx_fib_get_table(RT_TABLE_LOCAL, x) + +#define __vx_fib_info_hash_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.fib_info_hash : &fib_info_hash) + +#define __vx_fib_info_hash (*__vx_fib_info_hash_ptr) + +#define __vx_fib_info_laddrhash_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.fib_info_laddrhash : &fib_info_laddrhash) + +#define __vx_fib_info_laddrhash (*__vx_fib_info_laddrhash_ptr) + +#define __vx_fib_hash_size_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.fib_hash_size : &fib_hash_size) + +#define __vx_fib_hash_size (*__vx_fib_hash_size_ptr) + +#define __vx_fib_info_cnt_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.fib_info_cnt : &fib_info_cnt) + +#define __vx_fib_info_cnt (*__vx_fib_info_cnt_ptr) + +#define __vx_fib_rules_ptr (current->vx_info ? \ + ¤t->vx_info->ngnet.fib_rules : &fib_rules) + +#define __vx_fib_rules (*__vx_fib_rules_ptr) + +#define __vx_local_rule_ptr (current->vx_info ? \ + current->vx_info->ngnet.local_rule : &local_rule) + +#define _NGN_(x) do { x } while (0) + + +#else /* VSERVER_NGNET */ + +#define __vx_dev_base dev_base + +#define __vx_dev_tail_ptr &dev_tail + +#define __vx_ifindex_ptr &ifindex + +#define __vx_loopback_ptr &loopback_dev + +static inline +struct hlist_head *__vx_dev_name_hash(struct hlist_head *head, + unsigned mask, unsigned hash) +{ + return &head[hash & mask]; +} + +static inline +struct hlist_head *__vx_dev_index_hash(struct hlist_head *head, + unsigned mask, int ifindex) +{ + return &head[ifindex & mask]; +} + + +#define __vx_fib_main_table(x) ip_fib_main_table + +#define __vx_fib_local_table(x) ip_fib_local_table + +#define __vx_fib_info_hash fib_info_hash + +#define __vx_fib_info_laddrhash fib_info_laddrhash + +#define __vx_fib_hash_size fib_hash_size + +#define __vx_fib_info_cnt fib_info_cnt + +#define __vx_fib_rules fib_rules + +#define __vx_fib_rules_ptr &fib_rules + +#define __vx_local_rule_ptr &local_rule + +#define _NGN_(x) + + +#endif /* VSERVER_NGNET */ + +#else +#warning duplicate inclusion +#endif diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/ngnet.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/ngnet.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/ngnet.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/ngnet.h 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,20 @@ +#ifndef _VX_NGNET_H +#define _VX_NGNET_H + +#ifdef __KERNEL__ + +struct hlist_head; +struct net_device; +struct vx_info; + +extern struct net_device *vx_dev_base(struct vx_info *); + +extern struct hlist_head *vx_dev_name_hash(struct vx_info *, unsigned); +extern struct hlist_head *vx_dev_index_hash(struct vx_info *, int); + +#define NG_HASHBITS 4 + +#endif /* __KERNEL__ */ +#endif /* _VX_NGNET_H */ + + diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/ngnet_cmd.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/ngnet_cmd.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/ngnet_cmd.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/ngnet_cmd.h 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,37 @@ +#ifndef _VX_NGNET_CMD_H +#define _VX_NGNET_CMD_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +/* ngnet vserver commands */ + +#define VCMD_add_vndev VC_CMD(VNET, 2, 0) +#define VCMD_zap_vnet VC_CMD(VNET, 3, 0) + +struct vcmd_add_vndev_v0 { + uint16_t vnet; + uint16_t flags; + + char name[IFNAMSIZ]; + char real[IFNAMSIZ]; +}; + +struct vcmd_zap_vnet_v0 { + uint16_t vnet; + uint16_t flags; +}; + + +#ifdef __KERNEL__ + +#include + +extern int vc_add_vndev(uint32_t, void __user *); +extern int vc_zap_vnet(uint32_t, void __user *); + +#endif /* __KERNEL__ */ +#endif /* _VX_NGNET_CMD_H */ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/ngnet_def.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/ngnet_def.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/ngnet_def.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/ngnet_def.h 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,84 @@ +/* _VX_NGNET_DEF_H below */ + +#ifdef _VX_INFO_INIT_ + +struct fib_table *fib_hash_init(int id); + +static inline void vx_info_init_ngnet(struct _vx_ngnet *ngnet) +{ + int index; + + ngnet->dev_base = NULL; + ngnet->dev_tail = &ngnet->dev_base; + ngnet->loopback = &loopback_dev; +/* + ngnet->ifindex = 0; + +*/ + for (index=0; index<(1 << NG_HASHBITS); index++) { + INIT_HLIST_HEAD(&ngnet->dev_hash[index].name); + // INIT_HLIST_HEAD(&ngnet->dev_hash[index].index); + } + + ngnet->fib_main = fib_hash_init(RT_TABLE_MAIN); + ngnet->fib_local = fib_hash_init(RT_TABLE_LOCAL); + +} + +extern void vx_vnet_destroy(struct vx_info *, struct net_device *); +extern xid_t vnet_get_xid(struct net_device *); + +static inline void vx_info_exit_ngnet(struct vx_info *vxi, struct _vx_ngnet *ngnet) +{ + int index; + + for (index=0; index<(1 << NG_HASHBITS); index++) { + struct hlist_head *head = &ngnet->dev_hash[index].name; + struct hlist_node *node, *n; + struct net_device *vndev; + + hlist_for_each_entry_safe(vndev, node, n, head, name_hlist) { + printk("unreaped device %p:%s [#%d]\n", + vndev, vndev->name, (vxi)?vxi->vx_id:0); + vx_vnet_destroy(vxi, vndev); + } + } + + fib_table_free(ngnet->fib_main); + fib_table_free(ngnet->fib_local); +} + +#else /* _VX_INFO_INIT_ */ + +#ifndef _VX_NGNET_DEF_H +#define _VX_NGNET_DEF_H + +#include +#include + +#include "ngnet.h" + +/* context sub struct */ + +struct _vx_ngnet { + struct net_device *dev_base; + struct net_device **dev_tail; + struct net_device *loopback; +/* + int ifindex; + +*/ + struct _vx_dev_hash { + struct hlist_head name; +// struct hlist_head index; + } dev_hash[1 << NG_HASHBITS]; + + struct fib_table *fib_main; + struct fib_table *fib_local; + +// struct hlist_head *fib_info_laddrhash; + +}; + +#endif /* _VX_NGNET_DEF_H */ +#endif /* _VX_INFO_INIT_ */ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/Kconfig linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/Kconfig --- linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/Kconfig 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/Kconfig 2004-12-10 22:53:32.000000000 +0100 @@ -83,6 +83,15 @@ config INOXID_RUNTIME endchoice +config VSERVER_NGNET + bool "Enable Next Gen Networking" + depends on EXPERIMENTAL + select VNET + default n + help + This enables iptable marking based next generation + networking. Be prepared to change your vserver setup! + config VSERVER_DEBUG bool "Compile Debugging Code" default n diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/Makefile linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/Makefile --- linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/Makefile 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/Makefile 2004-12-10 22:53:32.000000000 +0100 @@ -10,4 +10,5 @@ vserver-y := switch.o context.o namespac vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o vserver-$(CONFIG_VSERVER_LEGACY) += legacy.o +vserver-$(CONFIG_VSERVER_NGNET) += ngnet.o diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/ngnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/ngnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/ngnet.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/ngnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,180 @@ +/* + * linux/kernel/vserver/limit.c + * + * Virtual Server: Context Limits + * + * Copyright (C) 2004 Herbert Pötzl + * + * V0.01 broken out from vcontext V0.05 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +struct net_device *vx_dev_base(struct vx_info *vxi) +{ + return vxi->ngnet.dev_base; +} + + +struct hlist_head *vx_dev_name_hash(struct vx_info *vxi, unsigned hash) +{ + return &vxi->ngnet.dev_hash[hash & + ((1 << NG_HASHBITS) - 1)].name; +} + +/* +struct hlist_head *vx_dev_index_hash(struct vx_info *vxi, int ifindex) +{ + return &vxi->ngnet.dev_hash[ifindex & + ((1 << NG_HASHBITS) - 1)].index; +} + +*/ + + +/** + * vnet_register_dev - register a vnet device + * @dev: device to register + * + * Take a completed network device structure and add it to the kernel + * interfaces. 0 is returned on success. A negative errno code is + * returned on a failure to set up the device. + * + * Callers must hold the rtnl semaphore. See the comment at the + * end of Space.c for details about the locking. You may want + * register_netdev() instead of this. + * + * BUGS: + * The locking appears insufficient to guarantee two parallel registers + * will not get the same name. + */ + + +struct net_device *vx_vnet_create(struct vx_info *vxi, const char *name) +{ + struct vx_info *old_vxi; + struct net_device *vndev; + xid_t old_xid; + + old_vxi = xchg(¤t->vx_info, vxi); + old_xid = current->xid; + current->xid = vxi->vx_id; + vndev = vnet_create_dev(name, vxi->vx_id); + current->xid = old_xid; + xchg(¤t->vx_info, old_vxi); + return vndev; +} + +void vx_vnet_destroy(struct vx_info *vxi, struct net_device *vndev) +{ + struct vx_info *old_vxi; + xid_t old_xid; + + old_vxi = xchg(¤t->vx_info, vxi); + old_xid = current->xid; + current->xid = vxi->vx_id; + vnet_destroy_dev(vndev); + current->xid = old_xid; + xchg(¤t->vx_info, old_vxi); +} + + + +int vc_add_vndev(uint32_t id, void __user *data) +{ + struct net_device *dev, *vndev; + struct vcmd_add_vndev_v0 vc_data; + struct vx_info *vxi; + int err = -ENODEV; + + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + vxi = locate_vx_info(id); + if (!vxi) + return -ESRCH; + + dev = dev_get_by_name(vc_data.real); + if (!dev) + goto out_put; + + err = -EINVAL; + vndev = vx_vnet_create(vxi, vc_data.name); + if (!vndev) + goto out_dev_put; + + /* attach vnet device to real device */ + err = vnet_attach_dev(vndev, dev); + if (err) + goto cleanup; + + /* configure vnet device properties */ + err = vnet_config(vndev, vc_data.vnet, vxi->vx_id); + if (err) + goto cleanup; + + /* private loopback device ? */ + if (vndev->flags & IFF_LOOPBACK) + vxi->ngnet.loopback = vndev; + + /* everything is fine, keep ref to dev */ + goto out_put; + +cleanup: + vx_vnet_destroy(vxi, vndev); +out_dev_put: + dev_put(dev); +out_put: + put_vx_info(vxi); + return err; +} + +int vc_zap_vnet(uint32_t id, void __user *data) +{ + struct vnet *vn; + struct vcmd_zap_vnet_v0 vc_data; + struct vx_info *vxi; + int err, cnt = 0; + + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + vxi = locate_vx_info(id); + if (!vxi) + return -ESRCH; + + err = -ENODEV; + while ((vn = vnet_get(vc_data.vnet))) { + struct net_device *vndev = vn->vndev; + + /* private loopback device ? */ + if (vndev == vxi->ngnet.loopback) + vxi->ngnet.loopback = &loopback_dev; + + vx_vnet_destroy(vxi, vn->vndev); + vnet_put(vn); + err = ++cnt; + } + + put_vx_info(vxi); + return err; +} + diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/ipt_VNET.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/ipt_VNET.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/ipt_VNET.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/ipt_VNET.c 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,131 @@ +/* This is a module which is used for setting the NFVNET field of an skb. */ + +/* Copyright (C) 2004 Herbert Poetzl + * heavily based on the MARK stuff by Marc Boucher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Herbert Poetzl "); +MODULE_DESCRIPTION("iptables VNET modification module"); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ipt_vnet_target_info *vnetinfo = targinfo; + struct vnet *vn; + + vxdprintk(VXD_CBIT(net, 1), + "vnet_target(%d,#%u) [%d,%d]", + (*pskb)->nfvnet, (*pskb)->nfxid, + vnetinfo->vnet, hooknum); + + switch (hooknum) { + case NF_IP_PRE_ROUTING: + + /* process prestine packets only */ + if ((*pskb)->nfvnet) + return IPT_CONTINUE; + + /* rewrite packet and reinject from vnet */ + if ((vn = vnet_get(vnetinfo->vnet))) { + (*pskb)->nfcache |= NFC_ALTERED; + (*pskb)->dev = vn->vndev; + (*pskb)->real_dev = vn->dev; + (*pskb)->nfxid = vn->nfxid; + (*pskb)->nfvnet = vn->vnet; + + vn->stats.rx_bytes += (*pskb)->len; + vn->stats.rx_packets++; + + vnet_put(vn); + + netif_receive_skb(*pskb); + return NF_STOLEN; + } + + /* unknown vnet */ + return NF_DROP; + + case NF_IP_LOCAL_OUT: + + /* process prestine packets only */ + if ((*pskb)->nfvnet != VNET_UNTAGGED) + return IPT_CONTINUE; + + /* rewrite packet output */ + if ((vn = vnet_get(vnetinfo->vnet))) { + (*pskb)->nfcache |= NFC_ALTERED; + (*pskb)->nfxid = vn->nfxid; + (*pskb)->nfvnet = vn->vnet; + + vnet_put(vn); + + return NF_ACCEPT; + } + + /* unknown vnet */ + return NF_DROP; + } + return IPT_CONTINUE; +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_vnet_target_info))) { + printk(KERN_WARNING "VNET: targinfosize %u != %Zu\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_vnet_target_info))); + return 0; + } + + if (strcmp(tablename, "vnet") != 0) { + printk(KERN_WARNING "VNET: can only be called from \"vnet\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_vnet_reg = { + .name = "VNET", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_target(&ipt_vnet_reg); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_vnet_reg); +} + +module_init(init); +module_exit(fini); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/ipt_vnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/ipt_vnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/ipt_vnet.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/ipt_vnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,65 @@ +/* Kernel module to match NFVNET values. */ + +/* Copyright (C) 2004 Herbert Poetzl + * heavily based on the MARK stuff by Marc Boucher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Herbert Poetzl "); +MODULE_DESCRIPTION("iptables vnet matching module"); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + const struct ipt_vnet_info *info = matchinfo; + + return (skb->nfvnet == info->vnet); +} + +static int +checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IPT_ALIGN(sizeof(struct ipt_vnet_info))) + return 0; + + return 1; +} + +static struct ipt_match vnet_match = { + .name = "vnet", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_match(&vnet_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&vnet_match); +} + +module_init(init); +module_exit(fini); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/iptable_vnet.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/iptable_vnet.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/netfilter/iptable_vnet.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/netfilter/iptable_vnet.c 2004-12-10 22:53:32.000000000 +0100 @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2004 Herbert Poetzl + * + * heavily based on the raw table by + * Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Herbert Poetzl "); +MODULE_DESCRIPTION("iptables vnet table"); + +#define VNET_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) + +/* Standard entry. */ +struct ipt_standard +{ + struct ipt_entry entry; + struct ipt_standard_target target; +}; + +struct ipt_error_target +{ + struct ipt_entry_target target; + char errorname[IPT_FUNCTION_MAXNAMELEN]; +}; + +struct ipt_error +{ + struct ipt_entry entry; + struct ipt_error_target target; +}; + +static struct +{ + struct ipt_replace repl; + struct ipt_standard entries[2]; + struct ipt_error term; +} initial_table __initdata = { + .repl = { + .name = "vnet", + .valid_hooks = VNET_VALID_HOOKS, + .num_entries = 3, + .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), + .hook_entry = { + [NF_IP_PRE_ROUTING] = 0, + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) }, + .underflow = { + [NF_IP_PRE_ROUTING] = 0, + [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) }, + }, + .entries = { + /* PRE_ROUTING */ + { + .entry = { + .target_offset = sizeof(struct ipt_entry), + .next_offset = sizeof(struct ipt_standard), + }, + .target = { + .target = { + .u = { + .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), + }, + }, + .verdict = -NF_ACCEPT - 1, + }, + }, + + /* LOCAL_OUT */ + { + .entry = { + .target_offset = sizeof(struct ipt_entry), + .next_offset = sizeof(struct ipt_standard), + }, + .target = { + .target = { + .u = { + .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), + }, + }, + .verdict = -NF_ACCEPT - 1, + }, + }, + }, + /* ERROR */ + .term = { + .entry = { + .target_offset = sizeof(struct ipt_entry), + .next_offset = sizeof(struct ipt_error), + }, + .target = { + .target = { + .u = { + .user = { + .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)), + .name = IPT_ERROR_TARGET, + }, + }, + }, + .errorname = "ERROR", + }, + } +}; + +static struct ipt_table packet_vnet = { + .name = "vnet", + .table = &initial_table.repl, + .valid_hooks = VNET_VALID_HOOKS, + .lock = RW_LOCK_UNLOCKED, + .me = THIS_MODULE +}; + +/* The work comes in here from netfilter.c. */ +static unsigned int +ipt_route_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ipt_do_table(pskb, hook, in, out, &packet_vnet, NULL); +} + +static unsigned int +ipt_out_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ipt_do_table(pskb, hook, in, out, &packet_vnet, NULL); +} + +/* 'vnet' is the very first table. */ +static struct nf_hook_ops ipt_ops[] = { + { + .hook = ipt_route_hook, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_VNET + }, + { + .hook = ipt_out_hook, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_VNET + }, +}; + +static int __init init(void) +{ + int ret; + + /* Register table */ + ret = ipt_register_table(&packet_vnet); + if (ret < 0) + return ret; + + /* Register hooks */ + ret = nf_register_hook(&ipt_ops[0]); + if (ret < 0) + goto cleanup_table; + + ret = nf_register_hook(&ipt_ops[1]); + if (ret < 0) + goto cleanup_hook0; + + return ret; + + cleanup_hook0: + nf_unregister_hook(&ipt_ops[0]); + cleanup_table: + ipt_unregister_table(&packet_vnet); + + return ret; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&ipt_ops[i]); + + ipt_unregister_table(&packet_vnet); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/if.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/if.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/if.h 2004-08-14 12:55:23.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/if.h 2004-12-10 22:53:32.000000000 +0100 @@ -53,6 +53,8 @@ #define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */ #define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */ +#define IFF_VNET 0x4 /* vnet virtual device */ + #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netfilter_ipv4.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netfilter_ipv4.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/netfilter_ipv4.h 2004-08-14 12:56:00.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/netfilter_ipv4.h 2004-12-10 22:53:32.000000000 +0100 @@ -51,6 +51,7 @@ enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, + NF_IP_PRI_VNET = -600, NF_IP_PRI_CONNTRACK_DEFRAG = -400, NF_IP_PRI_RAW = -300, NF_IP_PRI_SELINUX_FIRST = -225, diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vs_base.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vs_base.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vs_base.h 2004-12-08 20:33:12.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vs_base.h 2004-12-10 22:53:32.000000000 +0100 @@ -3,6 +3,7 @@ #include "vserver/context.h" +#include #define vx_task_xid(t) ((t)->xid) @@ -53,8 +54,6 @@ static inline int __vx_check(xid_t cid, #define vx_mask_mask(v,f,m) (((v) & ~(m)) | ((v) & (f) & (m))) -#define vx_check_bit(v,n) ((v) & (1LL << (n))) - /* context flags */ @@ -99,6 +98,22 @@ static inline int __vx_check(xid_t cid, (current->vx_info->vx_initpid == (n))) +/* ngn socket helper */ + +#ifdef CONFIG_VSERVER_NGNET + +#define VX_SOCK_MODE (VX_IDENT|VX_ADMIN) + +#define vx_sk_xid(s) ((s)?(s)->sk_xid:0) + +#define vx_sk_check(s,m) \ + __vx_check(vx_sk_xid(s), (m), VX_SOCK_MODE) + +#else +#define vx_sk_check(s,m) 1 +#endif + + #else #warning duplicate inclusion #endif diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/context.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/context.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/context.h 2004-12-10 21:11:42.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/context.h 2004-12-10 22:53:32.000000000 +0100 @@ -72,6 +72,7 @@ #include "limit_def.h" #include "sched_def.h" #include "cvirt_def.h" +#include "ngnet_def.h" struct vx_info { struct hlist_node vx_hlist; /* linked list of contexts */ @@ -97,6 +98,7 @@ struct vx_info { struct _vx_sched sched; /* vserver scheduler */ struct _vx_cvirt cvirt; /* virtual/bias stuff */ struct _vx_cacct cacct; /* context accounting */ + struct _vx_ngnet ngnet; /* next gen networking */ char vx_name[65]; /* vserver name */ }; diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/switch.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/switch.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/linux/vserver/switch.h 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/linux/vserver/switch.h 2004-12-10 22:53:32.000000000 +0100 @@ -61,6 +61,7 @@ #define VC_CAT_NETALT 26 #define VC_CAT_NETMIG 27 #define VC_CAT_NETCTRL 28 +#define VC_CAT_NGTEST 29 #define VC_CAT_DLIMIT 36 #define VC_CAT_INODE 38 diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/context.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/context.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/context.c 2004-12-10 21:34:47.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/context.c 2004-12-10 22:53:32.000000000 +0100 @@ -70,7 +78,7 @@ static struct vx_info *__alloc_vx_info(x vx_info_init_sched(&new->sched); vx_info_init_cvirt(&new->cvirt); vx_info_init_cacct(&new->cacct); - + vx_info_init_ngnet(&new->ngnet); new->vx_flags = VXF_STATE_SETUP|VXF_STATE_INIT; new->vx_bcaps = CAP_INIT_EFF_SET; @@ -90,6 +98,8 @@ static void __dealloc_vx_info(struct vx_ vxdprintk(VXD_CBIT(xid, 0), "dealloc_vx_info(%p)", vxi); + vx_info_exit_ngnet(vxi, &vxi->ngnet); + vxi->vx_hlist.next = LIST_POISON1; vxi->vx_id = -1; @@ -147,6 +156,8 @@ void free_vx_info(struct vx_info *vxi) struct namespace *namespace; struct fs_struct *fs; + vs_context_state(VS_CONTEXT_DESTROY); + /* context shutdown is mandatory */ // BUG_ON(vxi->vx_state != VXS_SHUTDOWN); @@ -631,6 +642,7 @@ int vc_ctx_create(uint32_t xid, void __u ret = -EEXIST; goto out_put; } + vs_context_state(VS_CONTEXT_CREATED); ret = new_vxi->vx_id; vx_migrate_task(current, new_vxi); diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/switch.c linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/switch.c --- linux-2.6.10-rc3-vs1.9.3.11-ng0/kernel/vserver/switch.c 2004-12-06 23:36:05.000000000 +0100 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/kernel/vserver/switch.c 2004-12-10 22:53:32.000000000 +0100 @@ -33,6 +33,7 @@ vc_get_version(uint32_t id) #include #include #include +#include #include #include @@ -189,6 +183,13 @@ sys_vserver(uint32_t cmd, uint32_t id, v case VCMD_net_migrate: return vc_net_migrate(id, data); +#ifdef CONFIG_VSERVER_NGNET + case VCMD_add_vndev: + return vc_add_vndev(id, data); + case VCMD_zap_vnet: + return vc_zap_vnet(id, data); +#endif + } return -ENOSYS; } diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/ip_fib.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/ip_fib.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/include/net/ip_fib.h 2004-10-23 05:06:24.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/include/net/ip_fib.h 2004-12-10 22:53:32.000000000 +0100 @@ -17,6 +17,10 @@ #define _NET_IP_FIB_H #include +#ifdef CONFIG_VSERVER_NGNET +#include +#else + #include #include @@ -267,4 +271,5 @@ static inline void fib_res_put(struct fi #endif } +#endif /* CONFIG_VSERVER_NGNET */ #endif /* _NET_FIB_H */ diff -NurpbBP --minimal linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_lookup.h linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_lookup.h --- linux-2.6.10-rc3-vs1.9.3.11-ng0/net/ipv4/fib_lookup.h 2004-10-23 05:06:25.000000000 +0200 +++ linux-2.6.10-rc3-vs1.9.3.11-ng7.2_r/net/ipv4/fib_lookup.h 2004-12-10 22:53:32.000000000 +0100 @@ -5,6 +5,10 @@ #include #include +#ifdef CONFIG_VSERVER_NGNET +#error wrong include +#endif + struct fib_alias { struct list_head fa_list; struct fib_info *fa_info;