summaryrefslogtreecommitdiff
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2010-05-19 13:09:10 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2010-05-19 13:09:10 +0000
commita5b90350387baa303cd9c624c294afc310b07e50 (patch)
treee419d0a02c48b5abad16c5220db8193b74925f47 /sys/net/rtsock.c
parent4c3903cd45cda5f0ec7b5cc3335eedd86187a60f (diff)
Require RTF_MPLS to be set when a mpls route is added or changed. To remove
only the MPLS bits from a route set rtm_fmask to RTF_MPLS. Additionally check if the nexthop is modified and in that case always remove the MPLS info since the path changed. This change makes life in userland a lot easier since the routing daemons normaly don't know about MPLS and until now they destroyed MPLS information when issuing RTM_CHANGEs. OK michele@
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c87
1 files changed, 45 insertions, 42 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index ac5cfdad10d..4dff661d0b3 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.99 2010/04/21 11:52:46 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.100 2010/05/19 13:09:09 claudio Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -79,7 +79,7 @@
#ifdef MPLS
#include <netmpls/mpls.h>
-#endif /* MPLS */
+#endif
#include <sys/stdarg.h>
@@ -158,7 +158,7 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
#ifdef MPLS
else if (af == AF_MPLS)
route_cb.mpls_count++;
-#endif /* MPLS */
+#endif
rp->rcb_faddr = &route_src;
route_cb.any_count++;
soisconnected(so);
@@ -175,7 +175,7 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
#ifdef MPLS
else if (af == AF_MPLS)
route_cb.mpls_count--;
-#endif /* MPLS */
+#endif
route_cb.any_count--;
}
/* FALLTHROUGH */
@@ -321,7 +321,7 @@ route_output(struct mbuf *m, ...)
struct rtentry *saved_nrt = NULL;
struct radix_node_head *rnh;
struct rt_addrinfo info;
- int len, error = 0;
+ int len, newgate, error = 0;
struct ifnet *ifp = NULL;
struct ifaddr *ifa = NULL;
struct socket *so;
@@ -454,8 +454,9 @@ route_output(struct mbuf *m, ...)
saved_nrt->rt_refcnt--;
saved_nrt->rt_genmask = genmask;
/* write back the priority the kernel used */
- rtm->rtm_index = saved_nrt->rt_ifp->if_index;
rtm->rtm_priority = saved_nrt->rt_priority & RTP_MASK;
+ rtm->rtm_index = saved_nrt->rt_ifp->if_index;
+ rtm->rtm_flags = saved_nrt->rt_flags;
}
break;
case RTM_DELETE:
@@ -615,6 +616,11 @@ report:
*/
if ((error = rt_getifa(&info, tableid)) != 0)
goto flush;
+ newgate = 0;
+ if (gate)
+ if (rt->rt_gateway == NULL ||
+ bcmp(rt->rt_gateway, gate, gate->sa_len))
+ newgate = 1;
if (gate && rt_setgate(rt, rt_key(rt), gate, tableid)) {
error = EDQUOT;
goto flush;
@@ -646,31 +652,18 @@ report:
#endif
}
}
-
- /* XXX Hack to allow some flags to be toggled */
- if (rtm->rtm_fmask & RTF_FMASK)
- rt->rt_flags = (rt->rt_flags &
- ~rtm->rtm_fmask) |
- (rtm->rtm_flags & rtm->rtm_fmask);
-
- rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
- &rt->rt_rmx);
- rtm->rtm_index = rt->rt_ifp->if_index;
- rtm->rtm_priority = rt->rt_priority & RTP_MASK;
- rtm->rtm_flags = rt->rt_flags;
- if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
- rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info);
- if (genmask)
- rt->rt_genmask = genmask;
- if (info.rti_info[RTAX_LABEL] != NULL) {
- char *rtlabel = ((struct sockaddr_rtlabel *)
- info.rti_info[RTAX_LABEL])->sr_label;
- rtlabel_unref(rt->rt_labelid);
- rt->rt_labelid =
- rtlabel_name2id(rtlabel);
- }
#ifdef MPLS
- if (info.rti_info[RTAX_SRC] != NULL) {
+ /* if gateway changed remove MPLS information */
+ if (newgate || ((rtm->rtm_fmask & RTF_MPLS) &&
+ !(rtm->rtm_flags & RTF_MPLS))) {
+ if (rt->rt_llinfo != NULL &&
+ rt->rt_flags & RTF_MPLS) {
+ free(rt->rt_llinfo, M_TEMP);
+ rt->rt_llinfo = NULL;
+ rt->rt_flags &= ~RTF_MPLS;
+ }
+ } else if ((rtm->rtm_flags & RTF_MPLS) &&
+ info.rti_info[RTAX_SRC] != NULL) {
struct rt_mpls *rt_mpls;
psa_mpls = (struct sockaddr_mpls *)
@@ -698,16 +691,30 @@ report:
/* XXX: set experimental bits */
rt->rt_flags |= RTF_MPLS;
- } else {
- if (rt->rt_llinfo != NULL &&
- rt->rt_flags & RTF_MPLS) {
- free(rt->rt_llinfo, M_TEMP);
- rt->rt_llinfo = NULL;
-
- rt->rt_flags &= (~RTF_MPLS);
- }
}
#endif
+ /* Hack to allow some flags to be toggled */
+ if (rtm->rtm_fmask & RTF_FMASK)
+ rt->rt_flags = (rt->rt_flags &
+ ~rtm->rtm_fmask) |
+ (rtm->rtm_flags & rtm->rtm_fmask);
+
+ rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
+ &rt->rt_rmx);
+ rtm->rtm_index = rt->rt_ifp->if_index;
+ rtm->rtm_priority = rt->rt_priority & RTP_MASK;
+ rtm->rtm_flags = rt->rt_flags;
+ if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
+ rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info);
+ if (genmask)
+ rt->rt_genmask = genmask;
+ if (info.rti_info[RTAX_LABEL] != NULL) {
+ char *rtlabel = ((struct sockaddr_rtlabel *)
+ info.rti_info[RTAX_LABEL])->sr_label;
+ rtlabel_unref(rt->rt_labelid);
+ rt->rt_labelid =
+ rtlabel_name2id(rtlabel);
+ }
if_group_routechange(dst, netmask);
/* FALLTHROUGH */
case RTM_LOCK:
@@ -729,10 +736,6 @@ flush:
if (error)
rtm->rtm_errno = error;
else {
-#ifdef MPLS
- if (rt && rt->rt_flags & RTF_MPLS)
- rtm->rtm_flags |= RTF_MPLS;
-#endif
rtm->rtm_flags |= RTF_DONE;
}
}