From aa818a825cc5808aab3eb2995af0b14b0418a3dd Mon Sep 17 00:00:00 2001 From: Mark Huang Date: Wed, 4 Aug 2004 20:25:34 +0000 Subject: [PATCH] remove VServer ipv4root checks in favor of VNET limitations --- include/linux/netfilter_ipv4/ip_conntrack.h | 4 + include/linux/skbuff.h | 1 + include/net/route.h | 73 +------------ include/net/sock.h | 6 ++ net/core/dev.c | 7 -- net/core/netfilter.c | 6 ++ net/core/rtnetlink.c | 4 - net/core/skbuff.c | 2 + net/ipv4/af_inet.c | 43 ++------ net/ipv4/devinet.c | 33 ------ net/ipv4/fib_hash.c | 4 +- net/ipv4/netfilter/ip_conntrack_standalone.c | 2 + net/ipv4/netfilter/ipt_MARK.c | 2 + net/ipv4/raw.c | 43 +------- net/ipv4/tcp_ipv4.c | 105 +++---------------- net/ipv4/tcp_minisocks.c | 2 + net/ipv4/udp.c | 35 +------ net/packet/af_packet.c | 20 +++- 18 files changed, 76 insertions(+), 316 deletions(-) diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 1974f162f..1ba82b408 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -8,6 +8,7 @@ #include #include #include +#include #include enum ip_conntrack_info @@ -207,6 +208,9 @@ struct ip_conntrack } nat; #endif /* CONFIG_IP_NF_NAT_NEEDED */ + /* VServer context id */ + xid_t xid; + }; /* get master conntrack via master expectation */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 3d0ba45fa..f139821c2 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -272,6 +272,7 @@ struct sk_buff { #endif #endif + xid_t xid; /* VServer context ID */ /* These elements must be at the end, see alloc_skb() for details. */ diff --git a/include/net/route.h b/include/net/route.h index 50c8cf024..a5e9c575e 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -33,9 +33,6 @@ #include #include #include -#include -#include -#include #ifndef __KERNEL__ #warning This file is not supposed to be used outside of kernel. @@ -151,59 +148,6 @@ static inline char rt_tos2priority(u8 tos) return ip_tos2prio[IPTOS_TOS(tos)>>1]; } -#define IPI_LOOPBACK 0x0100007f - -static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl) -{ - int err; - int i, n = nxi->nbipv4; - u32 ipv4root = nxi->ipv4[0]; - - if (ipv4root == 0) - return 0; - - if (fl->fl4_src == 0) { - if (n > 1) { - u32 foundsrc; - - err = __ip_route_output_key(rp, fl); - if (err) { - fl->fl4_src = ipv4root; - err = __ip_route_output_key(rp, fl); - } - if (err) - return err; - - foundsrc = (*rp)->rt_src; - ip_rt_put(*rp); - - for (i=0; imask[i]; - u32 ipv4 = nxi->ipv4[i]; - u32 net4 = ipv4 & mask; - - if (foundsrc == ipv4) { - fl->fl4_src = ipv4; - break; - } - if (!fl->fl4_src && (foundsrc & mask) == net4) - fl->fl4_src = ipv4; - } - } - if (fl->fl4_src == 0) - fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK) - ? IPI_LOOPBACK : ipv4root; - } else { - for (i=0; iipv4[i] == fl->fl4_src) - break; - } - if (i == n) - return -EPERM; - } - return 0; -} - static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif, u8 protocol, u16 sport, u16 dport, struct sock *sk) @@ -218,22 +162,7 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, .dport = dport } } }; int err; - struct nx_info *nx_info = current->nx_info; - - if (sk) - nx_info = sk->sk_nx_info; - vxdprintk("ip_route_connect(%p) %p,%p;%lx\n", - sk, nx_info, sk->sk_socket, - (sk->sk_socket?sk->sk_socket->flags:0)); - - if (nx_info) { - 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_dst || !fl.fl4_src) { + if (!dst || !src) { err = __ip_route_output_key(rp, &fl); if (err) return err; diff --git a/include/net/sock.h b/include/net/sock.h index 378766324..ec26f83a6 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1075,6 +1075,12 @@ static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) int err = 0; int skb_len; + /* Silently drop if the context is not entitled to read the + * packet. + */ + if (sk->sk_xid && sk->sk_xid != skb->xid) + goto out; + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces number of warnings when compiling with -W --ANK */ diff --git a/net/core/dev.c b/net/core/dev.c index 944cd9aa6..1e21cd988 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -108,7 +108,6 @@ #include #include #include -#include #ifdef CONFIG_NET_RADIO #include /* Note : will define WIRELESS_EXT */ #include @@ -2096,8 +2095,6 @@ static int dev_ifconf(char __user *arg) total = 0; for (dev = dev_base; dev; dev = dev->next) { - if (!dev_in_nx_info(dev, current->nx_info)) - continue; for (i = 0; i < NPROTO; i++) { if (gifconf_list[i]) { int done; @@ -2158,10 +2155,6 @@ void dev_seq_stop(struct seq_file *seq, void *v) static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) { - struct nx_info *nxi = current->nx_info; - - if (!dev_in_nx_info(dev, nxi)) - return; if (dev->get_stats) { struct net_device_stats *stats = dev->get_stats(dev); diff --git a/net/core/netfilter.c b/net/core/netfilter.c index 58632d189..e5e32b0a4 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c @@ -204,6 +204,9 @@ void nf_dump_skb(int pf, struct sk_buff *skb) for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++) printk(" O=0x%8.8X", *opt++); + printk(" MARK=%lu (0x%lu)", + (long unsigned int)skb->nfmark, + (long unsigned int)skb->nfmark); printk("\n"); } } @@ -831,3 +834,6 @@ EXPORT_SYMBOL(nf_setsockopt); EXPORT_SYMBOL(nf_unregister_hook); EXPORT_SYMBOL(nf_unregister_queue_handler); EXPORT_SYMBOL(nf_unregister_sockopt); +#ifdef CONFIG_NETFILTER_DEBUG +EXPORT_SYMBOL(nf_dump_skb); +#endif diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 95c97186c..e652d8fba 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -226,8 +226,6 @@ int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { if (idx < s_idx) continue; - if (!dev_in_nx_info(dev, current->nx_info)) - continue; if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0) <= 0) break; } @@ -313,8 +311,6 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) struct sk_buff *skb; int size = NLMSG_GOODSIZE; - if (!dev_in_nx_info(dev, current->nx_info)) - return; skb = alloc_skb(size, GFP_KERNEL); if (!skb) return; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0b44c0e25..2df876a10 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -333,6 +333,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) #endif #endif + C(xid); C(truesize); atomic_set(&n->users, 1); C(head); @@ -391,6 +392,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) #endif new->tc_index = old->tc_index; #endif + new->xid = old->xid; atomic_set(&new->users, 1); } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f4f7a57cb..2c0ac07bd 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -112,6 +112,9 @@ #ifdef CONFIG_IP_MROUTE #include #endif +#include +#include +#include DEFINE_SNMP_STAT(struct linux_mib, net_statistics); @@ -427,10 +430,6 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) unsigned short snum; int chk_addr_ret; int err; - __u32 s_addr; /* Address used for validation */ - __u32 s_addr1; - __u32 s_addr2 = 0xffffffffl; /* Optional address of 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) { @@ -441,36 +440,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (addr_len < sizeof(struct sockaddr_in)) goto out; - s_addr = s_addr1 = addr->sin_addr.s_addr; - nxdprintk("inet_bind(%p) %p,%p;%lx\n", - sk, nx_info, sk->sk_socket, - (sk->sk_socket?sk->sk_socket->flags:0)); - if (nxi) { - __u32 v4_bcast = nxi->v4_bcast; - __u32 ipv4root = nxi->ipv4[0]; - int nbipv4 = nxi->nbipv4; - if (s_addr == 0) { - s_addr = ipv4root; - if (nbipv4 > 1) - s_addr1 = 0; - else { - s_addr1 = ipv4root; - } - s_addr2 = v4_bcast; - } else if (s_addr == 0x0100007f) { - s_addr = s_addr1 = ipv4root; - } else if (s_addr != v4_bcast) { - int i; - for (i=0; iipv4[i]) - break; - } - if (i == nbipv4) { - return -EADDRNOTAVAIL; - } - } - } - chk_addr_ret = inet_addr_type(s_addr); + 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 @@ -482,7 +452,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 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) @@ -507,8 +477,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 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 --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 8749432da..2dc4e7a8a 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -488,33 +488,6 @@ static __inline__ int inet_abc_len(u32 addr) return rc; } -/* - Check that a device is not member of the ipv4root assigned to the process - Return true if this is the case - - If the process is not bound to specific IP, then it returns 0 (all - interface are fine). -*/ -static inline int devinet_notiproot (struct in_ifaddr *ifa) -{ - int ret = 0; - struct nx_info *nxi; - - if ((nxi = current->nx_info)) { - int i; - int nbip = nxi->nbipv4; - __u32 addr = ifa->ifa_local; - ret = 1; - for (i=0; iipv4[i] == addr) { - ret = 0; - break; - } - } - } - return ret; -} - int devinet_ioctl(unsigned int cmd, void __user *arg) { @@ -622,8 +595,6 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) ret = -EADDRNOTAVAIL; if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) goto done; - if (!ifa_in_nx_info(ifa, current->nx_info)) - goto done; switch(cmd) { case SIOCGIFADDR: /* Get interface address */ @@ -767,8 +738,6 @@ static int inet_gifconf(struct net_device *dev, char __user *buf, int len) goto out; for (; ifa; ifa = ifa->ifa_next) { - if (!ifa_in_nx_info(ifa, current->nx_info)) - continue; if (!buf) { done += sizeof(ifr); continue; @@ -1104,8 +1073,6 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) read_lock(&in_dev->lock); for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { - if (!ifa_in_nx_info(ifa, current->nx_info)) - continue; if (ip_idx < s_ip_idx) continue; if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 3b4f8e35e..2316dfa91 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -1010,8 +1010,6 @@ static unsigned fib_flag_trans(int type, int dead, u32 mask, struct fib_info *fi return flags; } -extern int dev_in_nx_info(struct net_device *, struct nx_info *); - /* * This outputs /proc/net/route. * @@ -1041,7 +1039,7 @@ static int fib_seq_show(struct seq_file *seq, void *v) mask = FZ_MASK(iter->zone); flags = fib_flag_trans(f->fn_type, f->fn_state & FN_S_ZOMBIE, mask, fi); - if (fi && dev_in_nx_info(fi->fib_dev, current->nx_info)) + if (fi) 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 --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 80edac904..fe5a980ba 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -111,6 +111,8 @@ print_conntrack(char *buffer, struct ip_conntrack *conntrack) len += sprintf(buffer + len, "[ASSURED] "); len += sprintf(buffer + len, "use=%u ", atomic_read(&conntrack->ct_general.use)); + len += sprintf(buffer + len, "xid=%d ", + conntrack->xid); len += sprintf(buffer + len, "\n"); return len; diff --git a/net/ipv4/netfilter/ipt_MARK.c b/net/ipv4/netfilter/ipt_MARK.c index 06bcb8d55..0931c145b 100644 --- a/net/ipv4/netfilter/ipt_MARK.c +++ b/net/ipv4/netfilter/ipt_MARK.c @@ -50,10 +50,12 @@ checkentry(const char *tablename, return 0; } +#if 0 if (strcmp(tablename, "mangle") != 0) { printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); return 0; } +#endif return 1; } diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index b95639034..41aaa7c0a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -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,38 +103,6 @@ static void raw_v4_unhash(struct sock *sk) write_unlock_bh(&raw_v4_lock); } - -/* - Check if an address is in the list -*/ -static inline int raw_addr_in_list ( - u32 rcv_saddr1, - u32 rcv_saddr2, - u32 loc_addr, - struct nx_info *nx_info) -{ - int ret = 0; - if (loc_addr != 0 && - (rcv_saddr1 == loc_addr || rcv_saddr2 == loc_addr)) - ret = 1; - else if (rcv_saddr1 == 0) { - /* Accept any address or only the one in the list */ - if (nx_info == NULL) - ret = 1; - else { - int n = nx_info->nbipv4; - int i; - for (i=0; iipv4[i] == loc_addr) { - ret = 1; - break; - } - } - } - } - return ret; -} - struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, unsigned long raddr, unsigned long laddr, int dif) @@ -145,8 +114,7 @@ struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, if (inet->num == num && !(inet->daddr && inet->daddr != raddr) && - raw_addr_in_list(inet->rcv_saddr, inet->rcv_saddr2, - laddr, sk->sk_nx_info) && + !(inet->rcv_saddr && inet->rcv_saddr != laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) goto found; /* gotcha */ } @@ -462,13 +430,6 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, .proto = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, }; - - if (sk->sk_nx_info) { - err = ip_find_src(sk->sk_nx_info, &rt, &fl); - - if (err) - goto done; - } err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); } if (err) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1f268b79c..97a0eeafc 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -75,6 +75,8 @@ #include #include +#include + extern int sysctl_ip_dynaddr; int sysctl_tcp_tw_reuse; int sysctl_tcp_low_latency; @@ -179,63 +181,9 @@ void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, tcp_sk(sk)->bind_hash = tb; } -/* - Return 1 if addr match the socket IP list - or the socket is INADDR_ANY -*/ -static inline int tcp_in_list(struct sock *sk, u32 addr) -{ - struct nx_info *nxi = sk->sk_nx_info; - - vxdprintk("tcp_in_list(%p) %p,%p;%lx\n", - sk, nxi, sk->sk_socket, - (sk->sk_socket?sk->sk_socket->flags:0)); - - if (nxi) { - int n = nxi->nbipv4; - int i; - - for (i=0; iipv4[i] == addr) - return 1; - } - else if (!tcp_v4_rcv_saddr(sk) || tcp_v4_rcv_saddr(sk) == addr) - return 1; - return 0; -} - -/* - Check if the addresses in sk1 conflict with those in sk2 -*/ -int tcp_ipv4_addr_conflict(struct sock *sk1, struct sock *sk2) -{ - if (sk1 && sk2) - nxdprintk("inet_bind(%p,%p) %p,%p;%lx %p,%p;%lx\n", - sk1, sk2, - sk1->sk_nx_info, sk1->sk_socket, - (sk1->sk_socket?sk1->sk_socket->flags:0), - sk2->sk_nx_info, sk2->sk_socket, - (sk2->sk_socket?sk2->sk_socket->flags:0)); - - if (tcp_v4_rcv_saddr(sk1)) { - /* Bind to one address only */ - return tcp_in_list (sk2, tcp_v4_rcv_saddr(sk1)); - } else if (sk1->sk_nx_info) { - /* A restricted bind(any) */ - struct nx_info *nxi = sk1->sk_nx_info; - int n = nxi->nbipv4; - int i; - - for (i=0; iipv4[i])) - return 1; - } else /* A bind(any) do not allow other bind on the same port */ - return 1; - return 0; -} - static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb) { + const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk); struct sock *sk2; struct hlist_node *node; int reuse = sk->sk_reuse; @@ -248,7 +196,9 @@ static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb) sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { if (!reuse || !sk2->sk_reuse || sk2->sk_state == TCP_LISTEN) { - if (tcp_ipv4_addr_conflict(sk, sk2)) + const u32 sk2_rcv_saddr = tcp_v4_rcv_saddr(sk2); + if (!sk2_rcv_saddr || !sk_rcv_saddr || + sk2_rcv_saddr == sk_rcv_saddr) break; } } @@ -457,34 +407,6 @@ void tcp_unhash(struct sock *sk) wake_up(&tcp_lhash_wait); } -/* - Check if an address is in the list -*/ -static inline int tcp_addr_in_list( - u32 rcv_saddr, - u32 daddr, - struct nx_info *nx_info) -{ - if (rcv_saddr == daddr) - return 1; - else if (rcv_saddr == 0) { - /* Accept any address or check the list */ - if (!nx_info) - return 1; - else { - int n = nx_info->nbipv4; - int i; - - for (i=0; iipv4[i] == daddr) - return 1; - } - } - return 0; -} - - - /* Don't inline this cruft. Here are some nice properties to * exploit here. The BSD API does not allow a listening TCP * to specify the remote port nor the remote address for the @@ -506,10 +428,11 @@ static struct sock *__tcp_v4_lookup_listener(struct hlist_head *head, u32 daddr, __u32 rcv_saddr = inet->rcv_saddr; score = (sk->sk_family == PF_INET ? 1 : 0); - if (tcp_addr_in_list(rcv_saddr, daddr, sk->sk_nx_info)) + if (rcv_saddr) { + if (rcv_saddr != daddr) + continue; score+=2; - else - continue; + } if (sk->sk_bound_dev_if) { if (sk->sk_bound_dev_if != dif) continue; @@ -538,8 +461,8 @@ inline struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum, if (!hlist_empty(head)) { struct inet_opt *inet = inet_sk((sk = __sk_head(head))); if (inet->num == hnum && !sk->sk_node.next && + (!inet->rcv_saddr || inet->rcv_saddr == daddr) && (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && - tcp_addr_in_list(inet->rcv_saddr, daddr, sk->sk_nx_info) && !sk->sk_bound_dev_if) goto sherry_cache; sk = __tcp_v4_lookup_listener(head, daddr, hnum, dif); @@ -1891,6 +1814,12 @@ int tcp_v4_rcv(struct sk_buff *skb) goto no_tcp_socket; process: + /* Silently drop if the context is not entitled to read the + * packet. + */ + if (sk->sk_xid && sk->sk_xid != skb->xid) + goto discard_it; + if (sk->sk_state == TCP_TIME_WAIT) goto do_time_wait; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 14115413d..a8da77f4d 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ec17e3218..9c64e4565 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -107,6 +107,7 @@ #include #include #include +#include /* * Snmp MIB for the UDP layer @@ -120,8 +121,6 @@ rwlock_t udp_hash_lock = RW_LOCK_UNLOCKED; /* Shared by v4/v6 udp. */ int udp_port_rover; -int tcp_ipv4_addr_conflict(struct sock *sk1, struct sock *sk2); - static int udp_v4_get_port(struct sock *sk, unsigned short snum) { struct hlist_node *node; @@ -181,7 +180,9 @@ gotit: (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && - tcp_ipv4_addr_conflict(sk2, sk) && + (!inet2->rcv_saddr || + !inet->rcv_saddr || + inet2->rcv_saddr == inet->rcv_saddr) && (!sk2->sk_reuse || !sk->sk_reuse)) goto fail; } @@ -216,17 +217,6 @@ static void udp_v4_unhash(struct sock *sk) 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 */ @@ -246,11 +236,6 @@ struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, i if (inet->rcv_saddr != daddr) continue; score+=2; - } else if (sk->sk_nx_info) { - if (udp_in_list(sk->sk_nx_info, daddr)) - score+=2; - else - continue; } if (inet->daddr) { if (inet->daddr != saddr) @@ -306,8 +291,7 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk, 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; @@ -616,15 +600,6 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, .uli_u = { .ports = { .sport = inet->sport, .dport = dport } } }; - struct nx_info *nxi = sk->sk_nx_info; - - if (nxi) { - 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) goto out; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 93ac3b310..429cb4b96 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -70,6 +70,9 @@ #include #include #include +#include +#include +#include #ifdef CONFIG_INET #include @@ -217,6 +220,8 @@ void packet_sock_destruct(struct sock *sk) { BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); + BUG_ON(sk->sk_nx_info); + BUG_ON(sk->sk_vx_info); if (!sock_flag(sk, SOCK_DEAD)) { printk("Attempt to release alive packet socket: %p\n", sk); @@ -449,6 +454,9 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packe sk = pt->af_packet_priv; po = pkt_sk(sk); + if (sk->sk_xid && sk->sk_xid != skb->xid) + goto drop; + skb->dev = dev; if (dev->hard_header) { @@ -819,6 +827,9 @@ static int packet_release(struct socket *sock) } #endif + clr_vx_info(&sk->sk_vx_info); + clr_nx_info(&sk->sk_nx_info); + /* * Now the socket is dead. No more input will appear. */ @@ -994,6 +1005,11 @@ static int packet_create(struct socket *sock, int protocol) sk->sk_destruct = packet_sock_destruct; atomic_inc(&packet_socks_nr); + set_vx_info(&sk->sk_vx_info, current->vx_info); + sk->sk_xid = vx_current_xid(); + set_nx_info(&sk->sk_nx_info, current->nx_info); + sk->sk_nid = nx_current_nid(); + /* * Attach a protocol block */ @@ -1779,12 +1795,14 @@ struct proto_ops packet_ops = { .mmap = packet_mmap, .sendpage = sock_no_sendpage, }; +EXPORT_SYMBOL(packet_ops); -static struct net_proto_family packet_family_ops = { +struct net_proto_family packet_family_ops = { .family = PF_PACKET, .create = packet_create, .owner = THIS_MODULE, }; +EXPORT_SYMBOL(packet_family_ops); static struct notifier_block packet_netdev_notifier = { .notifier_call =packet_notifier, -- 2.47.0