Pull RTM_CHANGE code out of route_output to make further changes easy
No functional change.
This commit is contained in:
parent
1656c8e745
commit
c0732db998
141
sys/net/rtsock.c
141
sys/net/rtsock.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtsock.c,v 1.197 2016/10/03 11:06:06 ozaki-r Exp $ */
|
||||
/* $NetBSD: rtsock.c,v 1.198 2016/10/26 06:49:10 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.197 2016/10/03 11:06:06 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.198 2016/10/26 06:49:10 ozaki-r Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
@ -593,6 +593,73 @@ out:
|
||||
return ifa;
|
||||
}
|
||||
|
||||
static int
|
||||
route_output_change(struct rtentry *rt, struct rt_addrinfo *info,
|
||||
struct rt_xmsghdr *rtm)
|
||||
{
|
||||
int error = 0;
|
||||
struct ifnet *ifp, *new_ifp;
|
||||
struct ifaddr *ifa, *new_ifa;
|
||||
struct psref psref_ifa, psref_new_ifa, psref_ifp;
|
||||
|
||||
/*
|
||||
* new gateway could require new ifaddr, ifp;
|
||||
* flags may also be different; ifp may be specified
|
||||
* by ll sockaddr when protocol address is ambiguous
|
||||
*/
|
||||
ifp = rt_getifp(info, &psref_ifp);
|
||||
ifa = rt_getifa(info, &psref_ifa);
|
||||
if (ifa == NULL) {
|
||||
error = ENETUNREACH;
|
||||
goto out;
|
||||
}
|
||||
if (info->rti_info[RTAX_GATEWAY]) {
|
||||
error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
}
|
||||
if (info->rti_info[RTAX_TAG]) {
|
||||
const struct sockaddr *tag;
|
||||
tag = rt_settag(rt, info->rti_info[RTAX_TAG]);
|
||||
if (tag == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* new gateway could require new ifaddr, ifp;
|
||||
flags may also be different; ifp may be specified
|
||||
by ll sockaddr when protocol address is ambiguous */
|
||||
new_ifa = route_output_get_ifa(*info, rt, &new_ifp, &psref_new_ifa);
|
||||
if (new_ifa != NULL) {
|
||||
ifa_release(ifa, &psref_ifa);
|
||||
ifa = new_ifa;
|
||||
}
|
||||
if (ifa) {
|
||||
struct ifaddr *oifa = rt->rt_ifa;
|
||||
if (oifa != ifa) {
|
||||
if (oifa && oifa->ifa_rtrequest)
|
||||
oifa->ifa_rtrequest(RTM_DELETE, rt, info);
|
||||
rt_replace_ifa(rt, ifa);
|
||||
rt->rt_ifp = new_ifp;
|
||||
}
|
||||
if (new_ifa == NULL)
|
||||
ifa_release(ifa, &psref_ifa);
|
||||
}
|
||||
ifa_release(new_ifa, &psref_new_ifa);
|
||||
if (new_ifp && rt->rt_ifp != new_ifp)
|
||||
rt->rt_ifp = new_ifp;
|
||||
rt_setmetrics(rtm->rtm_inits, rtm, rt);
|
||||
if (rt->rt_flags != info->rti_flags)
|
||||
rt->rt_flags = (info->rti_flags & ~PRESERVED_RTF)
|
||||
| (rt->rt_flags & PRESERVED_RTF);
|
||||
if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info);
|
||||
out:
|
||||
if_put(ifp, &psref_ifp);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
COMPATNAME(route_output)(struct mbuf *m, struct socket *so)
|
||||
@ -604,11 +671,8 @@ COMPATNAME(route_output)(struct mbuf *m, struct socket *so)
|
||||
struct rtentry *saved_nrt = NULL;
|
||||
struct rt_addrinfo info;
|
||||
int len, error = 0;
|
||||
struct ifnet *ifp = NULL;
|
||||
struct ifaddr *ifa = NULL;
|
||||
sa_family_t family;
|
||||
struct sockaddr_dl sdl;
|
||||
struct psref psref;
|
||||
int bound = curlwp_bind();
|
||||
|
||||
#define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0)
|
||||
@ -818,70 +882,11 @@ COMPATNAME(route_output)(struct mbuf *m, struct socket *so)
|
||||
}
|
||||
break;
|
||||
|
||||
case RTM_CHANGE: {
|
||||
struct ifnet *_ifp;
|
||||
struct ifaddr *_ifa;
|
||||
struct psref _psref, psref_ifp;
|
||||
/*
|
||||
* new gateway could require new ifaddr, ifp;
|
||||
* flags may also be different; ifp may be specified
|
||||
* by ll sockaddr when protocol address is ambiguous
|
||||
*/
|
||||
_ifp = rt_getifp(&info, &psref_ifp);
|
||||
ifa = rt_getifa(&info, &psref);
|
||||
if (ifa == NULL) {
|
||||
if_put(_ifp, &psref_ifp);
|
||||
senderr(ENETUNREACH);
|
||||
}
|
||||
if (info.rti_info[RTAX_GATEWAY]) {
|
||||
error = rt_setgate(rt,
|
||||
info.rti_info[RTAX_GATEWAY]);
|
||||
if (error != 0) {
|
||||
if_put(_ifp, &psref_ifp);
|
||||
senderr(error);
|
||||
}
|
||||
}
|
||||
if (info.rti_info[RTAX_TAG]) {
|
||||
const struct sockaddr *tag;
|
||||
tag = rt_settag(rt, info.rti_info[RTAX_TAG]);
|
||||
if (tag == NULL) {
|
||||
if_put(_ifp, &psref_ifp);
|
||||
senderr(ENOBUFS);
|
||||
}
|
||||
}
|
||||
/* new gateway could require new ifaddr, ifp;
|
||||
flags may also be different; ifp may be specified
|
||||
by ll sockaddr when protocol address is ambiguous */
|
||||
_ifa = route_output_get_ifa(info, rt, &ifp, &_psref);
|
||||
if (_ifa != NULL) {
|
||||
ifa_release(ifa, &psref);
|
||||
ifa = _ifa;
|
||||
}
|
||||
if (ifa) {
|
||||
struct ifaddr *oifa = rt->rt_ifa;
|
||||
if (oifa != ifa) {
|
||||
if (oifa && oifa->ifa_rtrequest) {
|
||||
oifa->ifa_rtrequest(RTM_DELETE,
|
||||
rt, &info);
|
||||
}
|
||||
rt_replace_ifa(rt, ifa);
|
||||
rt->rt_ifp = ifp;
|
||||
}
|
||||
if (_ifa == NULL)
|
||||
ifa_release(ifa, &psref);
|
||||
}
|
||||
ifa_release(_ifa, &_psref);
|
||||
if (ifp && rt->rt_ifp != ifp)
|
||||
rt->rt_ifp = ifp;
|
||||
rt_setmetrics(rtm->rtm_inits, rtm, rt);
|
||||
if (rt->rt_flags != info.rti_flags)
|
||||
rt->rt_flags = (info.rti_flags & ~PRESERVED_RTF)
|
||||
| (rt->rt_flags & PRESERVED_RTF);
|
||||
if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info);
|
||||
if_put(_ifp, &psref_ifp);
|
||||
case RTM_CHANGE:
|
||||
error = route_output_change(rt, &info, rtm);
|
||||
if (error != 0)
|
||||
goto flush;
|
||||
/*FALLTHROUGH*/
|
||||
}
|
||||
case RTM_LOCK:
|
||||
rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
|
||||
rt->rt_rmx.rmx_locks |=
|
||||
|
Loading…
Reference in New Issue
Block a user