diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/drivers/net/Kconfig linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/Kconfig --- linux-2.6.14-vs2.1.0-rc6/drivers/net/Kconfig 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/Kconfig 2005-11-02 16:53:12 +0100 @@ -105,6 +105,13 @@ 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 retransmission similar to the + loopback driver but allows for inter context communication. + config NET_SB1000 tristate "General Instruments Surfboard 1000" depends on PNP diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/drivers/net/Makefile linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/Makefile --- linux-2.6.14-vs2.1.0-rc6/drivers/net/Makefile 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/Makefile 2005-11-02 16:50:06 +0100 @@ -179,6 +179,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 -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/drivers/net/loopback.c linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/loopback.c --- linux-2.6.14-vs2.1.0-rc6/drivers/net/loopback.c 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/loopback.c 2005-11-04 05:40:36 +0100 @@ -69,7 +69,7 @@ static DEFINE_PER_CPU(struct net_device_ */ #ifdef LOOPBACK_TSO -static void emulate_large_send_offload(struct sk_buff *skb) +void emulate_large_send_offload(struct sk_buff *skb) { struct iphdr *iph = skb->nh.iph; struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4)); @@ -131,6 +131,7 @@ static int loopback_xmit(struct sk_buff struct net_device_stats *lb_stats; skb_orphan(skb); + printk("loopback received skb: %p[#%d]\n", skb, skb->nid); skb->protocol = eth_type_trans(skb,dev); skb->dev = dev; diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/drivers/net/vnet.c linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/vnet.c --- linux-2.6.14-vs2.1.0-rc6/drivers/net/vnet.c 1970-01-01 01:00:00 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/vnet.c 2005-11-03 03:26:05 +0100 @@ -0,0 +1,393 @@ +/* + * linux/drivers/net/vnet.c + * + * Written by Herbert Pötzl + * + * based on loopback.c and shaper.c + * + * Copyright (C) 2004-2005 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 +#include +#include +#include +#include +#include +#include /* For the statistics structure. */ +#include /* For ARPHRD_ETHER */ +#include +#include +#include + +#include +#include +#include + +LIST_HEAD(vnets); + +// static struct hlist_head vnet_head[1 << VNET_HASHBITS]; + +static rwlock_t vnet_lock = RW_LOCK_UNLOCKED; + + +// static DEFINE_PER_CPU(struct net_device_stats, vnet_stats); + +#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16) + + +static void vnet_reflect(struct sk_buff *skb) +{ + /* do some work */ + return; +} + + + +/* + * The higher levels take care of making this non-reentrant (it's + * called with bh's disabled). + */ +static int vnet_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct vnet *vn = dev->priv; + struct net_device_stats *stats; + + skb_orphan(skb); + vnet_reflect(skb); + + skb->protocol = eth_type_trans(skb,dev); + skb->dev = dev; +#ifndef LOOPBACK_MUST_CHECKSUM + skb->ip_summed = CHECKSUM_UNNECESSARY; +#endif + +#ifdef LOOPBACK_TSO + if (skb_shinfo(skb)->tso_size) { + BUG_ON(skb->protocol != htons(ETH_P_IP)); + BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); + + emulate_large_send_offload(skb); + return 0; + } +#endif + dev->last_rx = jiffies; + +#if 0 + stats = &per_cpu(vnet_stats, get_cpu()); + stats->rx_bytes += skb->len; + stats->tx_bytes = stats->rx_bytes; + stats->rx_packets++; + stats->tx_packets = stats->rx_packets; + put_cpu(); +#else + stats = &vn->stats; +#endif + + netif_rx(skb); + + return(0); +} + + +static struct net_device_stats *vnet_get_stats(struct net_device *dev) +{ + struct vnet *vn = dev->priv; + struct net_device_stats *stats; + + stats = &vn->stats; +#if 0 + memset(stats, 0, sizeof(struct net_device_stats)); + + for (int i=0; i < NR_CPUS; i++) { + struct net_device_stats *vn_stats; + + if (!cpu_possible(i)) + continue; + lb_stats = &per_cpu(vnet_stats, i); + stats->rx_bytes += vn_stats->rx_bytes; + stats->tx_bytes += vn_stats->tx_bytes; + stats->rx_packets += vn_stats->rx_packets; + stats->tx_packets += vn_stats->tx_packets; + } +#endif + return stats; +} + + +static int vnet_set_address(struct net_device *dev, void *p) +{ + struct sockaddr *sa = p; + + if (!is_valid_ether_addr(sa->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); + return 0; +} + + +static u32 vnet_get_link(struct net_device *dev) +{ + return 1; +} + + + +static struct ethtool_ops vnet_ethtool_ops = { + .get_link = vnet_get_link, + .get_tso = ethtool_op_get_tso, + .set_tso = ethtool_op_set_tso, +}; + + +static void vnet_init_priv(struct net_device *dev) +{ + struct vnet *vn = dev->priv; + + atomic_set(&vn->refcnt, 0); + INIT_LIST_HEAD(&vn->vnet_list); + INIT_HLIST_NODE(&vn->vnet_hlist); + + vn->dev = dev; + vn->vnet = ~0; +// vn->nfxid = 0; +} + + +static void vnet_init_dev(struct net_device *dev) +{ + vnet_init_priv(dev); + +// dev->open +// dev->stop + dev->hard_start_xmit = vnet_xmit; + dev->get_stats = vnet_get_stats; + dev->set_mac_address = vnet_set_address; +// dev->set_multicast_list = NULL; + + dev->hard_header = eth_header; + dev->hard_header_cache = eth_header_cache; + dev->header_cache_update = eth_header_cache_update; + + dev->mtu = 1500; // (16 * 1024) + 20 + 20 + 12; + + dev->type = ARPHRD_LOOPBACK; /* 0x0001*/ + dev->hard_header_len = ETH_HLEN; /* 14 */ + dev->addr_len = ETH_ALEN; /* 6 */ + dev->tx_queue_len = 0; + dev->rebuild_header = eth_rebuild_header; +// dev->flags = IFF_LOOPBACK; +// dev->priv_flags = IFF_VNET; + + dev->features = NETIF_F_SG | NETIF_F_FRAGLIST +#ifdef LOOPBACK_TSO + | NETIF_F_TSO +#endif + | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA + | NETIF_F_LLTX; + + dev->ethtool_ops = &vnet_ethtool_ops; + +} + + + + + + + +struct net_device *vnet_create_dev(const char *name) +{ + struct net_device *dev; + + dev = alloc_netdev(sizeof(struct vnet), name, vnet_init_dev); + + vxdprintk(VXD_CBIT(ngnet, 3), + "vnet_create_dev(%p »%s«)", dev, name); + + if (!dev) + goto out; + + if (register_netdev(dev)) { + free_netdev(dev); + dev = NULL; + } else { + struct vnet *vn = dev->priv; + + write_lock(&vnet_lock); + list_add_tail(&vn->vnet_list, &vnets); + write_unlock(&vnet_lock); + } + +out: + return dev; +} + + +void vnet_destroy_dev(struct net_device *dev) +{ + struct vnet *vn = dev->priv; + + vxdprintk(VXD_CBIT(ngnet, 3), + "vnet_destroy_dev(%p »%s«) [%p,%d]", + dev, dev->name, vn, vn->vnet); + + write_lock(&vnet_lock); + list_del(&vn->vnet_list); + +/* + if (!hlist_unhashed(&vn->vnet_hlist)) + hlist_del(&vn->vnet_hlist); +*/ + write_unlock(&vnet_lock); + + rtnl_lock(); + + /* put real dev if configured */ +// if (vn->dev) +// dev_put(vn->dev); + + /* unregister dev */ + unregister_netdevice(dev); + rtnl_unlock(); + + free_netdev(dev); +} + + + + + +#ifdef CONFIG_PROC_FS + + +static void *vnet_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct list_head *p; + loff_t l = *pos; + + read_lock(&vnet_lock); + + if (!l) + return SEQ_START_TOKEN; + list_for_each(p, &vnets) + if (!l--) + return list_entry(p, struct vnet, vnet_list); + return NULL; +} + +void *vnet_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct list_head *p; + + ++*pos; + if (v == SEQ_START_TOKEN) + return NULL; + + p = ((struct vnet *)v)->vnet_list.next; + return list_entry(p, struct vnet, vnet_list); +} + +void vnet_seq_stop(struct seq_file *seq, void *v) +{ + read_unlock(&vnet_lock); +} + + +static void vnet_seq_show_dev(struct seq_file *seq, + struct net_device *dev, struct vnet *vn) +{ + seq_printf(seq, "%s\n", + dev->name); +} + +static int vnet_seq_show(struct seq_file *seq, void *v) +{ + struct vnet *vn = v; + + if (v == SEQ_START_TOKEN) + seq_puts(seq, "bla|bla|bla\n"); + else + vnet_seq_show_dev(seq, vn->dev, vn); + 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_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &vnet_seq_op); +} + +static struct file_operations vnet_seq_fops = { + .owner = THIS_MODULE, + .open = vnet_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + + +#endif + + + + +/* Setup and register vnet. */ + +static int __init vnet_init_module(void) +{ +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *entry; + + entry = create_proc_entry("vnet", 0, NULL); + if (entry) + entry->proc_fops = &vnet_seq_fops; +#endif + + vnet_create_dev("karli"); + return 0; +}; + + +static void __init vnet_cleanup_module(void) +{ +#ifdef CONFIG_PROC_FS + remove_proc_entry("vnet", NULL); +#endif +} + +module_init(vnet_init_module); +module_exit(vnet_cleanup_module); + + +MODULE_LICENSE("GPL"); + diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/drivers/net/vnet_orig.c linux-2.6.14-vs2.1.0-ngn0.03/drivers/net/vnet_orig.c diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/fs/nfsd/auth.c linux-2.6.14-vs2.1.0-ngn0.03/fs/nfsd/auth.c --- linux-2.6.14-vs2.1.0-rc6/fs/nfsd/auth.c 2005-10-29 03:20:34 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/fs/nfsd/auth.c 2005-11-04 02:13:16 +0100 @@ -51,6 +51,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, else current->fsgid = exp->ex_anon_gid; + /* FIXME: enter/leave? */ current->xid = INOXID_XID(XID_TAG_NFSD, cred->cr_uid, cred->cr_gid, 0); if (!cred->cr_group_info) diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/linux/if_vnet.h linux-2.6.14-vs2.1.0-ngn0.03/include/linux/if_vnet.h --- linux-2.6.14-vs2.1.0-rc6/include/linux/if_vnet.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/linux/if_vnet.h 2005-11-04 01:10:45 +0100 @@ -0,0 +1,36 @@ +#ifndef __LINUX_VNET_H +#define __LINUX_VNET_H + +#ifdef __KERNEL__ + + +extern struct list_head vnets; + + +#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 *remote; /* future: group */ + + struct net_device_stats stats; + + uint16_t vnet; +}; + +#define VNET_UNTAGGED ((uint16_t)~0) + + +struct net_device *vnet_create_dev(const char *name); + +void vnet_destroy_dev(struct net_device *dev); + + +#endif + +#endif /* __LINUX_VNET_H */ diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/linux/netdevice.h linux-2.6.14-vs2.1.0-ngn0.03/include/linux/netdevice.h --- linux-2.6.14-vs2.1.0-rc6/include/linux/netdevice.h 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/linux/netdevice.h 2005-11-04 01:50:38 +0100 @@ -344,8 +344,9 @@ struct net_device unsigned short hard_header_len; /* hardware hdr length */ struct net_device *master; /* Pointer to master device of a group, - * which this device is member of. - */ + * which this device is member of. */ + + nid_t nid; /* network context id */ /* Interface address info. */ unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/linux/skbuff.h linux-2.6.14-vs2.1.0-ngn0.03/include/linux/skbuff.h --- linux-2.6.14-vs2.1.0-rc6/include/linux/skbuff.h 2005-10-28 20:49:56 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/linux/skbuff.h 2005-11-04 04:24:27 +0100 @@ -275,6 +275,7 @@ struct sk_buff { struct nf_bridge_info *nf_bridge; #endif #endif /* CONFIG_NETFILTER */ + nid_t nid; #ifdef CONFIG_NET_SCHED __u16 tc_index; /* traffic control index */ #ifdef CONFIG_NET_CLS_ACT diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/linux/vs_ngnet.h linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vs_ngnet.h --- linux-2.6.14-vs2.1.0-rc6/include/linux/vs_ngnet.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vs_ngnet.h 2005-11-04 04:02:57 +0100 @@ -0,0 +1,53 @@ +#ifndef _VX_VS_NGNET_H +#define _VX_VS_NGNET_H + + +#include +#include "vserver/debug.h" + + +#ifdef CONFIG_VSERVER_NGNET + +#include + +static inline +int ngn_dev_visible(struct net_device *dev, nid_t nid) +{ + if (!dev) + return 1; + if (__nx_check(nid, dev->nid, NX_IDENT|NX_BLEND)) + return 1; + return 0; +} + +static inline +int ngn_ifa_visible(struct in_ifaddr *ifa, nid_t nid) +{ + if (!ifa || !ifa->ifa_dev || !ifa->ifa_dev->dev) + return 0; + return ngn_dev_visible(ifa->ifa_dev->dev, nid); +} + + +#define NGN_DEV_VISIBLE(dev, vxi, nxi) \ + ngn_dev_visible(dev, nxi ? nxi->nx_id : 0) + +#define NGN_IFA_VISIBLE(ifa, vxi, nxi) \ + ngn_ifa_visible(ifa, nxi ? nxi->nx_id : 0) + +#else + +#define NGN_DEV_VISIBLE(dev, vxi, nxi) \ + (vx_info_flags(vxi, VXF_HIDE_NETIF, 0) && \ + !dev_in_nx_info(dev, nxi)) + +#define NGN_IFA_VISIBLE(ifa, vxi, nxi) \ + (vx_info_flags(vxi, VXF_HIDE_NETIF, 0) && \ + !ifa_in_nx_info(ifa, nxi)) + +#endif + + +#else +#warning duplicate inclusion +#endif diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/linux/vserver/debug.h linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vserver/debug.h --- linux-2.6.14-vs2.1.0-rc6/include/linux/vserver/debug.h 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vserver/debug.h 2005-11-03 02:12:42 +0100 @@ -22,6 +22,7 @@ extern unsigned int vx_debug_switch; extern unsigned int vx_debug_xid; extern unsigned int vx_debug_nid; extern unsigned int vx_debug_net; +extern unsigned int vx_debug_ngnet; extern unsigned int vx_debug_limit; extern unsigned int vx_debug_dlim; extern unsigned int vx_debug_quota; @@ -72,6 +73,7 @@ void dump_vx_info_inactive(int); #define vx_debug_xid 0 #define vx_debug_nid 0 #define vx_debug_net 0 +#define vx_debug_ngnet 0 #define vx_debug_limit 0 #define vx_debug_dlim 0 #define vx_debug_cvirt 0 diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/linux/vserver/ngnet_cmd.h linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vserver/ngnet_cmd.h --- linux-2.6.14-vs2.1.0-rc6/include/linux/vserver/ngnet_cmd.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vserver/ngnet_cmd.h 2005-11-04 03:10:46 +0100 @@ -0,0 +1,18 @@ +#ifndef _VX_NGNET_CMD_H +#define _VX_NGNET_CMD_H + + +/* ngnet commands */ + +#define VCMD_ngnet_tagdev VC_CMD(SYSTEST, 1, 0) + +struct vcmd_ngnet_tagdev { + uint32_t ifindex; +}; + +#ifdef __KERNEL__ + +extern int vc_ngnet_tagdev(uint32_t, void __user *); + +#endif /* __KERNEL__ */ +#endif /* _VX_NGNET_CMD_H */ diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/linux/vserver/ngnet_skb.h linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vserver/ngnet_skb.h --- linux-2.6.14-vs2.1.0-rc6/include/linux/vserver/ngnet_skb.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/linux/vserver/ngnet_skb.h 2005-11-04 06:33:09 +0100 @@ -0,0 +1,45 @@ +#ifndef _VX_NGNET_SKB_H +#define _VX_NGNET_SKB_H + +#ifdef __KERNEL__ + +#include + + +#define ngn_tag_sock_skb(sk, skb) \ + __ngn_tag_sock_skb(sk, skb, __FILE__, __LINE__) + +static inline +void __ngn_tag_sock_skb(struct sock *sk, struct sk_buff *skb, + const char *__file, int __line) +{ + printk("ngn_tag_sock_skb(%p[#%d],%p[#%d]) [#%d] @%s:%d\n", + sk, sk ? sk->sk_nid : 0, skb, skb->nid, current->nid, + __file, __line); + skb->nid = sk ? sk->sk_nid : current->nid; +} + +#define vx_tag_netlink_skb(sk, skb) \ + ngn_tag_sock_skb(sk, skb) + +#if 0 + +static inline +void vx_tag_dev_skb(struct net_device *dev, struct sk_buff *skb) +{ + if (dev->priv_flags & IFF_VNET) { + struct vnet *vn = dev->priv; + + skb->nfvnet = vn->vnet; + skb->nfxid = vn->nfxid; + } else { + skb->nfvnet = VNET_UNTAGGED; + skb->nfxid = dev->nfxid; + } +} +#endif + +#endif /* __KERNEL__ */ +#endif /* _VX_NGNET_SKB_H */ + + diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/net/inet_hashtables.h linux-2.6.14-vs2.1.0-ngn0.03/include/net/inet_hashtables.h --- linux-2.6.14-vs2.1.0-rc6/include/net/inet_hashtables.h 2005-10-30 02:16:07 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/net/inet_hashtables.h 2005-11-04 04:54:37 +0100 @@ -315,13 +315,14 @@ static inline int inet_addr_match ( extern struct sock *__inet_lookup_listener(const struct hlist_head *head, const u32 daddr, const unsigned short hnum, - const int dif); + const int dif, nid_t nid); /* Optimize the common listener case. */ static inline struct sock * inet_lookup_listener(struct inet_hashinfo *hashinfo, const u32 daddr, - const unsigned short hnum, const int dif) + const unsigned short hnum, + const int dif, nid_t nid) { struct sock *sk = NULL; const struct hlist_head *head; @@ -332,11 +333,12 @@ static inline struct sock * const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); if (inet->num == hnum && !sk->sk_node.next && + sk->sk_nid == nid && inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) && (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && !sk->sk_bound_dev_if) goto sherry_cache; - sk = __inet_lookup_listener(head, daddr, hnum, dif); + sk = __inet_lookup_listener(head, daddr, hnum, dif, nid); } if (sk) { sherry_cache: @@ -363,26 +365,26 @@ sherry_cache: #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \ const __u64 __name = (((__u64)(__daddr)) << 32) | ((__u64)(__saddr)); #endif /* __BIG_ENDIAN */ -#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __nid) \ + (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_nid == __nid) && \ ((*((__u64 *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \ ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) -#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __nid) \ + (((__sk)->sk_hash == (__hash)) && (inet_twsk(__sk)->tw_nid == __nid) && \ ((*((__u64 *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \ ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #else /* 32-bit arch */ #define INET_ADDR_COOKIE(__name, __saddr, __daddr) -#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif) \ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __nid) \ + (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_nid == __nid) && \ (inet_sk(__sk)->daddr == (__saddr)) && \ (inet_sk(__sk)->rcv_saddr == (__daddr)) && \ ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) -#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif, __nid) \ + (((__sk)->sk_hash == (__hash)) && (inet_twsk(__sk)->tw_nid == __nid) && \ (inet_twsk(__sk)->tw_daddr == (__saddr)) && \ (inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \ ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ @@ -399,7 +401,7 @@ static inline struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo, const u32 saddr, const u16 sport, const u32 daddr, const u16 hnum, - const int dif) + const int dif, nid_t nid) { INET_ADDR_COOKIE(acookie, saddr, daddr) const __u32 ports = INET_COMBINED_PORTS(sport, hnum); @@ -414,13 +416,13 @@ static inline struct sock * prefetch(head->chain.first); read_lock(&head->lock); sk_for_each(sk, node, &head->chain) { - if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) + if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif, nid)) goto hit; /* You sunk my battleship! */ } /* Must check for a TIME_WAIT'er before going to listener hash. */ sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { - if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) + if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif, nid)) goto hit; } sk = NULL; @@ -435,22 +437,22 @@ hit: static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo, const u32 saddr, const u16 sport, const u32 daddr, const u16 hnum, - const int dif) + const int dif, nid_t nid) { struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr, - hnum, dif); - return sk ? : inet_lookup_listener(hashinfo, daddr, hnum, dif); + hnum, dif, nid); + return sk ? : inet_lookup_listener(hashinfo, daddr, hnum, dif, nid); } static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo, const u32 saddr, const u16 sport, const u32 daddr, const u16 dport, - const int dif) + const int dif, nid_t nid) { struct sock *sk; local_bh_disable(); - sk = __inet_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif); + sk = __inet_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif, nid); local_bh_enable(); return sk; diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/net/raw.h linux-2.6.14-vs2.1.0-ngn0.03/include/net/raw.h --- linux-2.6.14-vs2.1.0-rc6/include/net/raw.h 2005-10-28 20:49:56 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/net/raw.h 2005-11-04 05:12:37 +0100 @@ -35,7 +35,7 @@ extern rwlock_t raw_v4_lock; extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, unsigned long raddr, unsigned long laddr, - int dif); + int dif, nid_t nid); extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash); diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/include/net/sock.h linux-2.6.14-vs2.1.0-ngn0.03/include/net/sock.h --- linux-2.6.14-vs2.1.0-rc6/include/net/sock.h 2005-10-29 21:24:04 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/include/net/sock.h 2005-11-04 07:02:39 +0100 @@ -852,6 +852,11 @@ static inline int sk_filter(struct sock { int err; + printk("sk_filter(%p[#%d], %p[#%d]) [#%d]\n", + sk, sk->sk_nid, skb, skb->nid, current->nid); + if (skb->nid != sk->sk_nid) + return -EPERM; + err = security_sock_rcv_skb(sk, skb); if (err) return err; @@ -1199,6 +1204,8 @@ static inline void sk_wake_async(struct #define SOCK_MIN_SNDBUF 2048 #define SOCK_MIN_RCVBUF 256 +#include + static inline void sk_stream_moderate_sndbuf(struct sock *sk) { if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { @@ -1220,6 +1227,7 @@ static inline struct sk_buff *sk_stream_ skb->truesize += mem; if (sk_stream_wmem_schedule(sk, skb->truesize)) { skb_reserve(skb, hdr_len); + ngn_tag_sock_skb(sk, skb); return skb; } __kfree_skb(skb); diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/ipc/sem.c linux-2.6.14-vs2.1.0-ngn0.03/ipc/sem.c --- linux-2.6.14-vs2.1.0-rc6/ipc/sem.c 2005-11-06 20:11:11 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/ipc/sem.c 2005-10-29 17:19:57 +0200 @@ -74,7 +74,6 @@ #include #include #include -#include #include #include "util.h" @@ -195,8 +194,6 @@ static int newary (key_t key, int nsems, return -ENOSPC; } used_sems += nsems; - vx_semary_inc(sma); - vx_nsems_add(sma, nsems); sma->sem_id = sem_buildid(id, sma->sem_perm.seq); sma->sem_base = (struct sem *) &sma[1]; @@ -474,8 +471,6 @@ static void freeary (struct sem_array *s sem_unlock(sma); used_sems -= sma->sem_nsems; - vx_nsems_sub(sma, sma->sem_nsems); - vx_semary_dec(sma); size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem); security_sem_free(sma); ipc_rcu_putref(sma); diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/kernel/vserver/Makefile linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/Makefile --- linux-2.6.14-vs2.1.0-rc6/kernel/vserver/Makefile 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/Makefile 2005-10-31 04:09:40 +0100 @@ -13,4 +13,5 @@ vserver-$(CONFIG_VSERVER_DEBUG) += sysct vserver-$(CONFIG_VSERVER_LEGACY) += legacy.o vserver-$(CONFIG_VSERVER_LEGACYNET) += legacynet.o vserver-$(CONFIG_VSERVER_HISTORY) += history.o +vserver-$(CONFIG_VSERVER_NGNET) += ngnet.o diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/kernel/vserver/ngnet.c linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/ngnet.c --- linux-2.6.14-vs2.1.0-rc6/kernel/vserver/ngnet.c 1970-01-01 01:00:00 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/ngnet.c 2005-11-04 03:15:24 +0100 @@ -0,0 +1,40 @@ +/* + * kernel/vserver/ngnet.c + * + * Copyright (C) 2005 Herbert Pötzl + * + * V0.01 ngnet dev tagging + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + + + +int vc_ngnet_tagdev(uint32_t id, void __user *data) +{ + struct vcmd_ngnet_tagdev vc_data; + struct net_device *dev; + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + dev = dev_get_by_index(vc_data.ifindex); + if (!dev) + return -ESRCH; + + /* FIXME: do some more checks? */ + dev->nid = id; + + return 0; +} + diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/kernel/vserver/switch.c linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/switch.c --- linux-2.6.14-vs2.1.0-rc6/kernel/vserver/switch.c 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/switch.c 2005-10-31 03:25:33 +0100 @@ -45,6 +45,7 @@ int vc_get_version(uint32_t id) #include #include #include +#include #include #include @@ -227,6 +228,10 @@ long do_vserver(uint32_t cmd, uint32_t i case VCMD_net_remove: return vc_net_remove(id, data); +#ifdef CONFIG_VSERVER_NGNET + case VCMD_ngnet_tagdev: + return vc_ngnet_tagdev(id, data); +#endif } return -ENOSYS; } diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/kernel/vserver/sysctl.c linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/sysctl.c --- linux-2.6.14-vs2.1.0-rc6/kernel/vserver/sysctl.c 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/kernel/vserver/sysctl.c 2005-11-03 02:22:32 +0100 @@ -30,6 +30,7 @@ enum { CTL_DEBUG_XID, CTL_DEBUG_NID, CTL_DEBUG_NET, + CTL_DEBUG_NGNET, CTL_DEBUG_LIMIT, CTL_DEBUG_DLIM, CTL_DEBUG_QUOTA, @@ -42,6 +43,7 @@ unsigned int vx_debug_switch = 0; unsigned int vx_debug_xid = 0; unsigned int vx_debug_nid = 0; unsigned int vx_debug_net = 0; +unsigned int vx_debug_ngnet = 0; unsigned int vx_debug_limit = 0; unsigned int vx_debug_dlim = 0; unsigned int vx_debug_quota = 0; @@ -143,6 +145,7 @@ static ctl_table debug_table[] = { CTL_ENTRY (CTL_DEBUG_XID, debug_xid), CTL_ENTRY (CTL_DEBUG_NID, debug_nid), CTL_ENTRY (CTL_DEBUG_NET, debug_net), + CTL_ENTRY (CTL_DEBUG_NGNET, debug_ngnet), CTL_ENTRY (CTL_DEBUG_LIMIT, debug_limit), CTL_ENTRY (CTL_DEBUG_DLIM, debug_dlim), CTL_ENTRY (CTL_DEBUG_QUOTA, debug_quota), @@ -167,6 +170,7 @@ static match_table_t tokens = { { CTL_DEBUG_XID, "xid=%x" }, { CTL_DEBUG_NID, "nid=%x" }, { CTL_DEBUG_NET, "net=%x" }, + { CTL_DEBUG_NGNET, "ngnet=%x" }, { CTL_DEBUG_LIMIT, "limit=%x" }, { CTL_DEBUG_DLIM, "dlim=%x" }, { CTL_DEBUG_QUOTA, "quota=%x" }, diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/core/dev.c linux-2.6.14-vs2.1.0-ngn0.03/net/core/dev.c --- linux-2.6.14-vs2.1.0-rc6/net/core/dev.c 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/core/dev.c 2005-11-04 06:15:17 +0100 @@ -114,6 +114,7 @@ #include #endif /* CONFIG_NET_RADIO */ #include +#include #include /* @@ -178,9 +179,11 @@ EXPORT_SYMBOL(dev_base_lock); static struct hlist_head dev_name_head[1<nid); + /* * The code is rearranged so that the path is the most * short when CPU is congested, but is still operating. @@ -1590,6 +1611,10 @@ int netif_receive_skb(struct sk_buff *sk pt_prev = NULL; + printk("netif_receive_skb(%p[#%d]) [#%d]\n", skb, skb->nid, current->nid); + /* FIXME: enter/leave? */ + current->nid = skb->nid; + rcu_read_lock(); #ifdef CONFIG_NET_CLS_ACT @@ -1838,8 +1863,7 @@ static int dev_ifconf(char __user *arg) total = 0; for (dev = dev_base; dev; dev = dev->next) { - if (vx_flags(VXF_HIDE_NETIF, 0) && - !dev_in_nx_info(dev, current->nx_info)) + if (!NGN_DEV_VISIBLE(dev, current->vx_info, current->nx_info)) continue; for (i = 0; i < NPROTO; i++) { if (gifconf_list[i]) { @@ -1901,9 +1925,7 @@ void dev_seq_stop(struct seq_file *seq, static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) { - struct nx_info *nxi = current->nx_info; - - if (vx_flags(VXF_HIDE_NETIF, 0) && !dev_in_nx_info(dev, nxi)) + if (!NGN_DEV_VISIBLE(dev, current->vx_info, current->nx_info)) return; if (dev->get_stats) { struct net_device_stats *stats = dev->get_stats(dev); @@ -2698,7 +2720,7 @@ int register_netdevice(struct net_device dev->iflink = dev->ifindex; /* Check for existence of name */ - head = dev_name_hash(dev->name); + head = dev_name_hash(dev->name, dev->nid); hlist_for_each(p, head) { struct net_device *d = hlist_entry(p, struct net_device, name_hlist); @@ -2986,6 +3008,7 @@ struct net_device *alloc_netdev(int size if (sizeof_priv) dev->priv = netdev_priv(dev); + dev->nid = nx_current_nid(); setup(dev); strcpy(dev->name, name); return dev; diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/core/rtnetlink.c linux-2.6.14-vs2.1.0-ngn0.03/net/core/rtnetlink.c --- linux-2.6.14-vs2.1.0-rc6/net/core/rtnetlink.c 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/core/rtnetlink.c 2005-11-04 02:48:10 +0100 @@ -50,6 +50,8 @@ #include #include +#include + DECLARE_MUTEX(rtnl_sem); void rtnl_lock(void) @@ -277,8 +279,8 @@ static int rtnetlink_dump_ifinfo(struct for (dev=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) && - !dev_in_nx_info(dev, skb->sk->sk_nx_info)) + if (!NGN_DEV_VISIBLE(dev, + skb->sk->sk_vx_info, skb->sk->sk_nx_info)) continue; if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, @@ -453,8 +455,7 @@ void rtmsg_ifinfo(int type, struct net_d sizeof(struct rtnl_link_ifmap) + sizeof(struct rtnl_link_stats) + 128); - if (vx_flags(VXF_HIDE_NETIF, 0) && - !dev_in_nx_info(dev, current->nx_info)) + if (!NGN_DEV_VISIBLE(dev, current->vx_info, current->nx_info)) return; skb = alloc_skb(size, GFP_KERNEL); if (!skb) diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/core/skbuff.c linux-2.6.14-vs2.1.0-ngn0.03/net/core/skbuff.c --- linux-2.6.14-vs2.1.0-rc6/net/core/skbuff.c 2005-10-28 20:49:58 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/core/skbuff.c 2005-11-04 05:47:58 +0100 @@ -413,6 +413,7 @@ struct sk_buff *skb_clone(struct sk_buff #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) C(ipvs_property); #endif + C(nid); #ifdef CONFIG_BRIDGE_NETFILTER C(nf_bridge); nf_bridge_get(skb->nf_bridge); diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/dccp/ipv4.c linux-2.6.14-vs2.1.0-ngn0.03/net/dccp/ipv4.c --- linux-2.6.14-vs2.1.0-rc6/net/dccp/ipv4.c 2005-10-28 20:49:58 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/dccp/ipv4.c 2005-11-04 04:50:45 +0100 @@ -507,7 +507,7 @@ void dccp_v4_err(struct sk_buff *skb, u3 } sk = inet_lookup(&dccp_hashinfo, iph->daddr, dh->dccph_dport, - iph->saddr, dh->dccph_sport, inet_iif(skb)); + iph->saddr, dh->dccph_sport, inet_iif(skb), skb->nid); if (sk == NULL) { ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); return; @@ -834,7 +834,7 @@ static struct sock *dccp_v4_hnd_req(stru nsk = __inet_lookup_established(&dccp_hashinfo, iph->saddr, dh->dccph_sport, iph->daddr, ntohs(dh->dccph_dport), - inet_iif(skb)); + inet_iif(skb), skb->nid); if (nsk != NULL) { if (nsk->sk_state != DCCP_TIME_WAIT) { bh_lock_sock(nsk); @@ -1142,7 +1142,7 @@ int dccp_v4_rcv(struct sk_buff *skb) sk = __inet_lookup(&dccp_hashinfo, skb->nh.iph->saddr, dh->dccph_sport, skb->nh.iph->daddr, ntohs(dh->dccph_dport), - inet_iif(skb)); + inet_iif(skb), skb->nid); /* * Step 2: diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/devinet.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/devinet.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/devinet.c 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/devinet.c 2005-11-04 02:50:04 +0100 @@ -62,6 +62,8 @@ #include #include +#include + struct ipv4_devconf ipv4_devconf = { .accept_redirects = 1, .send_redirects = 1, @@ -639,10 +641,13 @@ int devinet_ioctl(unsigned int cmd, void } ret = -EADDRNOTAVAIL; + if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) goto done; - if (vx_flags(VXF_HIDE_NETIF, 0) && - !ifa_in_nx_info(ifa, current->nx_info)) + + /* NGN: block forbidden addresses */ + if (cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS && + !NGN_IFA_VISIBLE(ifa, current->vx_info, current->nx_info)) goto done; switch(cmd) { @@ -787,8 +792,7 @@ static int inet_gifconf(struct net_devic goto out; for (; ifa; ifa = ifa->ifa_next) { - if (vx_flags(VXF_HIDE_NETIF, 0) && - !ifa_in_nx_info(ifa, current->nx_info)) + if (!NGN_IFA_VISIBLE(ifa, current->vx_info, current->nx_info)) continue; if (!buf) { done += sizeof(ifr); @@ -1119,8 +1123,8 @@ static int inet_dump_ifaddr(struct sk_bu for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { - if (sk && vx_info_flags(sk->sk_vx_info, VXF_HIDE_NETIF, 0) && - !ifa_in_nx_info(ifa, sk->sk_nx_info)) + if (sk && !NGN_IFA_VISIBLE(ifa, + sk->sk_vx_info, sk->sk_nx_info)) continue; if (ip_idx < s_ip_idx) continue; diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/fib_hash.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/fib_hash.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/fib_hash.c 2005-11-07 00:30:40 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/fib_hash.c 2005-11-04 02:51:05 +0100 @@ -43,6 +43,7 @@ #include #include +#include #include "fib_lookup.h" static kmem_cache_t *fn_hash_kmem __read_mostly; @@ -1020,8 +1021,9 @@ 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 && (!vx_flags(VXF_HIDE_NETIF, 0) || - dev_in_nx_info(fi->fib_dev, current->nx_info))) + + if (fi && NGN_DEV_VISIBLE(fi->fib_dev, + current->vx_info, 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, diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/icmp.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/icmp.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/icmp.c 2005-10-28 20:50:01 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/icmp.c 2005-11-04 06:41:13 +0100 @@ -359,6 +359,8 @@ static void icmp_push_reply(struct icmp_ unsigned int csum = 0; struct sk_buff *skb1; + // skb->nid = icmp_param->skb->nid; + skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) { csum = csum_add(csum, skb1->csum); } @@ -383,6 +385,9 @@ static void icmp_reply(struct icmp_bxm * struct rtable *rt = (struct rtable *)skb->dst; u32 daddr; + /* reverse tag icmp socket */ + sk->sk_nid = skb->nid; + if (ip_options_echo(&icmp_param->replyopts, skb)) goto out; @@ -700,8 +705,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->nid)) != NULL) { raw_err(raw_sk, skb, info); raw_sk = sk_next(raw_sk); iph = (struct iphdr *)skb->data; diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/inet_diag.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/inet_diag.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/inet_diag.c 2005-10-30 02:51:03 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/inet_diag.c 2005-11-04 04:51:21 +0100 @@ -201,7 +201,8 @@ static int inet_diag_get_exact(struct sk if (req->idiag_family == AF_INET) { sk = inet_lookup(hashinfo, req->id.idiag_dst[0], req->id.idiag_dport, req->id.idiag_src[0], - req->id.idiag_sport, req->id.idiag_if); + req->id.idiag_sport, req->id.idiag_if, + in_skb->nid); } #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) else if (req->idiag_family == AF_INET6) { diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/inet_hashtables.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/inet_hashtables.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/inet_hashtables.c 2005-10-30 02:36:53 +0100 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/inet_hashtables.c 2005-11-04 04:40:18 +0100 @@ -127,8 +127,10 @@ EXPORT_SYMBOL(inet_listen_wlock); * remote address for the connection. So always assume those are both * wildcarded during the search since they can never be otherwise. */ -struct sock *__inet_lookup_listener(const struct hlist_head *head, const u32 daddr, - const unsigned short hnum, const int dif) +struct sock *__inet_lookup_listener(const struct hlist_head *head, + const u32 daddr, + const unsigned short hnum, + const int dif, nid_t nid) { struct sock *result = NULL, *sk; const struct hlist_node *node; @@ -141,6 +143,9 @@ struct sock *__inet_lookup_listener(cons const __u32 rcv_saddr = inet->rcv_saddr; int score = sk->sk_family == PF_INET ? 1 : 0; + if (!__nx_check(nid, sk->sk_nid, NX_IDENT)) + continue; + if (inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr)) score += 2; else diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/ip_output.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/ip_output.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/ip_output.c 2005-10-28 20:50:01 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/ip_output.c 2005-11-04 05:23:01 +0100 @@ -152,6 +152,7 @@ int ip_build_and_send_pkt(struct sk_buff ip_send_check(iph); skb->priority = sk->sk_priority; + ngn_tag_sock_skb(sk, skb); /* Send it out. */ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, @@ -358,6 +359,7 @@ packet_routed: ip_send_check(iph); skb->priority = sk->sk_priority; + ngn_tag_sock_skb(sk, skb); return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); @@ -1179,6 +1181,7 @@ int ip_push_pending_frames(struct sock * skb->priority = sk->sk_priority; skb->dst = dst_clone(&rt->u.dst); + ngn_tag_sock_skb(sk, skb); /* Netfilter gets whole the not fragmented skb. */ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/raw.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/raw.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/raw.c 2005-10-29 19:05:58 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/raw.c 2005-11-05 04:39:00 +0100 @@ -125,14 +125,14 @@ static inline int raw_addr_match ( struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, unsigned long raddr, unsigned long laddr, - int dif) + int dif, nid_t nid) { struct hlist_node *node; sk_for_each_from(sk, node) { struct inet_sock *inet = inet_sk(sk); - if (inet->num == num && + if (inet->num == num && sk->sk_nid == nid && !(inet->daddr && inet->daddr != raddr) && raw_addr_match(sk->sk_nx_info, laddr, inet->rcv_saddr, inet->rcv_saddr2) && @@ -184,7 +184,7 @@ int raw_v4_input(struct sk_buff *skb, st goto out; sk = __raw_v4_lookup(__sk_head(head), iph->protocol, iph->saddr, iph->daddr, - skb->dev->ifindex); + skb->dev->ifindex, skb->nid); while (sk) { delivered = 1; @@ -197,7 +197,7 @@ int raw_v4_input(struct sk_buff *skb, st } sk = __raw_v4_lookup(sk_next(sk), iph->protocol, iph->saddr, iph->daddr, - skb->dev->ifindex); + skb->dev->ifindex, skb->nid); } out: read_unlock(&raw_v4_lock); @@ -260,6 +260,7 @@ void raw_err (struct sock *sk, struct sk static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) { + printk("raw_rcv_skb(%p[#%d], %p[#%d])\n", sk, sk->sk_nid, skb, skb->nid); /* Charge it to the socket. */ if (sock_queue_rcv_skb(sk, skb) < 0) { @@ -312,6 +313,7 @@ static int raw_send_hdrinc(struct sock * skb->priority = sk->sk_priority; skb->dst = dst_clone(&rt->u.dst); + ngn_tag_sock_skb(sk, skb); skb->nh.iph = iph = (struct iphdr *)skb_put(skb, length); diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/ipv4/tcp_ipv4.c linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/tcp_ipv4.c --- linux-2.6.14-vs2.1.0-rc6/net/ipv4/tcp_ipv4.c 2005-10-29 19:18:23 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/ipv4/tcp_ipv4.c 2005-11-04 05:01:09 +0100 @@ -136,6 +136,7 @@ static int __tcp_v4_check_established(st struct sock *sk2; const struct hlist_node *node; struct inet_timewait_sock *tw; + nid_t nid = nx_current_nid(); prefetch(head->chain.first); write_lock(&head->lock); @@ -144,7 +145,7 @@ static int __tcp_v4_check_established(st sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) { tw = inet_twsk(sk2); - if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) { + if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif, nid)) { const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2); struct tcp_sock *tp = tcp_sk(sk); @@ -181,7 +182,7 @@ static int __tcp_v4_check_established(st /* And established part... */ sk_for_each(sk2, node, &head->chain) { - if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) + if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif, nid)) goto not_unique; } @@ -516,7 +517,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 } sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr, - th->source, inet_iif(skb)); + th->source, inet_iif(skb), skb->nid); if (!sk) { ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); return; @@ -1093,7 +1094,8 @@ static struct sock *tcp_v4_hnd_req(struc nsk = __inet_lookup_established(&tcp_hashinfo, skb->nh.iph->saddr, th->source, skb->nh.iph->daddr, - ntohs(th->dest), inet_iif(skb)); + ntohs(th->dest), inet_iif(skb), + skb->nid); if (nsk) { if (nsk->sk_state != TCP_TIME_WAIT) { @@ -1237,7 +1239,7 @@ int tcp_v4_rcv(struct sk_buff *skb) sk = __inet_lookup(&tcp_hashinfo, skb->nh.iph->saddr, th->source, skb->nh.iph->daddr, ntohs(th->dest), - inet_iif(skb)); + inet_iif(skb), skb->nid); if (!sk) goto no_tcp_socket; @@ -1304,7 +1306,8 @@ do_time_wait: struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo, skb->nh.iph->daddr, ntohs(th->dest), - inet_iif(skb)); + inet_iif(skb), + skb->nid); if (sk2) { inet_twsk_deschedule((struct inet_timewait_sock *)sk, &tcp_death_row); diff -NurpP --minimal linux-2.6.14-vs2.1.0-rc6/net/packet/af_packet.c linux-2.6.14-vs2.1.0-ngn0.03/net/packet/af_packet.c --- linux-2.6.14-vs2.1.0-rc6/net/packet/af_packet.c 2005-10-28 20:50:02 +0200 +++ linux-2.6.14-vs2.1.0-ngn0.03/net/packet/af_packet.c 2005-11-05 05:15:16 +0100 @@ -471,8 +471,15 @@ static int packet_rcv(struct sk_buff *sk sk = pt->af_packet_priv; po = pkt_sk(sk); + /* allow ident and observer */ + if (!__nx_check(sk->sk_nid, skb->nid, NX_IDENT|NX_WATCH)) + goto drop; + skb->dev = dev; + printk("packet_rcv(%p[#%d], %p[#%d]) %p[#%d]\n", + skb, skb->nid, dev, dev->nid, sk, sk ? sk->sk_nid : 0); + if (dev->hard_header) { /* The device has an explicit notion of ll header, exported to higher levels.