diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/drivers/net/loopback.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/drivers/net/loopback.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/drivers/net/loopback.c 2005-10-28 20:49:26 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/drivers/net/loopback.c 2006-05-01 00:42:04 +0200 @@ -57,6 +57,7 @@ #include #include #include +#include static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); @@ -149,6 +150,9 @@ static int loopback_xmit(struct sk_buff #endif dev->last_rx = jiffies; + vxdprintk(VXD_CBIT(nid, 6), + "loopback_xmit(%p[#%u])", skb, skb->nid); + lb_stats = &per_cpu(loopback_stats, get_cpu()); lb_stats->rx_bytes += skb->len; lb_stats->tx_bytes = lb_stats->rx_bytes; diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/linux/skbuff.h linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/linux/skbuff.h --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/linux/skbuff.h 2006-02-15 13:54:35 +0100 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/linux/skbuff.h 2006-05-01 00:41:35 +0200 @@ -285,7 +285,7 @@ struct sk_buff { __u16 tc_verd; /* traffic control verdict */ #endif #endif - + nid_t nid; /* These elements must be at the end, see alloc_skb() for details. */ unsigned int truesize; diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/linux/vs_netiso.h linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/linux/vs_netiso.h --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/linux/vs_netiso.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/linux/vs_netiso.h 2006-05-01 00:41:35 +0200 @@ -0,0 +1,131 @@ +#ifndef _NX_VS_NETISO_H +#define _NX_VS_NETISO_H + +#include +#include + +#define tag_sock_skb(sk, skb) \ + __tag_sock_skb(sk, skb, __FILE__, __LINE__) + +static inline +void __tag_sock_skb(struct sock *sk, struct sk_buff *skb, + const char *_file, int _line) +{ + vxlprintk(VXD_CBIT(nid, 7), "tag_sock_skb(%p[#%u],%p[#%u])", + sk, sk ? sk->sk_nid : 0, skb, skb->nid, _file, _line); + skb->nid = sk ? sk->sk_nid : current->nid; +} + +#define sk_match_nid(sk, nid) \ + __sk_match_nid(sk, nid, __FILE__, __LINE__) + +/* __sk_match_nid + + * check that a socket is 'visible' in + * a given network context */ + +static inline +int __sk_match_nid(const struct sock *sk, nid_t nid, + const char *_file, int _line) +{ + nid_t sknid = sk->sk_nid; + + vxlprintk(VXD_CBIT(nid, 7), "sk_match_nid(%p[#%u],#%u)", + sk, sk ? sk->sk_nid : 0, nid, _file, _line); + + /* host, watch and same context */ + return __nx_check(nid, sknid, NX_ADMIN|NX_WATCH|NX_IDENT); +} + + +/* __match_addr + + * check if addresses matches + * addr is considered valid */ + +static inline +int __match_addr(uint32_t addr, nid_t nid, uint32_t baddr, nid_t bnid) +{ + /* looking for a loopback? */ + if ((addr == IPI_LOOPBACK) && + /* no loopback match from outside */ + (nid != bnid)) + return 0; + + /* ANY or direct match is fine */ + return (!baddr || baddr == addr); +} + + +#define sk_match_addr(sk, addr, nid) \ + __sk_match_addr(sk, addr, nid, __FILE__, __LINE__) + +/* __sk_match_addr + + * check that a socket 'matches' + * a given network address for nid */ + +static // inline +int __sk_match_addr(const struct sock *sk, uint32_t addr, nid_t nid, + const char *_file, int _line) +{ + struct nx_info *nxi = sk->sk_nx_info; + uint32_t saddr = inet_rcv_saddr(sk); + + vxdprintk(VXD_CBIT(net, 5), + "sk_match_addr(%p[#%u],%d.%d.%d.%d) %d.%d.%d.%d [#%u]", + sk, sk->sk_nid, VXD_QUAD(addr), VXD_QUAD(saddr), nid); + + /* match ANY against nx_info */ + if (!saddr) + return __addr_in_nx_info(nxi, addr, nid); + + return __match_addr(addr, nid, saddr, sk->sk_nid); +} + + +#define sk_conflict(sk, sk2) \ + __sk_conflict(sk, sk2, __FILE__, __LINE__) + +/* __sk_conflict + + * check if socket sk would + * conflict with existing socket sk2 */ + +static inline +int __sk_conflict(const struct sock *sk, const struct sock *sk2, + const char *_file, int _line) +{ + uint32_t saddr = inet_rcv_saddr(sk); + + vxlprintk(VXD_CBIT(net, 2), + "sk_conflict(%p[#%u],%p[#%u]) %d.%d.%d.%d", + sk, sk->sk_nid, sk2, sk2->sk_nid, VXD_QUAD(saddr), + _file, _line); + + return __sk_match_addr(sk2, saddr, sk->sk_nid, + _file, _line); +} + + +#define inet_sk_match_nid(sk, saddr, daddr, nid) \ + __inet_sk_match_nid(sk, saddr, daddr, nid, __FILE__, __LINE__) + +static inline +int __inet_sk_match_nid(const struct sock *sk, + uint32_t saddr, uint32_t daddr, nid_t nid, + const char *_file, int _line) +{ + vxlprintk(VXD_CBIT(net, 2), + "inet_sk_match_nid(%p[#%u],%d.%d.%d.%d,%d.%d.%d.%d,#%u)", + sk, sk->sk_nid, VXD_QUAD(saddr), VXD_QUAD(daddr), nid, + _file, _line); + + return __sk_match_addr(sk, daddr, nid, _file, _line); +} + + + +#else +#warning duplicate inclusion +#endif diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/linux/vs_network.h linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/linux/vs_network.h --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/linux/vs_network.h 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/linux/vs_network.h 2006-05-01 03:46:06 +0200 @@ -160,7 +160,7 @@ static __inline__ struct nx_info *__task /* - * check current context for ADMIN/WATCH and + * check context id for ADMIN/WATCH and * optionally against supplied argument */ static inline int __nx_check(nid_t cid, nid_t id, unsigned int mode) @@ -214,24 +214,48 @@ static inline int __nx_check(nid_t cid, #define nx_ncaps(c) nx_info_ncaps(current->nx_info,(c)) +#include -static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr) +#define IPI_LOOPBACK htonl(INADDR_LOOPBACK) + +static inline int __addr_in_nx_info(struct nx_info *nxi, uint32_t addr, nid_t nid) { int n,i; + vxdprintk(VXD_CBIT(nid, 8), + "__addr_in_nx_info(%p[#%u],%d.%d.%d.%d,#%u)", + nxi, nxi?nxi->nx_id:0, VXD_QUAD(addr), nid); + + /* unrestricted means match */ if (!nxi) return 1; + /* loopback is part of any nx_info now */ + if ((addr == IPI_LOOPBACK) && + /* but only when the context matches */ + __nx_check(nxi->nx_id, nid, NX_IDENT|NX_HOSTID)) + return 1; + n = nxi->nbipv4; + /* generic ANY context? */ if (n && (nxi->ipv4[0] == 0)) return 1; - for (i=0; iipv4[i] == addr) return 1; - } + + /* nothing found */ return 0; } +static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr) +{ + return __addr_in_nx_info(nxi, addr, 0); +} + + static inline void exit_nx_info(struct task_struct *p) { if (p->nx_info) diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/net/inet_hashtables.h linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/inet_hashtables.h --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/net/inet_hashtables.h 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/inet_hashtables.h 2006-05-01 00:41:35 +0200 @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -272,35 +273,18 @@ static inline int inet_iif(const struct return ((struct rtable *)skb->dst)->rt_iif; } -/* - * Check if a given address matches for an inet socket - * - * nxi: the socket's nx_info if any - * addr: to be verified address - * saddr: socket addresses - */ -static inline int inet_addr_match ( - struct nx_info *nxi, - uint32_t addr, - uint32_t saddr) -{ - if (addr && (saddr == addr)) - return 1; - if (!saddr) - return addr_in_nx_info(nxi, addr); - return 0; -} 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; @@ -311,11 +295,11 @@ static inline struct sock * const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); if (inet->num == hnum && !sk->sk_node.next && - inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) && + sk_match_addr(sk, daddr, nid) && (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: @@ -342,29 +326,37 @@ 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)\ +#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, \ + __ports, __dif, __nid) \ (((__sk)->sk_hash == (__hash)) && \ ((*((__u64 *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \ ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \ + inet_sk_match_nid(__sk, __saddr, __daddr, __nid) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) -#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ +#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, \ + __ports, __dif, __nid) \ (((__sk)->sk_hash == (__hash)) && \ ((*((__u64 *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \ ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ + inet_sk_match_nid(__sk, __saddr, __daddr, __nid) && \ (!((__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) \ +#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, \ + __ports, __dif, __nid) \ (((__sk)->sk_hash == (__hash)) && \ (inet_sk(__sk)->daddr == (__saddr)) && \ (inet_sk(__sk)->rcv_saddr == (__daddr)) && \ ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \ + inet_sk_match_nid(__sk, __saddr, __daddr, __nid) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) -#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \ +#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, \ + __ports, __dif, __nid) \ (((__sk)->sk_hash == (__hash)) && \ (inet_twsk(__sk)->tw_daddr == (__saddr)) && \ (inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \ ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ + inet_sk_match_nid(__sk, __saddr, __daddr, __nid) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #endif /* 64-bit arch */ @@ -378,7 +370,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); @@ -393,13 +385,15 @@ 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; @@ -414,22 +408,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.16.11-vs2.1.1-rc18-lo0.00/include/net/inet_sock.h linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/inet_sock.h --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/net/inet_sock.h 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/inet_sock.h 2006-05-01 00:40:58 +0200 @@ -115,7 +115,6 @@ struct inet_sock { /* Socket demultiplex comparisons on incoming packets. */ __u32 daddr; __u32 rcv_saddr; - __u32 rcv_saddr2; /* Second bound ipv4 addr, for ipv4root */ __u16 dport; __u16 num; __u32 saddr; diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/net/raw.h linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/raw.h --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/net/raw.h 2006-01-18 06:08:45 +0100 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/raw.h 2006-05-01 00:41:35 +0200 @@ -37,7 +37,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.16.11-vs2.1.1-rc18-lo0.00/include/net/route.h linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/route.h --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/include/net/route.h 2006-04-26 19:14:20 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/include/net/route.h 2006-05-01 00:41:25 +0200 @@ -147,8 +147,6 @@ static inline char rt_tos2priority(u8 to return ip_tos2prio[IPTOS_TOS(tos)>>1]; } -#define IPI_LOOPBACK htonl(INADDR_LOOPBACK) - static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl) { int err; @@ -173,6 +171,10 @@ static inline int ip_find_src(struct nx_ foundsrc = (*rp)->rt_src; ip_rt_put(*rp); + if (foundsrc == IPI_LOOPBACK) { + fl->fl4_src = foundsrc; + return 0; + } for (i=0; imask[i]; u32 ipv4 = nxi->ipv4[i]; @@ -186,10 +188,7 @@ static inline int ip_find_src(struct nx_ fl->fl4_src = ipv4; } } - if (fl->fl4_src == 0) - fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK) - ? IPI_LOOPBACK : ipv4root; - } else { + } else if (fl->fl4_src != IPI_LOOPBACK) { for (i=0; iipv4[i] == fl->fl4_src) break; @@ -227,10 +226,6 @@ static inline int ip_route_connect(struc err = ip_find_src(nx_info, rp, &fl); if (err) return err; - if (fl.fl4_dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) - fl.fl4_dst = nx_info->ipv4[0]; - if (fl.fl4_src == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) - fl.fl4_src = nx_info->ipv4[0]; } if (!fl.fl4_dst || !fl.fl4_src) { err = __ip_route_output_key(rp, &fl); diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/core/dev.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/core/dev.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/core/dev.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/core/dev.c 2006-05-01 00:41:36 +0200 @@ -1506,6 +1506,9 @@ static __inline__ int deliver_skb(struct struct net_device *orig_dev) { atomic_inc(&skb->users); + vxdprintk(VXD_CBIT(nid, 8), + "deliver_skb(%p[#%u],%p[%p])", + skb, skb->nid, pt_prev, pt_prev->func); return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); } diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/core/skbuff.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/core/skbuff.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/core/skbuff.c 2006-04-09 13:49:59 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/core/skbuff.c 2006-05-01 00:54:24 +0200 @@ -425,6 +425,7 @@ struct sk_buff *skb_clone(struct sk_buff C(nfct_reasm); nf_conntrack_get_reasm(skb->nfct_reasm); #endif + C(nid); #ifdef CONFIG_BRIDGE_NETFILTER C(nf_bridge); nf_bridge_get(skb->nf_bridge); diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/af_inet.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/af_inet.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/af_inet.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/af_inet.c 2006-05-01 00:40:58 +0200 @@ -401,13 +401,10 @@ int inet_bind(struct socket *sock, struc struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); + struct nx_info *nxi = sk->sk_nx_info; unsigned short snum; int chk_addr_ret; int err; - __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; /* If the socket has its own bind function then use it. (RAW) */ if (sk->sk_prot->bind) { @@ -418,40 +415,16 @@ int inet_bind(struct socket *sock, struc if (addr_len < sizeof(struct sockaddr_in)) goto out; - s_addr = addr->sin_addr.s_addr; - s_addr1 = s_addr; - s_addr2 = 0xffffffffl; - vxdprintk(VXD_CBIT(net, 3), "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d", sk, sk->sk_nx_info, sk->sk_socket, (sk->sk_socket?sk->sk_socket->flags:0), - VXD_QUAD(s_addr)); - if (nxi) { - __u32 v4_bcast = nxi->v4_bcast; - __u32 ipv4root = nxi->ipv4[0]; - int nbipv4 = nxi->nbipv4; - - if (s_addr == 0) { - /* bind to any for 1-n */ - s_addr = ipv4root; - s_addr1 = (nbipv4 > 1) ? 0 : s_addr; - s_addr2 = v4_bcast; - } else if (s_addr == IPI_LOOPBACK) { - /* rewrite localhost to ipv4root */ - s_addr = ipv4root; - s_addr1 = ipv4root; - } else if (s_addr != v4_bcast) { - /* normal address bind */ - if (!addr_in_nx_info(nxi, s_addr)) - return -EADDRNOTAVAIL; - } - } - chk_addr_ret = inet_addr_type(s_addr); + VXD_QUAD(addr->sin_addr.s_addr)); - 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)); + if (addr->sin_addr.s_addr && + !addr_in_nx_info(nxi, addr->sin_addr.s_addr)) + return -EADDRNOTAVAIL; + chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since @@ -463,7 +436,7 @@ int inet_bind(struct socket *sock, struc err = -EADDRNOTAVAIL; if (!sysctl_ip_nonlocal_bind && !inet->freebind && - s_addr != INADDR_ANY && + addr->sin_addr.s_addr != INADDR_ANY && chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) @@ -488,8 +461,7 @@ int inet_bind(struct socket *sock, struc if (sk->sk_state != TCP_CLOSE || inet->num) goto out_release_sock; - inet->rcv_saddr = inet->saddr = s_addr1; - inet->rcv_saddr2 = s_addr2; + inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) inet->saddr = 0; /* Use device */ diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/icmp.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/icmp.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/icmp.c 2006-02-18 14:40:39 +0100 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/icmp.c 2006-05-01 03:30:04 +0200 @@ -384,6 +384,12 @@ 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; + + /* reverse tag icmp socket */ + sk->sk_nid = skb->nid; + if (ip_options_echo(&icmp_param->replyopts, skb)) return; @@ -440,6 +446,9 @@ void icmp_send(struct sk_buff *skb_in, i u32 saddr; u8 tos; + vxdprintk(VXD_CBIT(net, 5), + "icmp_send(%p[#%u], %d)",skb_in, skb_in->nid, type); + if (!rt) goto out; @@ -701,7 +710,8 @@ static void icmp_unreach(struct sk_buff 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) { + 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.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/inet_connection_sock.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/inet_connection_sock.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/inet_connection_sock.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/inet_connection_sock.c 2006-05-01 00:40:58 +0200 @@ -52,8 +52,7 @@ int inet_csk_bind_conflict(const struct sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { if (!reuse || !sk2->sk_reuse || sk2->sk_state == TCP_LISTEN) { - if (nx_addr_conflict(sk->sk_nx_info, - inet_rcv_saddr(sk), sk2)) + if (sk_conflict(sk, sk2)) break; } } diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/inet_diag.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/inet_diag.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/inet_diag.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/inet_diag.c 2006-05-01 00:41:36 +0200 @@ -241,7 +241,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.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/inet_hashtables.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/inet_hashtables.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/inet_hashtables.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/inet_hashtables.c 2006-05-01 00:41:36 +0200 @@ -130,7 +130,8 @@ EXPORT_SYMBOL(inet_listen_wlock); * 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) + const unsigned short hnum, + const int dif, nid_t nid) { struct sock *result = NULL, *sk; const struct hlist_node *node; @@ -140,10 +141,9 @@ struct sock *__inet_lookup_listener(cons const struct inet_sock *inet = inet_sk(sk); if (inet->num == hnum && !ipv6_only_sock(sk)) { - const __u32 rcv_saddr = inet->rcv_saddr; int score = sk->sk_family == PF_INET ? 1 : 0; - if (inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr)) + if (sk_match_addr(sk, daddr, nid)) score += 2; else continue; @@ -190,7 +190,7 @@ static int __inet_check_established(stru sk_for_each(sk2, node, &(head + hinfo->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, 0)) { if (twsk_unique(sk, sk2, twp)) goto unique; else @@ -201,7 +201,7 @@ static int __inet_check_established(stru /* 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, 0)) goto not_unique; } diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/ip_output.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/ip_output.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/ip_output.c 2006-04-26 19:05:21 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/ip_output.c 2006-05-01 00:40:58 +0200 @@ -83,6 +83,7 @@ #include #include #include +#include int sysctl_ip_default_ttl = IPDEFTTL; @@ -153,6 +156,7 @@ int ip_build_and_send_pkt(struct sk_buff ip_send_check(iph); skb->priority = sk->sk_priority; + tag_sock_skb(sk, skb); /* Send it out. */ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, @@ -368,6 +372,7 @@ packet_routed: ip_send_check(iph); skb->priority = sk->sk_priority; + tag_sock_skb(sk, skb); return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); @@ -1258,6 +1263,7 @@ int ip_push_pending_frames(struct sock * skb->priority = sk->sk_priority; skb->dst = dst_clone(&rt->u.dst); + 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.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/raw.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/raw.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/raw.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/raw.c 2006-05-01 00:41:36 +0200 @@ -79,6 +79,7 @@ #include #include #include +#include struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE]; DEFINE_RWLOCK(raw_v4_lock); @@ -103,44 +104,27 @@ static void raw_v4_unhash(struct sock *s } -/* - * Check if a given address matches for a socket - * - * nxi: the socket's nx_info if any - * addr: to be verified address - * saddr/baddr: socket addresses - */ -static inline int raw_addr_match ( - struct nx_info *nxi, - uint32_t addr, - uint32_t saddr, - uint32_t baddr) -{ - if (addr && (saddr == addr || baddr == addr)) - return 1; - if (!saddr) - return addr_in_nx_info(nxi, addr); - return 0; -} - 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 && - !(inet->daddr && inet->daddr != raddr) && - raw_addr_match(sk->sk_nx_info, laddr, - inet->rcv_saddr, inet->rcv_saddr2) && - !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) + if (inet->num == num && + !(inet->daddr && inet->daddr != raddr) && + !(sk->sk_bound_dev_if && + sk->sk_bound_dev_if != dif) && + !(sk_match_addr(sk, laddr, nid))) goto found; /* gotcha */ } sk = NULL; found: + vxdprintk(VXD_CBIT(nid, 8), + "__raw_v4_lookup(#%u) = %p[#%u]", + nid, sk, sk ? sk->sk_nid : 0); return sk; } @@ -184,7 +168,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 +181,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,8 +244,11 @@ void raw_err (struct sock *sk, struct sk static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) { + vxdprintk(VXD_CBIT(nid, 8), + "raw_rcv_skb(%p[#%u],%p[#%u])", + sk, sk->sk_nid, skb, skb->nid); + /* Charge it to the socket. */ - if (sock_queue_rcv_skb(sk, skb) < 0) { /* FIXME: increment a raw drops counter here */ kfree_skb(skb); @@ -313,6 +300,7 @@ static int raw_send_hdrinc(struct sock * skb->priority = sk->sk_priority; skb->dst = dst_clone(&rt->u.dst); + tag_sock_skb(sk, skb); skb->nh.iph = iph = (struct iphdr *)skb_put(skb, length); diff -NurpP --minimal linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/tcp_ipv4.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/tcp_ipv4.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/tcp_ipv4.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/tcp_ipv4.c 2006-05-01 00:41:36 +0200 @@ -349,7 +349,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; @@ -932,7 +932,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) { @@ -1070,7 +1071,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; @@ -1138,7 +1139,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.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/udp.c linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/udp.c --- linux-2.6.16.11-vs2.1.1-rc18-lo0.00/net/ipv4/udp.c 2006-04-26 19:07:00 +0200 +++ linux-2.6.16.11-vs2.1.1-rc18-lo0.05/net/ipv4/udp.c 2006-05-01 03:50:05 +0200 @@ -109,6 +109,7 @@ #include #include #include +#include /* * Snmp MIB for the UDP layer @@ -180,8 +181,7 @@ gotit: (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && - nx_addr_conflict(sk->sk_nx_info, - inet_rcv_saddr(sk), sk2) && + sk_conflict(sk, sk2) && (!sk2->sk_reuse || !sk->sk_reuse)) goto fail; } @@ -221,16 +221,23 @@ static void udp_v4_unhash(struct sock *s * harder than this. -DaveM */ static struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, - u32 daddr, u16 dport, int dif) + u32 daddr, u16 dport, + int dif, nid_t nid) { struct sock *sk, *result = NULL; struct hlist_node *node; unsigned short hnum = ntohs(dport); int badness = -1; + vxdprintk(VXD_CBIT(net, 5), + "udp_v4_lookup_longway(%d.%d.%d.%d:%d,%d.%d.%d.%d:%d,#%u)", + VXD_QUAD(saddr), ntohs(sport), VXD_QUAD(daddr), hnum, nid); + sk_for_each(sk, node, &udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]) { struct inet_sock *inet = inet_sk(sk); + if (!sk_match_nid(sk, nid)) + continue; if (inet->num == hnum && !ipv6_only_sock(sk)) { int score = (sk->sk_family == PF_INET ? 1 : 0); if (inet->rcv_saddr) { @@ -238,7 +245,8 @@ static struct sock *udp_v4_lookup_longwa continue; score+=2; } else if (sk->sk_nx_info) { - if (addr_in_nx_info(sk->sk_nx_info, daddr)) + if (__addr_in_nx_info(sk->sk_nx_info, + daddr, nid)) score+=2; else continue; @@ -271,12 +279,13 @@ static struct sock *udp_v4_lookup_longwa } static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport, - u32 daddr, u16 dport, int dif) + u32 daddr, u16 dport, + int dif, nid_t nid) { 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, nid); if (sk) sock_hold(sk); read_unlock(&udp_hash_lock); @@ -286,7 +295,7 @@ static __inline__ struct sock *udp_v4_lo static inline struct sock *udp_v4_mcast_next(struct sock *sk, u16 loc_port, u32 loc_addr, u16 rmt_port, u32 rmt_addr, - int dif) + int dif, nid_t nid) { struct hlist_node *node; struct sock *s = sk; @@ -295,11 +304,12 @@ static inline struct sock *udp_v4_mcast_ sk_for_each_from(s, node) { struct inet_sock *inet = inet_sk(s); + if (!sk_match_nid(sk, nid)) + continue; if (inet->num != hnum || (inet->daddr && inet->daddr != rmt_addr) || (inet->dport != rmt_port && inet->dport) || - (inet->rcv_saddr && inet->rcv_saddr != loc_addr && - inet->rcv_saddr2 && inet->rcv_saddr2 != loc_addr) || + (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || ipv6_only_sock(s) || (s->sk_bound_dev_if && s->sk_bound_dev_if != dif)) continue; @@ -334,7 +344,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->nid); if (sk == NULL) { ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); return; /* No socket for error */ @@ -615,8 +626,6 @@ int udp_sendmsg(struct kiocb *iocb, stru err = ip_find_src(nxi, &rt, &fl); if (err) goto out; - if (daddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) - daddr = fl.fl4_dst = nxi->ipv4[0]; } err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); if (err) @@ -1061,11 +1070,13 @@ static int udp_v4_mcast_deliver(struct s { struct sock *sk; int dif; + nid_t nid; read_lock(&udp_hash_lock); sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); dif = skb->dev->ifindex; - sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); + nid = skb->nid; + sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif, nid); if (sk) { struct sock *sknext = NULL; @@ -1073,7 +1084,7 @@ static int udp_v4_mcast_deliver(struct s struct sk_buff *skb1 = skb; sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr, - uh->source, saddr, dif); + uh->source, saddr, dif, nid); if(sknext) skb1 = skb_clone(skb, GFP_ATOMIC); @@ -1127,6 +1138,10 @@ int udp_rcv(struct sk_buff *skb) u32 daddr = skb->nh.iph->daddr; int len = skb->len; + vxdprintk(VXD_CBIT(net, 5), + "udp_rcv(%p[#%u]) %d.%d.%d.%d -> %d.%d.%d.%d", + skb, skb->nid, VXD_QUAD(saddr), VXD_QUAD(daddr)); + /* * Validate the packet and the UDP length. */ @@ -1148,7 +1163,12 @@ 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->nid); + + vxdprintk(VXD_CBIT(net, 5), + "udp_rcv(%p[#%u]) %p[#%u]", + skb, skb->nid, sk, sk ? sk->sk_nid : 0); if (sk != NULL) { int ret = udp_queue_rcv_skb(sk, skb);