Use constant sockaddr in route lookup.
authorbluhm <bluhm@openbsd.org>
Sun, 12 Nov 2023 17:51:40 +0000 (17:51 +0000)
committerbluhm <bluhm@openbsd.org>
Sun, 12 Nov 2023 17:51:40 +0000 (17:51 +0000)
In rtalloc() and rtalloc_mpath() declare the parameter dst as const
sockaddr.  This makes MP safe route lookup easier as the destination
address is definitely not modified during the operation.  Array
rti_info, the central data structure with addresses for route
matching, contains constant sockaddr now.

OK mvs@ dlg@

sys/net/if_dl.h
sys/net/route.c
sys/net/route.h
sys/net/rtable.c
sys/net/rtable.h
sys/net/rtsock.c

index 229cdad..9271995 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_dl.h,v 1.12 2017/05/04 15:00:24 bluhm Exp $        */
+/*     $OpenBSD: if_dl.h,v 1.13 2023/11/12 17:51:40 bluhm Exp $        */
 /*     $NetBSD: if_dl.h,v 1.8 1995/03/26 20:30:13 jtc Exp $    */
 
 /*
@@ -79,6 +79,12 @@ satosdl(struct sockaddr *sa)
        return ((struct sockaddr_dl *)(sa));
 }
 
+static inline const struct sockaddr_dl *
+satosdl_const(const struct sockaddr *sa)
+{
+       return ((const struct sockaddr_dl *)(sa));
+}
+
 static inline struct sockaddr *
 sdltosa(struct sockaddr_dl *sdl)
 {
index 0b401f9..f6930ba 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: route.c,v 1.424 2023/11/12 15:42:05 dlg Exp $ */
+/*     $OpenBSD: route.c,v 1.425 2023/11/12 17:51:40 bluhm Exp $       */
 /*     $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $      */
 
 /*
@@ -158,15 +158,17 @@ int                       rttrash;        /* routes not in table but not freed */
 struct pool    rtentry_pool;           /* pool for rtentry structures */
 struct pool    rttimer_pool;           /* pool for rttimer structures */
 
-int    rt_setgwroute(struct rtentry *, struct sockaddr *, u_int);
+int    rt_setgwroute(struct rtentry *, const struct sockaddr *, u_int);
 void   rt_putgwroute(struct rtentry *, struct rtentry *);
 int    rtflushclone1(struct rtentry *, void *, u_int);
 int    rtflushclone(struct rtentry *, unsigned int);
 int    rt_ifa_purge_walker(struct rtentry *, void *, unsigned int);
-struct rtentry *rt_match(struct sockaddr *, uint32_t *, int, unsigned int);
-int    rt_clone(struct rtentry **, struct sockaddr *, unsigned int);
+struct rtentry *rt_match(const struct sockaddr *, uint32_t *, int,
+    unsigned int);
+int    rt_clone(struct rtentry **, const struct sockaddr *, unsigned int);
 struct sockaddr *rt_plentosa(sa_family_t, int, struct sockaddr_in6 *);
-static int rt_copysa(struct sockaddr *, struct sockaddr *, struct sockaddr **);
+static int rt_copysa(const struct sockaddr *, const struct sockaddr *,
+    struct sockaddr **);
 
 #define        LABELID_MAX     50000
 
@@ -229,7 +231,8 @@ rtisvalid(struct rtentry *rt)
  * NDP), if it does not exist.
  */
 struct rtentry *
-rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid)
+rt_match(const struct sockaddr *dst, uint32_t *src, int flags,
+    unsigned int tableid)
 {
        struct rtentry          *rt = NULL;
 
@@ -247,7 +250,8 @@ rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid)
 }
 
 int
