use a mobileip_tunnel struct to represent the interfaces tunnel info.
authordlg <dlg@openbsd.org>
Mon, 12 Feb 2018 02:33:50 +0000 (02:33 +0000)
committerdlg <dlg@openbsd.org>
Mon, 12 Feb 2018 02:33:50 +0000 (02:33 +0000)
this avoids allocating a mobileip_softc on the stack to build a key
for looking up interfaces with on packet input. struct ifnet inside
mobileip_softc is "quite large", and may blow the 2k limit one day.

sys/net/if_mobileip.c

index e0b13ee..fdedc81 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_mobileip.c,v 1.5 2018/02/09 09:30:37 dlg Exp $ */
+/*     $OpenBSD: if_mobileip.c,v 1.6 2018/02/12 02:33:50 dlg Exp $ */
 
 /*
  * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
 
 #include <net/if_mobileip.h>
 
-struct mobileip_softc {
-       struct ifnet            sc_if;
+struct mobileip_tunnel {
+       unsigned int            t_rtableid;
+       struct in_addr          t_src;
+       struct in_addr          t_dst;
 
        RBT_ENTRY(mobileip_softc)
-                               sc_entry;
+                               t_entry;
+};
+
+RBT_HEAD(mobileip_tree, mobileip_tunnel);
 
-       unsigned int            sc_rtableid;
-       struct in_addr          sc_src;
-       struct in_addr          sc_dst;
+struct mobileip_softc {
+       struct mobileip_tunnel  sc_tunnel;
+       struct ifnet            sc_if;
 };
 
 static int     mobileip_clone_create(struct if_clone *, int);
@@ -66,15 +71,13 @@ static int  mobileip_clone_destroy(struct ifnet *);
 static struct if_clone mobileip_cloner = IF_CLONE_INITIALIZER("mobileip",
     mobileip_clone_create, mobileip_clone_destroy);
 
-RBT_HEAD(mobileip_tree, mobileip_softc);
-
 static inline int
-               mobileip_cmp(const struct mobileip_softc *,
-                   const struct mobileip_softc *);
+               mobileip_cmp(const struct mobileip_tunnel *,
+                   const struct mobileip_tunnel *);
 
-RBT_PROTOTYPE(mobileip_tree, mobileip_softc, sc_entry, mobileip_cmp);
+RBT_PROTOTYPE(mobileip_tree, mobileip_tunnel, t_entry, mobileip_cmp);
 
-struct mobileip_tree mobileip_softcs = RBT_INITIALIZER();
+struct mobileip_tree mobileip_tree = RBT_INITIALIZER();
 
 #define MOBILEIPMTU    (1500 - (sizeof(struct mobileip_header) +       \
                            sizeof(struct mobileip_h_src)))             \
@@ -114,9 +117,9 @@ mobileip_clone_create(struct if_clone *ifc, int unit)
        if (!sc)
                return (ENOMEM);
 
-       sc->sc_rtableid = 0;
-       sc->sc_src.s_addr = INADDR_ANY;
-       sc->sc_dst.s_addr = INADDR_ANY;
+       sc->sc_tunnel.t_rtableid = 0;
+       sc->sc_tunnel.t_src.s_addr = INADDR_ANY;
+       sc->sc_tunnel.t_dst.s_addr = INADDR_ANY;
 
        snprintf(sc->sc_if.if_xname, sizeof sc->sc_if.if_xname, "%s%d",
            ifc->ifc_name, unit);
@@ -179,21 +182,21 @@ mobileip_cksum(const void *buf, size_t len)
 }
 
 static inline int
-mobileip_cmp(const struct mobileip_softc *a, const struct mobileip_softc *b)
+mobileip_cmp(const struct mobileip_tunnel *a, const struct mobileip_tunnel *b)
 {
-       if (a->sc_src.s_addr > b->sc_src.s_addr)
+       if (a->t_src.s_addr > b->t_src.s_addr)
                return (1);
-       if (a->sc_src.s_addr < b->sc_src.s_addr)
+       if (a->t_src.s_addr < b->t_src.s_addr)
                return (-1);
 
-       if (a->sc_dst.s_addr > b->sc_dst.s_addr)
+       if (a->t_dst.s_addr > b->t_dst.s_addr)
                return (1);
-       if (a->sc_dst.s_addr < b->sc_dst.s_addr)
+       if (a->t_dst.s_addr < b->t_dst.s_addr)
                return (-1);
 
-       if (a->sc_rtableid > b->sc_rtableid)
+       if (a->t_rtableid > b->t_rtableid)
                return (1);
-       if (a->sc_rtableid < b->sc_rtableid)
+       if (a->t_rtableid < b->t_rtableid)
                return (-1);
 
        return (0);
@@ -272,6 +275,7 @@ static int
 mobileip_encap(struct mobileip_softc *sc, struct mbuf *m)
 {
        struct ip *ip;
+       struct mobileip_tunnel *tunnel = &sc->sc_tunnel;
        struct mobileip_header *mh;
        struct mobileip_h_src *msh;
        caddr_t hdr;
@@ -288,7 +292,7 @@ mobileip_encap(struct mobileip_softc *sc, struct mbuf *m)
 
        /* figure out how much extra space we'll need */
        hlen = sizeof(*mh);
