FreeBSD Bugzilla – Attachment 22174 Details for
Bug 38554
[patch] changing interface ipaddress doesn't seem to work
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
archie-current.diff
archie-current.diff (text/plain; charset=us-ascii), 12.00 KB, created by
Bruce M Simpson
on 2004-07-03 09:09:00 UTC
(
hide
)
Description:
archie-current.diff
Filename:
MIME Type:
Creator:
Bruce M Simpson
Created:
2004-07-03 09:09:00 UTC
Size:
12.00 KB
patch
obsolete
>Index: in.c >=================================================================== >RCS file: /home/ncvs/src/sys/netinet/in.c,v >retrieving revision 1.75 >diff -u -p -r1.75 in.c >--- in.c 7 Apr 2004 20:46:13 -0000 1.75 >+++ in.c 3 Jul 2004 07:40:19 -0000 >@@ -420,6 +420,11 @@ in_control(so, cmd, data, ifp, td) > */ > in_ifadown(&ia->ia_ifa, 1); > /* >+ * Mark the interface address as no longer valid. >+ * Sockets that are bound to it should notice. >+ */ >+ ia->ia_ifa.ifa_flags |= RTF_REJECT; >+ /* > * XXX horrible hack to detect that we are being called > * from if_detach() > */ >Index: in_pcb.c >=================================================================== >RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v >retrieving revision 1.150 >diff -u -p -r1.150 in_pcb.c >--- in_pcb.c 16 Jun 2004 10:02:36 -0000 1.150 >+++ in_pcb.c 3 Jul 2004 07:47:54 -0000 >@@ -53,6 +53,7 @@ > #include <net/if.h> > #include <net/if_types.h> > #include <net/route.h> >+#include <net/net_osdep.h> > > #include <netinet/in.h> > #include <netinet/in_pcb.h> >@@ -228,14 +229,17 @@ in_pcbbind(inp, nam, cred) > anonport = inp->inp_lport == 0 && (nam == NULL || > ((struct sockaddr_in *)nam)->sin_port == 0); > error = in_pcbbind_setup(inp, nam, &inp->inp_laddr.s_addr, >- &inp->inp_lport, cred); >+ &inp->inp_lport, &inp->inp_locia, cred); > if (error) > return (error); > if (in_pcbinshash(inp) != 0) { > inp->inp_laddr.s_addr = INADDR_ANY; > inp->inp_lport = 0; >+ inp->inp_locia = NULL; > return (EAGAIN); > } >+ if (inp->inp_locia != NULL) >+ IFAREF(&inp->inp_locia->ia_ifa); > if (anonport) > inp->inp_flags |= INP_ANONPORT; > return (0); >@@ -251,17 +255,19 @@ in_pcbbind(inp, nam, cred) > * On error, the values of *laddrp and *lportp are not changed. > */ > int >-in_pcbbind_setup(inp, nam, laddrp, lportp, cred) >+in_pcbbind_setup(inp, nam, laddrp, lportp, iap, cred) > struct inpcb *inp; > struct sockaddr *nam; > in_addr_t *laddrp; > u_short *lportp; >+ struct in_ifaddr **iap; > struct ucred *cred; > { > struct socket *so = inp->inp_socket; > unsigned short *lastport; > struct sockaddr_in *sin; > struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; >+ struct in_ifaddr *ia = NULL; > struct in_addr laddr; > u_short lport = 0; > int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); >@@ -312,7 +318,8 @@ in_pcbbind_setup(inp, nam, laddrp, lport > } else if (sin->sin_addr.s_addr != INADDR_ANY) { > sin->sin_port = 0; /* yech... */ > bzero(&sin->sin_zero, sizeof(sin->sin_zero)); >- if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) >+ if ((ia = (struct in_ifaddr *)ifa_ifwithaddr( >+ (struct sockaddr *)sin)) == 0) > return (EADDRNOTAVAIL); > } > laddr = sin->sin_addr; >@@ -451,6 +458,8 @@ in_pcbbind_setup(inp, nam, laddrp, lport > return (EINVAL); > *laddrp = laddr.s_addr; > *lportp = lport; >+ if (iap != NULL) >+ *iap = ia; > return (0); > } > >@@ -468,13 +477,14 @@ in_pcbconnect(inp, nam, cred) > { > u_short lport, fport; > in_addr_t laddr, faddr; >+ struct in_ifaddr *locia; > int anonport, error; > > lport = inp->inp_lport; > laddr = inp->inp_laddr.s_addr; > anonport = (lport == 0); > error = in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport, >- NULL, cred); >+ NULL, &locia, cred); > if (error) > return (error); > >@@ -492,6 +502,9 @@ in_pcbconnect(inp, nam, cred) > /* Commit the remaining changes. */ > inp->inp_lport = lport; > inp->inp_laddr.s_addr = laddr; >+ inp->inp_locia = locia; >+ if (inp->inp_locia != NULL) >+ IFAREF(&inp->inp_locia->ia_ifa); > inp->inp_faddr.s_addr = faddr; > inp->inp_fport = fport; > in_pcbrehash(inp); >@@ -509,7 +522,9 @@ in_pcbconnect(inp, nam, cred) > * On entry, *laddrp and *lportp should contain the current local > * address and port for the PCB; these are updated to the values > * that should be placed in inp_laddr and inp_lport to complete >- * the connect. >+ * the connect. If iap is not NULL, *iap is set to the interface >+ * address corresponding to *laddrp, if any, but no new reference >+ * to it has been added. > * > * On success, *faddrp and *fportp will be set to the remote address > * and port. These are not updated in the error case. >@@ -520,7 +535,7 @@ in_pcbconnect(inp, nam, cred) > * is set to NULL. > */ > int >-in_pcbconnect_setup(inp, nam, laddrp, lportp, faddrp, fportp, oinpp, cred) >+in_pcbconnect_setup(inp, nam, laddrp, lportp, faddrp, fportp, oinpp, iap, cred) > register struct inpcb *inp; > struct sockaddr *nam; > in_addr_t *laddrp; >@@ -528,10 +543,11 @@ in_pcbconnect_setup(inp, nam, laddrp, lp > in_addr_t *faddrp; > u_short *fportp; > struct inpcb **oinpp; >+ struct in_ifaddr **iap; > struct ucred *cred; > { > struct sockaddr_in *sin = (struct sockaddr_in *)nam; >- struct in_ifaddr *ia; >+ struct in_ifaddr *ia = NULL; > struct sockaddr_in sa; > struct ucred *socred; > struct inpcb *oinp; >@@ -558,7 +574,7 @@ in_pcbconnect_setup(inp, nam, laddrp, lp > sa.sin_len = sizeof(sa); > sa.sin_family = AF_INET; > error = in_pcbbind_setup(inp, (struct sockaddr *)&sa, >- &laddr.s_addr, &lport, cred); >+ &laddr.s_addr, &lport, &ia, cred); > if (error) > return (error); > } >@@ -648,7 +664,7 @@ in_pcbconnect_setup(inp, nam, laddrp, lp > } > if (lport == 0) { > error = in_pcbbind_setup(inp, NULL, &laddr.s_addr, &lport, >- cred); >+ &ia, cred); > if (error) > return (error); > } >@@ -656,6 +672,8 @@ in_pcbconnect_setup(inp, nam, laddrp, lp > *lportp = lport; > *faddrp = faddr.s_addr; > *fportp = fport; >+ if (iap != NULL) >+ *iap = ia; > return (0); > } > >@@ -694,6 +712,8 @@ in_pcbdetach(inp) > so->so_pcb = 0; > sotryfree(so); > } >+ if (inp->inp_locia != NULL) >+ IFAFREE(&inp->inp_locia->ia_ifa); > if (inp->inp_options) > (void)m_free(inp->inp_options); > ip_freemoptions(inp->inp_moptions); >Index: in_pcb.h >=================================================================== >RCS file: /home/ncvs/src/sys/netinet/in_pcb.h,v >retrieving revision 1.73 >diff -u -p -r1.73 in_pcb.h >--- in_pcb.h 24 Jun 2004 02:01:48 -0000 1.73 >+++ in_pcb.h 3 Jul 2004 07:49:32 -0000 >@@ -71,6 +71,7 @@ struct in_addr_4in6 { > struct in_endpoints { > u_int16_t ie_fport; /* foreign port */ > u_int16_t ie_lport; /* local port */ >+ struct in_ifaddr *ie_locia; /* locally bound address */ > /* protocol dependent part, local and foreign addr */ > union { > /* foreign host table entry */ >@@ -102,6 +103,7 @@ struct in_conninfo { > #define inc_isipv6 inc_flags /* temp compatability */ > #define inc_fport inc_ie.ie_fport > #define inc_lport inc_ie.ie_lport >+#define inc_locia inc_ie.ie_locia > #define inc_faddr inc_ie.ie_faddr > #define inc_laddr inc_ie.ie_laddr > #define inc6_faddr inc_ie.ie6_faddr >@@ -142,6 +144,7 @@ struct inpcb { > } inp_depend4; > #define inp_fport inp_inc.inc_fport > #define inp_lport inp_inc.inc_lport >+#define inp_locia inp_inc.inc_locia > #define inp_faddr inp_inc.inc_faddr > #define inp_laddr inp_inc.inc_laddr > #define inp_ip_tos inp_depend4.inp4_ip_tos >@@ -340,6 +343,8 @@ struct inpcbinfo { /* XXX documentation > #define INP_CHECK_SOCKAF(so, af) (INP_SOCKAF(so) == af) > > #ifdef _KERNEL >+struct in_ifaddr; >+ > extern int ipport_lowfirstauto; > extern int ipport_lowlastauto; > extern int ipport_firstauto; >@@ -351,11 +356,11 @@ void in_pcbpurgeif0(struct inpcbinfo *, > int in_pcballoc(struct socket *, struct inpcbinfo *, const char *); > int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *); > int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *, >- u_short *, struct ucred *); >+ u_short *, struct in_ifaddr **, struct ucred *); > int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *); > int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *, > u_short *, in_addr_t *, u_short *, struct inpcb **, >- struct ucred *); >+ struct in_ifaddr **, struct ucred *); > void in_pcbdetach(struct inpcb *); > void in_pcbdisconnect(struct inpcb *); > int in_pcbinshash(struct inpcb *); >Index: tcp_output.c >=================================================================== >RCS file: /home/ncvs/src/sys/netinet/tcp_output.c,v >retrieving revision 1.95 >diff -u -p -r1.95 tcp_output.c >--- tcp_output.c 23 Jun 2004 21:04:37 -0000 1.95 >+++ tcp_output.c 3 Jul 2004 07:40:19 -0000 >@@ -51,12 +51,15 @@ > #include <sys/sysctl.h> > > #include <net/route.h> >+#include <net/if.h> >+#include <net/if_var.h> > > #include <netinet/in.h> > #include <netinet/in_systm.h> > #include <netinet/ip.h> > #include <netinet/in_pcb.h> > #include <netinet/ip_var.h> >+#include <netinet/in_var.h> > #ifdef INET6 > #include <netinet6/in6_pcb.h> > #include <netinet/ip6.h> >@@ -804,6 +807,16 @@ send: > } > > /* >+ * Check that our local (source) IP address is still valid. >+ */ >+ if (tp->t_inpcb->inp_locia != NULL >+ && (tp->t_inpcb->inp_locia->ia_ifa.ifa_flags & RTF_REJECT) != 0) { >+ error = EADDRNOTAVAIL; >+ m_freem(m); >+ goto out; >+ } >+ >+ /* > * Fill in fields, remembering maximum advertised > * window for use in delaying messages about window sizes. > * If resending a FIN, be sure not to use a new sequence number. >Index: tcp_usrreq.c >=================================================================== >RCS file: /home/ncvs/src/sys/netinet/tcp_usrreq.c,v >retrieving revision 1.103 >diff -u -p -r1.103 tcp_usrreq.c >--- tcp_usrreq.c 26 Jun 2004 17:50:50 -0000 1.103 >+++ tcp_usrreq.c 3 Jul 2004 07:51:41 -0000 >@@ -51,6 +51,7 @@ > #include <sys/jail.h> > > #include <net/if.h> >+#include <net/net_osdep.h> > #include <net/route.h> > > #include <netinet/in.h> >@@ -817,6 +818,7 @@ tcp_connect(tp, nam, td) > struct socket *so = inp->inp_socket; > struct tcptw *otw; > struct rmxp_tao tao; >+ struct in_ifaddr *locia; > struct in_addr laddr; > u_short lport; > int error; >@@ -836,8 +838,10 @@ tcp_connect(tp, nam, td) > */ > laddr = inp->inp_laddr; > lport = inp->inp_lport; >+ locia = inp->inp_locia; > error = in_pcbconnect_setup(inp, nam, &laddr.s_addr, &lport, >- &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred); >+ &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, &locia, >+ td->td_ucred); > if (error && oinp == NULL) > return error; > if (oinp) { >@@ -852,6 +856,11 @@ tcp_connect(tp, nam, td) > return EADDRINUSE; > } > inp->inp_laddr = laddr; >+ if (inp->inp_locia != NULL) >+ IFAFREE(&inp->inp_locia->ia_ifa); >+ inp->inp_locia = locia; >+ if (inp->inp_locia != NULL) >+ IFAREF(&inp->inp_locia->ia_ifa); > in_pcbrehash(inp); > > /* Compute window scaling to request. */ >Index: udp_usrreq.c >=================================================================== >RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v >retrieving revision 1.156 >diff -u -p -r1.156 udp_usrreq.c >--- udp_usrreq.c 26 Jun 2004 19:10:39 -0000 1.156 >+++ udp_usrreq.c 3 Jul 2004 07:52:53 -0000 >@@ -724,6 +724,7 @@ udp_output(inp, m, addr, control, td) > { > register struct udpiphdr *ui; > register int len = m->m_pkthdr.len; >+ struct in_ifaddr *locia; > struct in_addr faddr, laddr; > struct cmsghdr *cm; > struct sockaddr_in *sin, src; >@@ -792,13 +793,14 @@ udp_output(inp, m, addr, control, td) > goto release; > laddr = inp->inp_laddr; > lport = inp->inp_lport; >+ locia = inp->inp_locia; > if (src.sin_addr.s_addr != INADDR_ANY) { > if (lport == 0) { > error = EINVAL; > goto release; > } > error = in_pcbbind_setup(inp, (struct sockaddr *)&src, >- &laddr.s_addr, &lport, td->td_ucred); >+ &laddr.s_addr, &lport, &locia, td->td_ucred); > if (error) > goto release; > } >@@ -812,7 +814,7 @@ udp_output(inp, m, addr, control, td) > goto release; > } > error = in_pcbconnect_setup(inp, addr, &laddr.s_addr, &lport, >- &faddr.s_addr, &fport, NULL, td->td_ucred); >+ &faddr.s_addr, &fport, NULL, &locia, td->td_ucred); > if (error) > goto release; > >@@ -835,6 +837,15 @@ udp_output(inp, m, addr, control, td) > goto release; > } > } >+ >+ /* >+ * Check that the local (source) IP address is valid. >+ */ >+ if (locia != NULL && (locia->ia_ifa.ifa_flags & RTF_REJECT) != 0) { >+ error = EADDRNOTAVAIL; >+ goto release; >+ } >+ > /* > * Calculate data length and get a mbuf > * for UDP and IP headers. >@@ -1054,6 +1065,10 @@ udp_disconnect(struct socket *so) > s = splnet(); > in_pcbdisconnect(inp); > inp->inp_laddr.s_addr = INADDR_ANY; >+ if (inp->inp_locia != NULL) { >+ IFAFREE(&inp->inp_locia->ia_ifa); >+ inp->inp_locia = NULL; >+ } > INP_UNLOCK(inp); > INP_INFO_WUNLOCK(&udbinfo); > splx(s);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 38554
: 22174 |
22175