-rt_clone(struct rtentry **rtp, struct sockaddr *dst, unsigned int rtableid)
+rt_clone(struct rtentry **rtp, const struct sockaddr *dst,
+    unsigned int rtableid)
 {
        struct rt_addrinfo       info;
        struct rtentry          *rt = *rtp;
@@ -355,7 +359,7 @@ rt_hash(struct rtentry *rt, const struct sockaddr *dst, uint32_t *src)
  * Allocate a route, potentially using multipath to select the peer.
  */
 struct rtentry *
-rtalloc_mpath(struct sockaddr *dst, uint32_t *src, unsigned int rtableid)
+rtalloc_mpath(const struct sockaddr *dst, uint32_t *src, unsigned int rtableid)
 {
        return (rt_match(dst, src, RT_RESOLVE, rtableid));
 }
@@ -368,7 +372,7 @@ rtalloc_mpath(struct sockaddr *dst, uint32_t *src, unsigned int rtableid)
  * longer valid, try to cache it.
  */
 struct rtentry *
-rtalloc(struct sockaddr *dst, int flags, unsigned int rtableid)
+rtalloc(const struct sockaddr *dst, int flags, unsigned int rtableid)
 {
        return (rt_match(dst, NULL, flags, rtableid));
 }
@@ -378,7 +382,7 @@ rtalloc(struct sockaddr *dst, int flags, unsigned int rtableid)
  * the gateway entry ``rt''.
  */
 int
-rt_setgwroute(struct rtentry *rt, struct sockaddr *gate, u_int rtableid)
+rt_setgwroute(struct rtentry *rt, const struct sockaddr *gate, u_int rtableid)
 {
        struct rtentry *prt, *nhrt;
        unsigned int rdomain = rtable_l2(rtableid);
@@ -988,7 +992,7 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
 }
 
 int
-rt_setgate(struct rtentry *rt, struct sockaddr *gate, u_int rtableid)
+rt_setgate(struct rtentry *rt, const struct sockaddr *gate, u_int rtableid)
 {
        int glen = ROUNDUP(gate->sa_len);
        struct sockaddr *sa, *osa;
@@ -1064,7 +1068,8 @@ rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst,
  * that is useable for the routing table.
  */
 static int
-rt_copysa(struct sockaddr *src, struct sockaddr *mask, struct sockaddr **dst)
+rt_copysa(const struct sockaddr *src, const struct sockaddr *mask,
+    struct sockaddr **dst)
 {
        static const u_char maskarray[] = {
            0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
@@ -1576,7 +1581,7 @@ rt_timer_timer(void *arg)
 
 #ifdef MPLS
 int
-rt_mpls_set(struct rtentry *rt, struct sockaddr *src, uint8_t op)
+rt_mpls_set(struct rtentry *rt, const struct sockaddr *src, uint8_t op)
 {
        struct sockaddr_mpls    *psa_mpls = (struct sockaddr_mpls *)src;
        struct rt_mpls          *rt_mpls;
@@ -1614,7 +1619,7 @@ rt_mpls_clear(struct rtentry *rt)
 #endif
 
 u_int16_t
-rtlabel_name2id(char *name)
+rtlabel_name2id(const char *name)
 {
        struct rt_label         *label, *p;
        u_int16_t                new_id = 1, id = 0;
index 9b4ea5c..96a76d7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: route.h,v 1.202 2023/11/12 15:42:54 dlg Exp $ */
+/*     $OpenBSD: route.h,v 1.203 2023/11/12 17:51:40 bluhm Exp $       */
 /*     $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $       */
 
 /*
@@ -383,7 +383,7 @@ struct route {
 
 struct rt_addrinfo {
        int     rti_addrs;
-       struct  sockaddr *rti_info[RTAX_MAX];
+       const   struct sockaddr *rti_info[RTAX_MAX];
        int     rti_flags;
        struct  ifaddr *rti_ifa;
        struct  rt_msghdr *rti_rtm;
@@ -428,7 +428,7 @@ struct rttimer_queue {
 
 const char     *rtlabel_id2name_locked(u_int16_t);
 const char     *rtlabel_id2name(u_int16_t, char *, size_t);
-u_int16_t       rtlabel_name2id(char *);
+u_int16_t       rtlabel_name2id(const char *);
 struct sockaddr        *rtlabel_id2sa(u_int16_t, struct sockaddr_rtlabel *);
 void            rtlabel_unref(u_int16_t);
 
@@ -458,7 +458,7 @@ void         rtm_send(struct rtentry *, int, int, unsigned int);
 void    rtm_addr(int, struct ifaddr *);
 void    rtm_miss(int, struct rt_addrinfo *, int, uint8_t, u_int, int, u_int);
 void    rtm_proposal(struct ifnet *, struct rt_addrinfo *, int, uint8_t);
-int     rt_setgate(struct rtentry *, struct sockaddr *, u_int);
+int     rt_setgate(struct rtentry *, const struct sockaddr *, u_int);
 struct rtentry *rt_getll(struct rtentry *);
 
 void           rt_timer_init(void);
@@ -473,13 +473,13 @@ void              rt_timer_queue_flush(struct rttimer_queue *);
 unsigned long  rt_timer_queue_count(struct rttimer_queue *);
 void           rt_timer_timer(void *);
 
-int     rt_mpls_set(struct rtentry *, struct sockaddr *, uint8_t);
+int     rt_mpls_set(struct rtentry *, const struct sockaddr *, uint8_t);
 void    rt_mpls_clear(struct rtentry *);
 
 int     rtisvalid(struct rtentry *);
 int     rt_hash(struct rtentry *, const struct sockaddr *, uint32_t *);
-struct  rtentry *rtalloc_mpath(struct sockaddr *, uint32_t *, u_int);
-struct  rtentry *rtalloc(struct sockaddr *, int, unsigned int);
+struct  rtentry *rtalloc_mpath(const struct sockaddr *, uint32_t *, u_int);
+struct  rtentry *rtalloc(const struct sockaddr *, int, unsigned int);
 void    rtref(struct rtentry *);
 void    rtfree(struct rtentry *);
 
index f2519eb..38282eb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rtable.c,v 1.84 2023/11/11 12:17:50 bluhm Exp $ */
+/*     $OpenBSD: rtable.c,v 1.85 2023/11/12 17:51:40 bluhm Exp $ */
 
 /*
  * Copyright (c) 2014-2016 Martin Pieuchot
@@ -352,7 +352,7 @@ rtable_l2set(unsigned int rtableid, unsigned int rdomain, unsigned int loifidx)
 static inline const uint8_t *satoaddr(struct art_root *,
     const struct sockaddr *);
 
-int    an_match(struct art_node *, struct sockaddr *, int);
+int    an_match(struct art_node *, const struct sockaddr *, int);
 void   rtentry_ref(void *, void *);
 void   rtentry_unref(void *, void *);
 
@@ -415,8 +415,8 @@ rtable_clearsource(unsigned int rtableid, struct sockaddr *src)
 }
 
 struct rtentry *
-rtable_lookup(unsigned int rtableid, struct sockaddr *dst,
-    struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio)
+rtable_lookup(unsigned int rtableid, const struct sockaddr *dst,
+    const struct sockaddr *mask, const struct sockaddr *gateway, uint8_t prio)
 {
        struct art_root                 *ar;
        struct art_node                 *an;
@@ -545,7 +545,7 @@ out:
 
 int
 rtable_insert(unsigned int rtableid, struct sockaddr *dst,
-    struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio,
+    const struct sockaddr *mask, const struct sockaddr *gateway, uint8_t prio,
     struct rtentry *rt)
 {
        struct rtentry                  *mrt;
@@ -650,8 +650,8 @@ leave:
 }
 
 int
-rtable_delete(unsigned int rtableid, struct sockaddr *dst,
-    struct sockaddr *mask, struct rtentry *rt)
+rtable_delete(unsigned int rtableid, const struct sockaddr *dst,
+    const struct sockaddr *mask, struct rtentry *rt)
 {
        struct art_root                 *ar;
        struct art_node                 *an;
@@ -865,7 +865,7 @@ rtable_mpath_insert(struct art_node *an, struct rtentry *rt)
  * Returns 1 if ``an'' perfectly matches (``dst'', ``plen''), 0 otherwise.
  */
 int
-an_match(struct art_node *an, struct sockaddr *dst, int plen)
+an_match(struct art_node *an, const struct sockaddr *dst, int plen)
 {
        struct rtentry                  *rt;
        struct srp_ref                   sr;
@@ -912,7 +912,7 @@ satoaddr(struct art_root *at, const struct sockaddr *sa)
  * Return the prefix length of a mask.
  */
 int
-rtable_satoplen(sa_family_t af, struct sockaddr *mask)
+rtable_satoplen(sa_family_t af, const struct sockaddr *mask)
 {
        const struct domain     *dp;
        uint8_t                 *ap, *ep;
index a849183..441c471 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rtable.h,v 1.27 2023/11/10 20:05:22 bluhm Exp $ */
+/*     $OpenBSD: rtable.h,v 1.28 2023/11/12 17:51:41 bluhm Exp $ */
 
 /*
  * Copyright (c) 2014-2016 Martin Pieuchot
@@ -29,7 +29,7 @@
 #define        rt_plen(rt)     ((rt)->rt_plen)
 #define        RT_ROOT(rt)     (0)
 
-int             rtable_satoplen(sa_family_t, struct sockaddr *);
+int             rtable_satoplen(sa_family_t, const struct sockaddr *);
 
 void            rtable_init(void);
 int             rtable_exists(unsigned int);
@@ -42,16 +42,16 @@ void                 rtable_l2set(unsigned int, unsigned int, unsigned int);
 int             rtable_setsource(unsigned int, int, struct sockaddr *);
 struct sockaddr *rtable_getsource(unsigned int, int);
 void            rtable_clearsource(unsigned int, struct sockaddr *);
-struct rtentry *rtable_lookup(unsigned int, struct sockaddr *,
-                    struct sockaddr *, struct sockaddr *, uint8_t);
+struct rtentry *rtable_lookup(unsigned int, const struct sockaddr *,
+                    const struct sockaddr *, const struct sockaddr *, uint8_t);
 struct rtentry *rtable_match(unsigned int, const struct sockaddr *,
                     uint32_t *);
 struct rtentry *rtable_iterate(struct rtentry *);
 int             rtable_insert(unsigned int, struct sockaddr *,
-                    struct sockaddr *, struct sockaddr *, uint8_t,
+                    const struct sockaddr *, const struct sockaddr *, uint8_t,
                     struct rtentry *);
-int             rtable_delete(unsigned int, struct sockaddr *,
-                    struct sockaddr *, struct rtentry *);
+int             rtable_delete(unsigned int, const struct sockaddr *,
+                    const struct sockaddr *, struct rtentry *);
 int             rtable_walk(unsigned int, sa_family_t, struct rtentry **,
                     int (*)(struct rtentry *, void *, unsigned int), void *);
 
index 3d25239..0816eb7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rtsock.c,v 1.371 2023/11/12 16:10:46 bluhm Exp $      */
+/*     $OpenBSD: rtsock.c,v 1.372 2023/11/12 17:51:41 bluhm Exp $      */
 /*     $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $  */
 
 /*
@@ -145,7 +145,7 @@ int          sysctl_iflist(int, struct walkarg *);
 int             sysctl_ifnames(struct walkarg *);
 int             sysctl_rtable_rtstat(void *, size_t *, void *);
 
-int             rt_setsource(unsigned int, struct sockaddr *);
+int             rt_setsource(unsigned int, const struct sockaddr *);
 
 /*
  * Locks used to protect struct members
@@ -1176,7 +1176,7 @@ change:
                ifp->if_rtrequest(ifp, RTM_ADD, rt);
 
                if (info->rti_info[RTAX_LABEL] != NULL) {
-                       char *rtlabel = ((struct sockaddr_rtlabel *)
+                       const char *rtlabel = ((const struct sockaddr_rtlabel *)
                            info->rti_info[RTAX_LABEL])->sr_label;
                        rtlabel_unref(rt->rt_labelid);
                        rt->rt_labelid = rtlabel_name2id(rtlabel);
@@ -1202,8 +1202,8 @@ change:
 }
 
 struct ifaddr *
-ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
-    unsigned int rtableid)
+ifa_ifwithroute(int flags, const struct sockaddr *dst,
+    const struct sockaddr *gateway, unsigned int rtableid)
 {
        struct ifaddr   *ifa;
 
@@ -1230,9 +1230,11 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
        }
        if (ifa == NULL) {
                if (gateway->sa_family == AF_LINK) {
-                       struct sockaddr_dl *sdl = satosdl(gateway);
-                       struct ifnet *ifp = if_get(sdl->sdl_index);
+                       const struct sockaddr_dl *sdl;
+                       struct ifnet *ifp;
 
+                       sdl = satosdl_const(gateway);
+                       ifp = if_get(sdl->sdl_index);
                        if (ifp != NULL)
                                ifa = ifaof_ifpforaddr(dst, ifp);
                        if_put(ifp);
@@ -1272,9 +1274,9 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
         * is ambiguous
         */
        if (info->rti_info[RTAX_IFP] != NULL) {
-               struct sockaddr_dl *sdl;
+               const struct sockaddr_dl *sdl;
 
-               sdl = satosdl(info->rti_info[RTAX_IFP]);
+               sdl = satosdl_const(info->rti_info[RTAX_IFP]);
                ifp = if_get(sdl->sdl_index);
        }
 
@@ -1294,7 +1296,7 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
                info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid);
 
        if (info->rti_ifa == NULL) {
-               struct sockaddr *sa;
+               const struct sockaddr   *sa;
 
                if ((sa = info->rti_info[RTAX_IFA]) == NULL)
                        if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL)
@@ -1573,7 +1575,7 @@ rtm_msg1(int type, struct rt_addrinfo *rtinfo)
        struct rt_msghdr        *rtm;
        struct mbuf             *m;
        int                      i;
-       struct sockaddr         *sa;
+       const struct sockaddr   *sa;
        int                      len, dlen, hlen;
 
        switch (type) {
@@ -1666,7 +1668,7 @@ again:
        if ((cp0 = cp) != NULL)
                cp += len;
        for (i = 0; i < RTAX_MAX; i++) {
-               struct sockaddr *sa;
+               const struct sockaddr *sa;
 
                if ((sa = rtinfo->rti_info[i]) == NULL)
                        continue;
@@ -1753,7 +1755,7 @@ rtm_miss(int type, struct rt_addrinfo *rtinfo, int flags, uint8_t prio,
 {
        struct rt_msghdr        *rtm;
        struct mbuf             *m;
-       struct sockaddr         *sa = rtinfo->rti_info[RTAX_DST];
+       const struct sockaddr   *sa = rtinfo->rti_info[RTAX_DST];
 
        if (rtptable.rtp_count == 0)
                return;
@@ -2275,7 +2277,7 @@ rtm_validate_proposal(struct rt_addrinfo *info)
        }
 
        if (ISSET(info->rti_addrs, RTA_NETMASK)) {
-               struct sockaddr *sa = info->rti_info[RTAX_NETMASK];
+               const struct sockaddr *sa = info->rti_info[RTAX_NETMASK];
                if (sa == NULL)
                        return -1;
                switch (sa->sa_family) {
@@ -2293,7 +2295,7 @@ rtm_validate_proposal(struct rt_addrinfo *info)
        }
 
        if (ISSET(info->rti_addrs, RTA_IFA)) {
-               struct sockaddr *sa = info->rti_info[RTAX_IFA];
+               const struct sockaddr *sa = info->rti_info[RTAX_IFA];
                if (sa == NULL)
                        return -1;
                switch (sa->sa_family) {
@@ -2311,8 +2313,8 @@ rtm_validate_proposal(struct rt_addrinfo *info)
        }
 
        if (ISSET(info->rti_addrs, RTA_DNS)) {
-               struct sockaddr_rtdns *rtdns =
-                   (struct sockaddr_rtdns *)info->rti_info[RTAX_DNS];
+               const struct sockaddr_rtdns *rtdns =
+                   (const struct sockaddr_rtdns *)info->rti_info[RTAX_DNS];
                if (rtdns == NULL)
                        return -1;
                if (rtdns->sr_len > sizeof(*rtdns))
@@ -2338,8 +2340,8 @@ rtm_validate_proposal(struct rt_addrinfo *info)
        }
 
        if (ISSET(info->rti_addrs, RTA_STATIC)) {
-               struct sockaddr_rtstatic *rtstatic =
-                   (struct sockaddr_rtstatic *)info->rti_info[RTAX_STATIC];
+               const struct sockaddr_rtstatic *rtstatic = (const struct
+                   sockaddr_rtstatic *)info->rti_info[RTAX_STATIC];
                if (rtstatic == NULL)
                        return -1;
                if (rtstatic->sr_len > sizeof(*rtstatic))
@@ -2350,8 +2352,8 @@ rtm_validate_proposal(struct rt_addrinfo *info)
        }
 
        if (ISSET(info->rti_addrs, RTA_SEARCH)) {
-               struct sockaddr_rtsearch *rtsearch =
-                   (struct sockaddr_rtsearch *)info->rti_info[RTAX_SEARCH];
+               const struct sockaddr_rtsearch *rtsearch = (const struct
+                   sockaddr_rtsearch *)info->rti_info[RTAX_SEARCH];
                if (rtsearch == NULL)
                        return -1;
                if (rtsearch->sr_len > sizeof(*rtsearch))
@@ -2365,7 +2367,7 @@ rtm_validate_proposal(struct rt_addrinfo *info)
 }
 
 int
-rt_setsource(unsigned int rtableid, struct sockaddr *src)
+rt_setsource(unsigned int rtableid, const struct sockaddr *src)
 {
        struct ifaddr   *ifa;
        /*
@@ -2374,14 +2376,14 @@ rt_setsource(unsigned int rtableid, struct sockaddr *src)
         */
        switch(src->sa_family) {
        case AF_INET:
-               if(satosin(src)->sin_addr.s_addr == INADDR_ANY) {
+               if(satosin_const(src)->sin_addr.s_addr == INADDR_ANY) {
                        rtable_setsource(rtableid, AF_INET, NULL);
                        return (0);
                }
                break;
 #ifdef INET6
        case AF_INET6:
-               if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(src)->sin6_addr)) {
+               if (IN6_IS_ADDR_UNSPECIFIED(&satosin6_const(src)->sin6_addr)) {
                        rtable_setsource(rtableid, AF_INET6, NULL);
                        return (0);
                }