Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Jan 2014 12:13:56 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r260508 - in head/sys: net netinet
Message-ID:  <201401101213.s0ACDunV085406@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Fri Jan 10 12:13:55 2014
New Revision: 260508
URL: http://svnweb.freebsd.org/changeset/base/260508

Log:
  Simplify inet alias handling code: if we're adding/removing alias which
  has the same prefix as some other alias on the same interface, use
  newly-added rt_addrmsg() instead of hand-rolled in_addralias_rtmsg().
  
  This eliminates the following rtsock messages:
  
  Pinned RTM_ADD for prefix (for alias addition).
  Pinned RTM_DELETE for prefix (for alias withdrawal).
  
  Example (got 10.0.0.1/24 on vlan4, playing with 10.0.0.2/24):
  
  before commit, addition:
  
    got message of size 116 on Fri Jan 10 14:13:15 2014
    RTM_NEWADDR: address being added to iface: len 116, metric 0, flags:
    sockaddrs: <NETMASK,IFP,IFA,BRD>
     255.255.255.0 vlan4:8.0.27.c5.29.d4 10.0.0.2 10.0.0.255
  
    got message of size 192 on Fri Jan 10 14:13:15 2014
    RTM_ADD: Add Route: len 192, pid: 0, seq 0, errno 0, flags:<UP,PINNED>
    locks:  inits:
    sockaddrs: <DST,GATEWAY,NETMASK>
     10.0.0.0 10.0.0.2 (255) ffff ffff ff
  
  after commit, addition:
  
    got message of size 116 on Fri Jan 10 13:56:26 2014
    RTM_NEWADDR: address being added to iface: len 116, metric 0, flags:
    sockaddrs: <NETMASK,IFP,IFA,BRD>
     255.255.255.0 vlan4:8.0.27.c5.29.d4 14.0.0.2 14.0.0.255
  
  before commit, wihdrawal:
  
    got message of size 192 on Fri Jan 10 13:58:59 2014
    RTM_DELETE: Delete Route: len 192, pid: 0, seq 0, errno 0, flags:<UP,PINNED>
    locks:  inits:
    sockaddrs: <DST,GATEWAY,NETMASK>
     10.0.0.0 10.0.0.2 (255) ffff ffff ff
  
    got message of size 116 on Fri Jan 10 13:58:59 2014
    RTM_DELADDR: address being removed from iface: len 116, metric 0, flags:
    sockaddrs: <NETMASK,IFP,IFA,BRD>
     255.255.255.0 vlan4:8.0.27.c5.29.d4 10.0.0.2 10.0.0.255
  
  adter commit, withdrawal:
  
    got message of size 116 on Fri Jan 10 14:14:11 2014
    RTM_DELADDR: address being removed from iface: len 116, metric 0, flags:
    sockaddrs: <NETMASK,IFP,IFA,BRD>
     255.255.255.0 vlan4:8.0.27.c5.29.d4 10.0.0.2 10.0.0.255
  
  Sending both RTM_ADD/RTM_DELETE messages to rtsock is completely wrong
  (and requires some hacks to keep prefix in route table on RTM_DELETE).
  
  I've tested this change with quagga (no change) and bird (*).
  
  bird alias handling is already broken in *BSD sysdep code, so nothing
  changes here, too.
  
  I'm going to MFC this change if there will be no complains about behavior
  change.
  
  While here, fix some style(9) bugs introduced by r260488
  (pointed by glebius and bde).
  
  Sponsored by:	Yandex LLC
  MFC after:	4 weeks

Modified:
  head/sys/net/route.c
  head/sys/net/route.h
  head/sys/net/rtsock.c
  head/sys/netinet/in.c

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c	Fri Jan 10 12:09:38 2014	(r260507)
+++ head/sys/net/route.c	Fri Jan 10 12:13:55 2014	(r260508)
@@ -53,7 +53,6 @@
 #include <sys/proc.h>
 #include <sys/domain.h>
 #include <sys/kernel.h>
-#include <sys/kdb.h>
 
 #include <net/if.h>
 #include <net/if_var.h>
@@ -1751,24 +1750,20 @@ rt_addrmsg(int cmd, struct ifaddr *ifa, 
 {
 
 	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
-		("unexpected cmd %u", cmd));
+	    ("unexpected cmd %d", cmd));
 	
-	if (fibnum != RT_ALL_FIBS) {
-		KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: "
-		    "fibnum out of range 0 <= %d < %d", __func__,
-		     fibnum, rt_numfibs));
-	}
+	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
 
 	return (rtsock_addrmsg(cmd, ifa, fibnum));
 }
 
