From owner-svn-src-head@FreeBSD.ORG Wed Dec 30 22:13:02 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E97C9106566B; Wed, 30 Dec 2009 22:13:01 +0000 (UTC) (envelope-from qingli@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D71D28FC12; Wed, 30 Dec 2009 22:13:01 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nBUMD1pP073810; Wed, 30 Dec 2009 22:13:01 GMT (envelope-from qingli@svn.freebsd.org) Received: (from qingli@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nBUMD1PA073808; Wed, 30 Dec 2009 22:13:01 GMT (envelope-from qingli@svn.freebsd.org) Message-Id: <200912302213.nBUMD1PA073808@svn.freebsd.org> From: Qing Li Date: Wed, 30 Dec 2009 22:13:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201285 - head/sys/netinet X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Dec 2009 22:13:02 -0000 Author: qingli Date: Wed Dec 30 22:13:01 2009 New Revision: 201285 URL: http://svn.freebsd.org/changeset/base/201285 Log: Consolidate the route message generation code for when address aliases were added or deleted. The announced route entry for an address alias is no longer empty because this empty route entry was causing some route daemon to fail and exit abnormally. MFC after: 5 days Modified: head/sys/netinet/in.c Modified: head/sys/netinet/in.c ============================================================================== --- head/sys/netinet/in.c Wed Dec 30 21:51:23 2009 (r201284) +++ head/sys/netinet/in.c Wed Dec 30 22:13:01 2009 (r201285) @@ -950,6 +950,49 @@ in_ifinit(struct ifnet *ifp, struct in_i #define rtinitflags(x) \ ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \ ? 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. */ @@ -997,40 +1040,7 @@ in_addprefix(struct in_ifaddr *target, i IN_IFADDR_RUNLOCK(); return (EEXIST); } else { - 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 for an address alias. - * Therefore this route report is inaccurate. Perhaps - * it's better to supply a empty rtentry as how it - * is done in in_scrubprefix(). - */ - 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 given 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 *)&ia->ia_addr; - rt_newaddrmsg(RTM_ADD, - (struct ifaddr *)target, - 0, &msg_rt); - RTFREE(pfx_ro.ro_rt); - } - + in_addralias_rtmsg(RTM_ADD, &prefix, target); IN_IFADDR_RUNLOCK(); return (0); } @@ -1099,20 +1109,6 @@ in_scrubprefix(struct in_ifaddr *target) arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr); } - if ((target->ia_flags & IFA_ROUTE) == 0) { - struct rtentry rt; - - /* QL: XXX - * Report a blank rtentry when a route has not been - * installed for the given interface address. - */ - bzero(&rt, sizeof(rt)); - rt_newaddrmsg(RTM_DELETE, - (struct ifaddr *)target, - 0, &rt); - return (0); - } - if (rtinitflags(target)) prefix = target->ia_dstaddr.sin_addr; else { @@ -1121,6 +1117,11 @@ in_scrubprefix(struct in_ifaddr *target) prefix.s_addr &= mask.s_addr; } + if ((target->ia_flags & IFA_ROUTE) == 0) { + in_addralias_rtmsg(RTM_DELETE, &prefix, target); + return (0); + } + IN_IFADDR_RLOCK(); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia))