Author: melifaro Date: Wed Dec 2 08:17:31 2015 New Revision: 291643 URL: https://svnweb.freebsd.org/changeset/base/291643
Log: Move RTF_PINNED handling to generic route code. This eliminates last RTF_RNH_LOCKED rtrequest1_fib() user. Modified: head/sys/net/route.c Modified: head/sys/net/route.c ============================================================================== --- head/sys/net/route.c Wed Dec 2 05:36:45 2015 (r291642) +++ head/sys/net/route.c Wed Dec 2 08:17:31 2015 (r291643) @@ -1089,6 +1089,7 @@ rt_unlinkrte(struct radix_node_head *rnh rt = RNTORT(rn); RT_LOCK(rt); RT_ADDREF(rt); + rt->rt_flags &= ~RTF_UP; *perror = 0; @@ -1100,8 +1101,6 @@ rt_notifydelete(struct rtentry *rt, stru { struct ifaddr *ifa; - rt->rt_flags &= ~RTF_UP; - /* * give the protocol a chance to keep things in sync. */ @@ -1434,7 +1433,7 @@ rtrequest1_fib(int req, struct rt_addrin u_int fibnum) { int error = 0, needlock = 0; - struct rtentry *rt; + struct rtentry *rt, *rt_old; #ifdef FLOWTABLE struct rtentry *rt0; #endif @@ -1577,6 +1576,26 @@ rtrequest1_fib(int req, struct rt_addrin /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */ rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes); + + rt_old = NULL; + if (rn == NULL && (info->rti_flags & RTF_PINNED) != 0) { + + /* + * Force removal and re-try addition + * TODO: better multipath&pinned support + */ + struct sockaddr *info_dst = info->rti_info[RTAX_DST]; + info->rti_info[RTAX_DST] = ndst; + rt_old = rt_unlinkrte(rnh, info, &error); + info->rti_info[RTAX_DST] = info_dst; + if (rt_old != NULL) + rn = rnh->rnh_addaddr(ndst, netmask, rnh, + rt->rt_nodes); + } + + if (rt_old != NULL) + RT_UNLOCK(rt_old); + /* * If it still failed to go into the tree, * then un-make it (this should be a function) @@ -1598,6 +1617,11 @@ rtrequest1_fib(int req, struct rt_addrin } #endif + if (rt_old != NULL) { + rt_notifydelete(rt_old, info); + RTFREE(rt_old); + } + /* * If this protocol has something to add to this then * allow it to do that as well. @@ -1974,32 +1998,6 @@ rtinit1(struct ifaddr *ifa, int cmd, int info.rti_info[RTAX_NETMASK] = netmask; error = rtrequest1_fib(cmd, &info, &rt, fibnum); - if ((error == EEXIST) && (cmd == RTM_ADD)) { - /* - * Interface route addition failed. - * Atomically delete current prefix generating - * RTM_DELETE message, and retry adding - * interface prefix. - */ - rnh = rt_tables_get_rnh(fibnum, dst->sa_family); - RADIX_NODE_HEAD_LOCK(rnh); - - /* Delete old prefix */ - info.rti_ifa = NULL; - info.rti_flags = RTF_RNH_LOCKED; - - error = rtrequest1_fib(RTM_DELETE, &info, NULL, fibnum); - if (error == 0) { - info.rti_ifa = ifa; - info.rti_flags = flags | RTF_RNH_LOCKED | - (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED; - error = rtrequest1_fib(cmd, &info, &rt, fibnum); - } - - RADIX_NODE_HEAD_UNLOCK(rnh); - } - - if (error == 0 && rt != NULL) { /* * notify any listening routing agents of the change _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"