-/* $OpenBSD: mpls_input.c,v 1.65 2017/12/08 22:10:34 bluhm Exp $ */
+/* $OpenBSD: mpls_input.c,v 1.66 2018/01/09 06:24:15 dlg Exp $ */
/*
* Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
struct mbuf *mpls_do_error(struct mbuf *, int, int, int);
void
-mpls_input(struct mbuf *m)
+mpls_input(struct ifnet *ifp, struct mbuf *m)
{
struct sockaddr_mpls *smpls;
struct sockaddr_mpls sa_mpls;
struct shim_hdr *shim;
struct rtentry *rt;
struct rt_mpls *rt_mpls;
- struct ifnet *ifp;
- u_int8_t ttl;
+ uint8_t ttl;
int hasbos;
- if ((ifp = if_get(m->m_pkthdr.ph_ifidx)) == NULL ||
- !ISSET(ifp->if_xflags, IFXF_MPLS)) {
- m_freem(m);
- if_put(ifp);
- return;
- }
-
/* drop all broadcast and multicast packets */
if (m->m_flags & (M_BCAST | M_MCAST)) {
m_freem(m);
- if_put(ifp);
return;
}
- if (m->m_len < sizeof(*shim))
- if ((m = m_pullup(m, sizeof(*shim))) == NULL) {
- if_put(ifp);
+ if (m->m_len < sizeof(*shim)) {
+ m = m_pullup(m, sizeof(*shim));
+ if (m == NULL)
return;
- }
+ }
shim = mtod(m, struct shim_hdr *);
#ifdef MPLS_DEBUG
- printf("mpls_input: iface %d label=%d, ttl=%d BoS %d\n",
- m->m_pkthdr.ph_ifidx, MPLS_LABEL_GET(shim->shim_label),
- MPLS_TTL_GET(shim->shim_label),
- MPLS_BOS_ISSET(shim->shim_label));
+ printf("mpls_input: iface %s label=%d, ttl=%d BoS %d\n",
+ ifp->if_xname, MPLS_LABEL_GET(shim->shim_label), ttls, hasbos);
#endif
/* check and decrement TTL */
- ttl = ntohl(shim->shim_label & MPLS_TTL_MASK);
- if (ttl-- <= 1) {
+ if (--ttl == 0) {
/* TTL exceeded */
m = mpls_do_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0);
- if (m == NULL) {
- if_put(ifp);
+ if (m == NULL)
return;
- }
+
shim = mtod(m, struct shim_hdr *);
ttl = ntohl(shim->shim_label & MPLS_TTL_MASK);
}
+ hasbos = MPLS_BOS_ISSET(shim->shim_label);
bzero(&sa_mpls, sizeof(sa_mpls));
smpls = &sa_mpls;
smpls->smpls_len = sizeof(*smpls);
smpls->smpls_label = shim->shim_label & MPLS_LABEL_MASK;
- hasbos = MPLS_BOS_ISSET(shim->shim_label);
-
if (ntohl(smpls->smpls_label) < MPLS_LABEL_RESERVED_MAX) {
m = mpls_shim_pop(m);
- if (m == NULL) {
- if_put(ifp);
+ if (m == NULL)
return;
- }
if (!hasbos) {
/*
* RFC 4182 relaxes the position of the
switch (ntohl(smpls->smpls_label)) {
case MPLS_LABEL_IPV4NULL:
do_v4:
- if ((m = mpls_ip_adjttl(m, ttl)) == NULL) {
- if_put(ifp);
+ if ((m = mpls_ip_adjttl(m, ttl)) == NULL)
return;
- }
ipv4_input(ifp, m);
- if_put(ifp);
return;
#ifdef INET6
case MPLS_LABEL_IPV6NULL:
do_v6:
- if ((m = mpls_ip6_adjttl(m, ttl)) == NULL) {
- if_put(ifp);
+ if ((m = mpls_ip6_adjttl(m, ttl)) == NULL)
return;
- }
ipv6_input(ifp, m);
- if_put(ifp);
return;
#endif /* INET6 */
case MPLS_LABEL_IMPLNULL:
if (m->m_len < sizeof(u_char) &&
- (m = m_pullup(m, sizeof(u_char))) == NULL) {
- if_put(ifp);
+ (m = m_pullup(m, sizeof(u_char))) == NULL)
return;
- }
switch (*mtod(m, u_char *) >> 4) {
case IPVERSION:
goto do_v4;
#endif
default:
m_freem(m);
- if_put(ifp);
return;
}
default:
/* Other cases are not handled for now */
m_freem(m);
- if_put(ifp);
return;
}
}
}
- if_put(ifp);
+
ifp = NULL;
rt = rtalloc(smplstosa(smpls), RT_RESOLVE, m->m_pkthdr.ph_rtableid);