-       if (ip->ip_src.s_addr != sc->sc_src.s_addr)
+       if (ip->ip_src.s_addr != tunnel->t_src.s_addr)
                hlen += sizeof(*msh);
 
        /* add the space */
@@ -313,23 +317,23 @@ mobileip_encap(struct mobileip_softc *sc, struct mbuf *m)
        mh->mip_hcrc = 0;
        mh->mip_dst = ip->ip_dst.s_addr;
 
-       if (ip->ip_src.s_addr != sc->sc_src.s_addr) {
+       if (ip->ip_src.s_addr != tunnel->t_src.s_addr) {
                mh->mip_flags |= MOBILEIP_SP;
 
                msh = (struct mobileip_h_src *)(mh + 1);
                msh->mip_src = ip->ip_src.s_addr;
 
-               ip->ip_src.s_addr = sc->sc_src.s_addr;
+               ip->ip_src.s_addr = tunnel->t_src.s_addr;
        }
 
        htobem16(&mh->mip_hcrc, mobileip_cksum(mh, hlen));
 
        ip->ip_p = IPPROTO_MOBILE;
        htobem16(&ip->ip_len, bemtoh16(&ip->ip_len) + hlen);
-       ip->ip_dst = sc->sc_dst;
+       ip->ip_dst = tunnel->t_dst;
 
        m->m_flags &= ~(M_BCAST|M_MCAST);
-       m->m_pkthdr.ph_rtableid = sc->sc_rtableid;
+       m->m_pkthdr.ph_rtableid = tunnel->t_rtableid;
 
 #if NPF > 0
        pf_pkt_addr_changed(m);
@@ -405,10 +409,10 @@ mobileip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                        error = EINVAL;
                        break;
                }
-               sc->sc_rtableid = ifr->ifr_rdomainid;
+               sc->sc_tunnel.t_rtableid = ifr->ifr_rdomainid;
                break;
        case SIOCGLIFPHYRTABLE:
-               ifr->ifr_rdomainid = sc->sc_rtableid;
+               ifr->ifr_rdomainid = sc->sc_tunnel.t_rtableid;
                break;
 
        default:
@@ -422,14 +426,11 @@ mobileip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 static int
 mobileip_up(struct mobileip_softc *sc)
 {
-       struct mobileip_softc *osc;
-
-       if (sc->sc_dst.s_addr == INADDR_ANY)
+       if (sc->sc_tunnel.t_dst.s_addr == INADDR_ANY)
                return (EDESTADDRREQ);
 
        NET_ASSERT_LOCKED();
-       osc = RBT_INSERT(mobileip_tree, &mobileip_softcs, sc);
-       if (osc != NULL)
+       if (RBT_INSERT(mobileip_tree, &mobileip_tree, &sc->sc_tunnel) != NULL)
                return (EADDRINUSE);
 
        SET(sc->sc_if.if_flags, IFF_RUNNING);
@@ -441,7 +442,7 @@ static int
 mobileip_down(struct mobileip_softc *sc)
 {
        NET_ASSERT_LOCKED();
-       RBT_REMOVE(mobileip_tree, &mobileip_softcs, sc);
+       RBT_REMOVE(mobileip_tree, &mobileip_tree, &sc->sc_tunnel);
 
        CLR(sc->sc_if.if_flags, IFF_RUNNING);
 
@@ -475,8 +476,8 @@ mobileip_set_tunnel(struct mobileip_softc *sc, struct if_laddrreq *req)
                return (EINVAL);
 
        /* commit */
-       sc->sc_src = src->sin_addr;
-       sc->sc_dst = dst->sin_addr;
+       sc->sc_tunnel.t_src = src->sin_addr;
+       sc->sc_tunnel.t_dst = dst->sin_addr;
 
        return (0);
 }
@@ -487,18 +488,18 @@ mobileip_get_tunnel(struct mobileip_softc *sc, struct if_laddrreq *req)
        struct sockaddr_in *src = (struct sockaddr_in *)&req->addr;
        struct sockaddr_in *dst = (struct sockaddr_in *)&req->dstaddr;
 
-       if (sc->sc_dst.s_addr == INADDR_ANY)
+       if (sc->sc_tunnel.t_dst.s_addr == INADDR_ANY)
                return (EADDRNOTAVAIL);
 
        memset(src, 0, sizeof(*src));
        src->sin_family = AF_INET;
        src->sin_len = sizeof(*src);
-       src->sin_addr = sc->sc_src;
+       src->sin_addr = sc->sc_tunnel.t_src;
 
        memset(dst, 0, sizeof(*dst));
        dst->sin_family = AF_INET;
        dst->sin_len = sizeof(*dst);
-       dst->sin_addr = sc->sc_dst;
+       dst->sin_addr = sc->sc_tunnel.t_dst;
 
        return (0);
 }
@@ -510,8 +511,8 @@ mobileip_del_tunnel(struct mobileip_softc *sc)
                return (EBUSY);
 
        /* commit */
-       sc->sc_src.s_addr = INADDR_ANY;
-       sc->sc_dst.s_addr = INADDR_ANY;
+       sc->sc_tunnel.t_src.s_addr = INADDR_ANY;
+       sc->sc_tunnel.t_dst.s_addr = INADDR_ANY;
 
        return (0);
 }
@@ -519,7 +520,7 @@ mobileip_del_tunnel(struct mobileip_softc *sc)
 int
 mobileip_input(struct mbuf **mp, int *offp, int type, int af)
 {
-       struct mobileip_softc key;
+       struct mobileip_tunnel key;
        struct mbuf *m = *mp;
        struct ifnet *ifp;
        struct mobileip_softc *sc;
@@ -535,12 +536,13 @@ mobileip_input(struct mbuf **mp, int *offp, int type, int af)
 
        ip = mtod(m, struct ip *);
 
-       key.sc_rtableid = m->m_pkthdr.ph_rtableid;
-       key.sc_src = ip->ip_dst;
-       key.sc_dst = ip->ip_src;
+       key.t_rtableid = m->m_pkthdr.ph_rtableid;
+       key.t_src = ip->ip_dst;
+       key.t_dst = ip->ip_src;
 
        /* NET_ASSERT_READ_LOCKED() */
-       sc = RBT_FIND(mobileip_tree, &mobileip_softcs, &key);
+       sc = (struct mobileip_softc *)RBT_FIND(mobileip_tree,
+           &mobileip_tree, &key);
        if (sc == NULL)
                goto drop;
 
@@ -643,4 +645,4 @@ mobileip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
        return (0);
 }
 
-RBT_GENERATE(mobileip_tree, mobileip_softc, sc_entry, mobileip_cmp);
+RBT_GENERATE(mobileip_tree, mobileip_tunnel, t_entry, mobileip_cmp);