Module Name: src Committed By: ozaki-r Date: Thu Jun 22 09:58:04 UTC 2017
Modified Files: src/sys/net: rtsock.c Log Message: Purge L2 caches on changing an interface of a route The change addresses situations similar to PR 51179. To generate a diff of this commit: cvs rdiff -u -r1.216 -r1.217 src/sys/net/rtsock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.216 src/sys/net/rtsock.c:1.217 --- src/sys/net/rtsock.c:1.216 Fri Jun 16 02:26:17 2017 +++ src/sys/net/rtsock.c Thu Jun 22 09:58:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.216 2017/06/16 02:26:17 ozaki-r Exp $ */ +/* $NetBSD: rtsock.c,v 1.217 2017/06/22 09:58:04 ozaki-r Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.216 2017/06/16 02:26:17 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.217 2017/06/22 09:58:04 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -641,7 +641,7 @@ route_output_change(struct rtentry *rt, struct ifnet *ifp = NULL, *new_ifp; struct ifaddr *ifa = NULL, *new_ifa; struct psref psref_ifa, psref_new_ifa, psref_ifp; - bool newgw; + bool newgw, ifp_changed = false; /* * New gateway could require new ifaddr, ifp; @@ -691,13 +691,16 @@ route_output_change(struct rtentry *rt, oifa->ifa_rtrequest(RTM_DELETE, rt, info); rt_replace_ifa(rt, ifa); rt->rt_ifp = new_ifp; + ifp_changed = true; } if (new_ifa == NULL) ifa_release(ifa, &psref_ifa); } ifa_release(new_ifa, &psref_new_ifa); - if (new_ifp && rt->rt_ifp != new_ifp && !if_is_deactivated(new_ifp)) + if (new_ifp && rt->rt_ifp != new_ifp && !if_is_deactivated(new_ifp)) { rt->rt_ifp = new_ifp; + ifp_changed = true; + } rt_setmetrics(rtm->rtm_inits, rtm, rt); if (rt->rt_flags != info->rti_flags) { rt->rt_flags = (info->rti_flags & ~PRESERVED_RTF) | @@ -705,6 +708,11 @@ route_output_change(struct rtentry *rt, } if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info); +#if defined(INET) || defined(INET6) + if (ifp_changed && rt_mask(rt) != NULL) + lltable_prefix_free(rt_getkey(rt)->sa_family, rt_getkey(rt), + rt_mask(rt), 0); +#endif out: if_put(ifp, &psref_ifp);