diff options
Diffstat (limited to 'sys/net/route.c')
-rw-r--r-- | sys/net/route.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index 74c274cb772..3e5ec851890 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.101 2009/01/08 12:47:45 michele Exp $ */ +/* $OpenBSD: route.c,v 1.102 2009/01/28 22:18:44 michele Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -419,6 +419,10 @@ rtfree(struct rtentry *rt) if (ifa) IFAFREE(ifa); rtlabel_unref(rt->rt_labelid); +#ifdef MPLS + if (rt->rt_flags & RTF_MPLS) + free(rt->rt_llinfo, M_TEMP); +#endif Free(rt_key(rt)); pool_put(&rtentry_pool, rt); } @@ -822,7 +826,9 @@ makeroute: if (rt == NULL) senderr(ENOBUFS); Bzero(rt, sizeof(*rt)); + rt->rt_flags = info->rti_flags; + if (prio == 0) prio = ifa->ifa_ifp->if_priority + RTP_STATIC; rt->rt_priority = prio; /* init routing priority */ @@ -867,10 +873,36 @@ makeroute: } #ifdef MPLS - if (info->rti_info[RTAX_SRC] != NULL) { + /* We have to allocate additional space for MPLS infos */ + if (info->rti_info[RTAX_SRC] != NULL || + info->rti_info[RTAX_DST]->sa_family == AF_MPLS) { + struct rt_mpls *rt_mpls; + sa_mpls = (struct sockaddr_mpls *) info->rti_info[RTAX_SRC]; - rt->rt_mpls = sa_mpls->smpls_label; + + rt->rt_llinfo = (caddr_t)malloc(sizeof(struct rt_mpls), + M_TEMP, M_NOWAIT|M_ZERO); + + if (rt->rt_llinfo == NULL) { + if (rt->rt_gwroute) + rtfree(rt->rt_gwroute); + Free(rt_key(rt)); + pool_put(&rtentry_pool, rt); + senderr(ENOMEM); + } + + rt_mpls = (struct rt_mpls *)rt->rt_llinfo; + + if (sa_mpls != NULL) + rt_mpls->mpls_label = sa_mpls->smpls_label; + + rt_mpls->mpls_operation = rt->rt_flags & + (MPLS_OP_PUSH | MPLS_OP_POP | MPLS_OP_SWAP); + + /* XXX: set experimental bits */ + + rt->rt_flags |= RTF_MPLS; } #endif |