so now that the loopback link1 crap is out of the way - use the rb
tree for local address lookup in ip_input instead of traversing the
list of interfaces traversing the list of addresses on them linearily.
this needs heavy testing. last not least somebody please throw this on
his rarpd server and netboot a sparc against it so that the compat
hack for classful broadcast is tested. otherwise, just stuff binding
to local addresses and make sure you can reach it from another box.
the printf is not to stay of course, but useful while testing.
Index: netinet/in_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.113
diff -u -p -r1.113 in_pcb.c
--- netinet/in_pcb.c 3 Jul 2010 04:44:51 -0000 1.113
+++ netinet/in_pcb.c 2 Apr 2011 15:30:10 -0000
@@ -276,8 +276,7 @@ in_pcbbind(v, nam, p)
} else if (sin->sin_addr.s_addr != INADDR_ANY) {
sin->sin_port = 0; /* yech... */
if (!(so->so_options & SO_BINDANY) &&
- in_iawithaddr(sin->sin_addr, NULL,
- inp->inp_rtableid) == 0)
+ !ifa_ifwithaddr(sintosa(sin), inp->inp_rtableid))
return (EADDRNOTAVAIL);
}
if (lport) {
Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.187
diff -u -p -r1.187 ip_input.c
--- netinet/ip_input.c 2 Apr 2011 14:38:09 -0000 1.187
+++ netinet/ip_input.c 2 Apr 2011 15:30:11 -0000
@@ -144,6 +144,9 @@ struct pool ipq_pool;
struct ipstat ipstat;
+struct in_ifaddr *
+ in_iawithaddr(struct in_addr, struct mbuf *, u_int);
+
char *
inet_ntoa(ina)
struct in_addr ina;
@@ -682,30 +685,33 @@ bad:
struct in_ifaddr *
in_iawithaddr(struct in_addr ina, struct mbuf *m, u_int rdomain)
{
- struct in_ifaddr *ia;
+ struct in_ifaddr *ia;
+ struct sockaddr_in sin;
- rdomain = rtable_l2(rdomain);
- TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
- if (ia->ia_ifp->if_rdomain != rdomain)
- continue;
- if (ina.s_addr == ia->ia_addr.sin_addr.s_addr)
- return ia;
- /* check ancient classful too, e. g. for rarp-based netboot */
- if (((ip_directedbcast == 0) || (m && ip_directedbcast &&
- ia->ia_ifp == m->m_pkthdr.rcvif)) &&
- (ia->ia_ifp->if_flags & IFF_BROADCAST)) {
- if (ina.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
+ bzero(&sin, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr = ina;
+ ia = (struct in_ifaddr *)ifa_ifwithaddr(sintosa(&sin), rdomain);
+printf("in_iawithaddr ina=%s: %s\n", inet_ntoa(ina), ia ? "yay" : "rotten
shark");
+
+ /* check ancient classful, e. g. for rarp-based netboot */
+ if (ia == NULL && m->m_flags | M_BCAST &&
+ IN_CLASSFULBROADCAST(ina.s_addr, ina.s_addr)) {
+ TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
+ if (ia->ia_ifp->if_rdomain != rdomain)
+ continue;
+ if (((ip_directedbcast == 0) ||
+ (m && ip_directedbcast &&
+ ia->ia_ifp == m->m_pkthdr.rcvif)) &&
+ (ia->ia_ifp->if_flags & IFF_BROADCAST) &&
IN_CLASSFULBROADCAST(ina.s_addr,
- ia->ia_addr.sin_addr.s_addr)) {
- /* Make sure M_BCAST is set */
- if (m)
- m->m_flags |= M_BCAST;
- return ia;
- }
+ ia->ia_addr.sin_addr.s_addr))
+ return (ia);
}
}
- return NULL;
+ return (ia);
}
/*
Index: netinet/ip_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_var.h,v
retrieving revision 1.39
diff -u -p -r1.39 ip_var.h
--- netinet/ip_var.h 5 Jun 2009 00:05:22 -0000 1.39
+++ netinet/ip_var.h 2 Apr 2011 15:30:11 -0000
@@ -172,8 +172,6 @@ int ip_pcbopts(struct mbuf **, struct m
struct mbuf *
ip_reass(struct ipqent *, struct ipq *);
struct in_ifaddr *
- in_iawithaddr(struct in_addr, struct mbuf *, u_int);
-struct in_ifaddr *
ip_rtaddr(struct in_addr, u_int);
u_int16_t
ip_randomid(void);
Index: netinet/raw_ip.c
===================================================================
RCS file: /cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.50
diff -u -p -r1.50 raw_ip.c
--- netinet/raw_ip.c 8 Sep 2010 08:34:42 -0000 1.50
+++ netinet/raw_ip.c 2 Apr 2011 15:30:11 -0000
@@ -422,8 +422,7 @@ rip_usrreq(struct socket *so, int req, s
(addr->sin_family != AF_IMPLINK)) ||
(addr->sin_addr.s_addr &&
(!(so->so_options & SO_BINDANY) &&
- in_iawithaddr(addr->sin_addr, NULL, inp->inp_rtableid) ==
- 0))) {
+ !ifa_ifwithaddr(sintosa(addr), inp->inp_rtableid)))) {
error = EADDRNOTAVAIL;
break;
}
--
Henning Brauer, [email protected], [email protected]
BS Web Services, http://bsws.de
Full-Service ISP - Secure Hosting, Mail and DNS Services
Dedicated Servers, Rootservers, Application Hosting