tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Detached address check
On 22/11/2017 12:26, Roy Marples wrote:
On 22/11/2017 11:49, Roy Marples wrote:
That's a fair comment.
I've attached a patch which should fix this for IPv4 at least.
Simpler patch attached.
Now includes IPv6.
ping/ping6 and telnet to ipv4/ipv6 detached addresses works fine.
Let me know if this fixes everything for you please.
Roy
? sys/netinet6/.nd6_nbr.c.swp
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_input.c,v
retrieving revision 1.362
diff -u -p -r1.362 ip_input.c
--- sys/netinet/ip_input.c 17 Nov 2017 07:37:12 -0000 1.362
+++ sys/netinet/ip_input.c 22 Nov 2017 16:23:32 -0000
@@ -371,11 +371,14 @@ ip_match_our_address(struct ifnet *ifp,
continue;
if (checkif && ia->ia_ifp != ifp)
continue;
- if ((ia->ia_ifp->if_flags & IFF_UP) != 0 &&
- (ia->ia4_flags & IN_IFF_DETACHED) == 0)
- break;
- else
+ if ((ia->ia_ifp->if_flags & IFF_UP) == 0) {
(*downmatch)++;
+ continue;
+ }
+ if (ia->ia4_flags & IN_IFF_DETACHED &&
+ (ifp->if_flags & IFF_LOOPBACK) == 0)
+ continue;
+ break;
}
}
@@ -392,7 +395,10 @@ ip_match_our_address_broadcast(struct if
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
ia = ifatoia(ifa);
- if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
+ if (ia->ia4_flags & IN_IFF_NOTREADY)
+ continue;
+ if (ia->ia4_flags & IN_IFF_DETACHED &&
+ (ifp->if_flags & IFF_LOOPBACK) == 0)
continue;
if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) ||
in_hosteq(ip->ip_dst, ia->ia_netbroadcast) ||
Index: sys/netinet6/in6_src.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_src.c,v
retrieving revision 1.82
diff -u -p -r1.82 in6_src.c
--- sys/netinet6/in6_src.c 20 Nov 2017 09:01:20 -0000 1.82
+++ sys/netinet6/in6_src.c 22 Nov 2017 16:23:33 -0000
@@ -218,7 +218,7 @@ in6_select_best_ia(struct sockaddr_in6 *
/* avoid unusable addresses */
if ((ia->ia6_flags &
- (IN6_IFF_NOTREADY | IN6_IFF_ANYCAST | IN6_IFF_DETACHED))) {
+ (IN6_IFF_NOTREADY | IN6_IFF_ANYCAST))) {
continue;
}
if (!ip6_use_deprecated && IFA6_IS_DEPRECATED(ia))
Index: sys/netinet6/ip6_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.183
diff -u -p -r1.183 ip6_input.c
--- sys/netinet6/ip6_input.c 17 Nov 2017 07:37:12 -0000 1.183
+++ sys/netinet6/ip6_input.c 22 Nov 2017 16:23:33 -0000
@@ -501,13 +501,33 @@ ip6_input(struct mbuf *m, struct ifnet *
#endif
rt->rt_ifp->if_type == IFT_LOOP) {
struct in6_ifaddr *ia6 = (struct in6_ifaddr *)rt->rt_ifa;
+ int addrok;
+
if (ia6->ia6_flags & IN6_IFF_ANYCAST)
m->m_flags |= M_ANYCAST6;
/*
* packets to a tentative, duplicated, or somehow invalid
* address must not be accepted.
*/
- if (!(ia6->ia6_flags & (IN6_IFF_NOTREADY | IN6_IFF_DETACHED))) {
+ if (ia6->ia6_flags & IN6_IFF_NOTREADY)
+ addrok = 0;
+ else if (ia6->ia6_flags & IN6_IFF_DETACHED &&
+ !IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src))
+ {
+ /* Allow internal traffic to DETACHED addresses */
+ struct sockaddr_in6 sin6;
+ int s;
+
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_addr = ip6->ip6_src;
+ s = pserialize_read_enter();
+ addrok = (ifa_ifwithaddr(sin6tosa(&sin6)) != NULL);
+ pserialize_read_exit(s);
+ } else
+ addrok = 0;
+ if (addrok) {
/* this address is ready */
ours = 1;
deliverifp = ia6->ia_ifp; /* correct? */
Index: sys/netinet6/ip6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.193
diff -u -p -r1.193 ip6_output.c
--- sys/netinet6/ip6_output.c 2 Aug 2017 01:28:03 -0000 1.193
+++ sys/netinet6/ip6_output.c 22 Nov 2017 16:23:33 -0000
@@ -134,7 +134,7 @@ static int ip6_insert_jumboopt(struct ip
static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
static int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *, int *);
static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
-static int ip6_ifaddrvalid(const struct in6_addr *);
+static int ip6_ifaddrvalid(const struct in6_addr *, const struct in6_addr *);
static int ip6_handle_rthdr(struct ip6_rthdr *, struct ip6_hdr *);
#ifdef RFC2292
@@ -605,7 +605,9 @@ ip6_output(
/* scope check is done. */
/* Ensure we only send from a valid address. */
- if ((error = ip6_ifaddrvalid(&src0)) != 0) {
+ if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
+ (error = ip6_ifaddrvalid(&src0, &dst0)) != 0)
+ {
char ip6buf[INET6_ADDRSTRLEN];
nd6log(LOG_ERR,
"refusing to send from invalid address %s (pid %d)\n",
@@ -3363,27 +3365,31 @@ ip6_optlen(struct in6pcb *in6p)
* if the packet could be dropped without error (protocol dependent).
*/
static int
-ip6_ifaddrvalid(const struct in6_addr *addr)
+ip6_ifaddrvalid(const struct in6_addr *src, const struct in6_addr *dst)
{
struct sockaddr_in6 sin6;
int s, error;
struct ifaddr *ifa;
struct in6_ifaddr *ia6;
- if (IN6_IS_ADDR_UNSPECIFIED(addr))
+ if (IN6_IS_ADDR_UNSPECIFIED(src))
return 0;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
- sin6.sin6_addr = *addr;
+ sin6.sin6_addr = *src;
s = pserialize_read_enter();
ifa = ifa_ifwithaddr(sin6tosa(&sin6));
if ((ia6 = ifatoia6(ifa)) == NULL ||
ia6->ia6_flags & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED))
error = -1;
- else if (ia6->ia6_flags & (IN6_IFF_TENTATIVE | IN6_IFF_DETACHED))
+ else if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
+ error = 1;
+ else if (ia6->ia6_flags & IN6_IFF_DETACHED &&
+ ifa_ifwithaddr(sin6tosa(&dst)) == NULL)
+ /* Allow internal traffic to DETACHED addresses */
error = 1;
else
error = 0;
Home |
Main Index |
Thread Index |
Old Index