-
 /*
- * Announce route addition/removal
+ * Announce route addition/removal.
  * Users of this function MUST validate input data BEFORE calling.
  * However we have to be able to handle invalid data:
  * if some userland app sends us "invalid" route message (invalid mask,
- * no dst, wrokg address families, etc...) we need to pass it back
+ * no dst, wrong address families, etc...) we need to pass it back
  * to app (and any other rtsock consumers) with rtm_errno field set to
  * non-zero value.
  * Returns 0 on success.
@@ -1779,13 +1774,10 @@ rt_routemsg(int cmd, struct ifnet *ifp, 
 {
 
 	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
-		("unexpected cmd %u", cmd));
+	    ("unexpected cmd %d", cmd));
 	
-	if (fibnum != RT_ALL_FIBS) {
-		KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: "
-		    "fibnum out of range 0 <= %d < %d", __func__,
-		     fibnum, rt_numfibs));
-	}
+	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
 
 	KASSERT(rt_key(rt) != NULL, (":%s: rt_key must be supplied", __func__));
 
@@ -1810,11 +1802,8 @@ rt_newaddrmsg_fib(int cmd, struct ifaddr
 
 	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
 		("unexpected cmd %u", cmd));
-	if (fibnum != RT_ALL_FIBS) {
-		KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: "
-		    "fibnum out of range 0 <= %d < %d", __func__,
-		     fibnum, rt_numfibs));
-	}
+	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
 
 #if defined(INET) || defined(INET6)
 #ifdef SCTP

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h	Fri Jan 10 12:09:38 2014	(r260507)
+++ head/sys/net/route.h	Fri Jan 10 12:13:55 2014	(r260508)
@@ -94,6 +94,7 @@ struct rt_metrics {
 #define	RT_DEFAULT_FIB	0	/* Explicitly mark fib=0 restricted cases */
 #define	RT_ALL_FIBS	-1	/* Announce event for every fib */
 extern u_int rt_numfibs;	/* number of usable routing tables */
+extern u_int rt_add_addr_allfibs;	/* Announce interfaces to all fibs */
 /*
  * XXX kernel function pointer `rt_output' is visible to applications.
  */

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c	Fri Jan 10 12:09:38 2014	(r260507)
+++ head/sys/net/rtsock.c	Fri Jan 10 12:13:55 2014	(r260508)
@@ -1415,7 +1415,6 @@ rtsock_routemsg(int cmd, struct ifnet *i
 	return (0);
 }
 
-
 /*
  * This is the analogue to the rt_newaddrmsg which performs the same
  * function but for multicast group memberhips.  This is easier since

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Fri Jan 10 12:09:38 2014	(r260507)
+++ head/sys/netinet/in.c	Fri Jan 10 12:13:55 2014	(r260508)
@@ -610,45 +610,6 @@ in_difaddr_ioctl(caddr_t data, struct if
 	    ? RTF_HOST : 0)
 
 /*
- * Generate a routing message when inserting or deleting
- * an interface address alias.
- */
-static void in_addralias_rtmsg(int cmd, struct in_addr *prefix,
-    struct in_ifaddr *target)
-{
-	struct route pfx_ro;
-	struct sockaddr_in *pfx_addr;
-	struct rtentry msg_rt;
-
-	/* QL: XXX
-	 * This is a bit questionable because there is no
-	 * additional route entry added/deleted for an address
-	 * alias. Therefore this route report is inaccurate.
-	 */
-	bzero(&pfx_ro, sizeof(pfx_ro));
-	pfx_addr = (struct sockaddr_in *)(&pfx_ro.ro_dst);
-	pfx_addr->sin_len = sizeof(*pfx_addr);
-	pfx_addr->sin_family = AF_INET;
-	pfx_addr->sin_addr = *prefix;
-	rtalloc_ign_fib(&pfx_ro, 0, 0);
-	if (pfx_ro.ro_rt != NULL) {
-		msg_rt = *pfx_ro.ro_rt;
-
-		/* QL: XXX
-		 * Point the gateway to the new interface
-		 * address as if a new prefix route entry has
-		 * been added through the new address alias.
-		 * All other parts of the rtentry is accurate,
-		 * e.g., rt_key, rt_mask, rt_ifp etc.
-		 */
-		msg_rt.rt_gateway = (struct sockaddr *)&target->ia_addr;
-		rt_newaddrmsg(cmd, (struct ifaddr *)target, 0, &msg_rt);
-		RTFREE(pfx_ro.ro_rt);
-	}
-	return;
-}
-
-/*
  * Check if we have a route for the given prefix already or add one accordingly.
  */
 int
@@ -656,7 +617,7 @@ in_addprefix(struct in_ifaddr *target, i
 {
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p, m;
-	int error;
+	int error, fibnum;
 
 	if ((flags & RTF_HOST) != 0) {
 		prefix = target->ia_dstaddr.sin_addr;
@@ -667,6 +628,8 @@ in_addprefix(struct in_ifaddr *target, i
 		prefix.s_addr &= mask.s_addr;
 	}
 
+	fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib;
+
 	IN_IFADDR_RLOCK();
 	TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
 		if (rtinitflags(ia)) {
@@ -701,7 +664,7 @@ in_addprefix(struct in_ifaddr *target, i
 				IN_IFADDR_RUNLOCK();
 				return (EEXIST);
 			} else {
-				in_addralias_rtmsg(RTM_ADD, &prefix, target);
+				rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum);
 				IN_IFADDR_RUNLOCK();
 				return (0);
 			}
@@ -728,9 +691,11 @@ in_scrubprefix(struct in_ifaddr *target,
 {
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p, m;
-	int error = 0;
+	int error = 0, fibnum;
 	struct sockaddr_in prefix0, mask0;
 
+	fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib;
+
 	/*
 	 * Remove the loopback route to the interface address.
 	 */
@@ -766,7 +731,7 @@ in_scrubprefix(struct in_ifaddr *target,
 	}
 
 	if ((target->ia_flags & IFA_ROUTE) == 0) {
-		in_addralias_rtmsg(RTM_DELETE, &prefix, target);
+		rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum);
 		return (0);
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401101213.s0ACDunV085406>