From 94c0e2bd60f346b99cc50d840aac5f7019b7b57b Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 13 Feb 2024 12:22:09 +0000 Subject: [PATCH] Merge struct route and struct route_in6. Use a common struct route for both inet and inet6. Unfortunately struct sockaddr is shorter than sockaddr_in6, so netinet/in.h has to be exposed from net/route.h. Struct route has to be bsd visible for userland as netstat kvm code inspects inp_route. Internet PCB and TCP SYN cache can use a plain struct route now. All specific sockaddr types for inet and inet6 are embeded there. OK claudio@ --- sys/net/if_bridge.c | 3 ++- sys/net/if_etherip.c | 3 ++- sys/net/if_pfsync.c | 3 ++- sys/net/if_veb.c | 3 +-- sys/net/route.c | 25 ++++++++++++------------- sys/net/route.h | 35 +++++++++++++++++++++++++---------- sys/netinet/in.h | 4 +--- sys/netinet/in_pcb.c | 6 +++--- sys/netinet/in_pcb.h | 9 ++------- sys/netinet/ip_carp.c | 3 ++- sys/netinet/ip_input.c | 4 ++-- sys/netinet/ip_output.c | 13 +++++++------ sys/netinet/ip_var.h | 3 ++- sys/netinet/tcp_input.c | 21 ++++++++------------- sys/netinet/tcp_output.c | 4 ++-- sys/netinet/tcp_subr.c | 4 ++-- sys/netinet/tcp_var.h | 13 ++----------- sys/netinet6/dest6.c | 4 +++- sys/netinet6/in6.h | 14 +------------- sys/netinet6/in6_pcb.c | 20 ++++++++------------ sys/netinet6/in6_src.c | 17 ++++++++--------- sys/netinet6/ip6_divert.c | 10 +++++----- sys/netinet6/ip6_forward.c | 8 ++++---- sys/netinet6/ip6_id.c | 3 +-- sys/netinet6/ip6_output.c | 24 ++++++++++++------------ sys/netinet6/ip6_var.h | 10 +++++----- sys/netinet6/mld6.c | 3 ++- sys/netinet6/raw_ip6.c | 4 ++-- sys/netinet6/route6.c | 3 ++- sys/netinet6/udp6_output.c | 4 ++-- usr.bin/netstat/inet.c | 10 +++++----- 31 files changed, 137 insertions(+), 153 deletions(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 486b041bcfb..51c65e8fa48 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.368 2023/05/16 14:32:54 jan Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.369 2024/02/13 12:22:09 bluhm Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -48,6 +48,7 @@ #include #include #include +#include #include #include diff --git a/sys/net/if_etherip.c b/sys/net/if_etherip.c index 653371f3e6e..dd4e90c595d 100644 --- a/sys/net/if_etherip.c +++ b/sys/net/if_etherip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_etherip.c,v 1.54 2023/12/23 10:52:54 bluhm Exp $ */ +/* $OpenBSD: if_etherip.c,v 1.55 2024/02/13 12:22:09 bluhm Exp $ */ /* * Copyright (c) 2015 Kazuya GODA * @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c index 748020fe20f..4ad51489509 100644 --- a/sys/net/if_pfsync.c +++ b/sys/net/if_pfsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.c,v 1.324 2023/12/23 10:52:54 bluhm Exp $ */ +/* $OpenBSD: if_pfsync.c,v 1.325 2024/02/13 12:22:09 bluhm Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -69,6 +69,7 @@ #include #include #include +#include #include #include diff --git a/sys/net/if_veb.c b/sys/net/if_veb.c index e6cdf6bbe65..ebbca155c89 100644 --- a/sys/net/if_veb.c +++ b/sys/net/if_veb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_veb.c,v 1.34 2023/12/23 10:52:54 bluhm Exp $ */ +/* $OpenBSD: if_veb.c,v 1.35 2024/02/13 12:22:09 bluhm Exp $ */ /* * Copyright (c) 2021 David Gwynne @@ -46,7 +46,6 @@ #ifdef INET6 #include #include -#include #endif #if 0 && defined(IPSEC) diff --git a/sys/net/route.c b/sys/net/route.c index bb9c7b05099..f9915cdf7c1 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.431 2024/02/09 14:02:11 bluhm Exp $ */ +/* $OpenBSD: route.c,v 1.432 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -212,8 +212,8 @@ route_cache(struct route *ro, struct in_addr addr, u_int rtableid) if (rtisvalid(ro->ro_rt) && ro->ro_generation == gen && ro->ro_tableid == rtableid && - ro->ro_dst.sa_family == AF_INET && - satosin(&ro->ro_dst)->sin_addr.s_addr == addr.s_addr) { + ro->ro_dstsa.sa_family == AF_INET && + ro->ro_dstsin.sin_addr.s_addr == addr.s_addr) { ipstat_inc(ips_rtcachehit); return (0); } @@ -225,17 +225,16 @@ route_cache(struct route *ro, struct in_addr addr, u_int rtableid) ro->ro_tableid = rtableid; memset(&ro->ro_dst, 0, sizeof(ro->ro_dst)); - satosin(&ro->ro_dst)->sin_family = AF_INET; - satosin(&ro->ro_dst)->sin_len = sizeof(struct sockaddr_in); - satosin(&ro->ro_dst)->sin_addr = addr; + ro->ro_dstsin.sin_family = AF_INET; + ro->ro_dstsin.sin_len = sizeof(struct sockaddr_in); + ro->ro_dstsin.sin_addr = addr; return (ESRCH); } #ifdef INET6 int -route6_cache(struct route_in6 *ro, const struct in6_addr *addr, - u_int rtableid) +route6_cache(struct route *ro, const struct in6_addr *addr, u_int rtableid) { u_long gen; @@ -245,8 +244,8 @@ route6_cache(struct route_in6 *ro, const struct in6_addr *addr, if (rtisvalid(ro->ro_rt) && ro->ro_generation == gen && ro->ro_tableid == rtableid && - ro->ro_dst.sin6_family == AF_INET6 && - IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, addr)) { + ro->ro_dstsa.sa_family == AF_INET6 && + IN6_ARE_ADDR_EQUAL(&ro->ro_dstsin6.sin6_addr, addr)) { ip6stat_inc(ip6s_rtcachehit); return (0); } @@ -258,9 +257,9 @@ route6_cache(struct route_in6 *ro, const struct in6_addr *addr, ro->ro_tableid = rtableid; memset(&ro->ro_dst, 0, sizeof(ro->ro_dst)); - ro->ro_dst.sin6_family = AF_INET6; - ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6); - ro->ro_dst.sin6_addr = *addr; + ro->ro_dstsin6.sin6_family = AF_INET6; + ro->ro_dstsin6.sin6_len = sizeof(struct sockaddr_in6); + ro->ro_dstsin6.sin6_addr = *addr; return (ESRCH); } diff --git a/sys/net/route.h b/sys/net/route.h index 9871d820c5e..7833f7ca9a8 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.205 2024/02/05 12:52:11 aoyama Exp $ */ +/* $OpenBSD: route.h,v 1.206 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -370,6 +370,19 @@ struct sockaddr_rtsearch { char sr_search[RTSEARCH_LEN]; }; +struct rt_addrinfo { + int rti_addrs; + const struct sockaddr *rti_info[RTAX_MAX]; + int rti_flags; + struct ifaddr *rti_ifa; + struct rt_msghdr *rti_rtm; + u_char rti_mpls; +}; + +#ifdef __BSD_VISIBLE + +#include + /* * A route consists of a destination address and a reference * to a routing entry. These are often held by protocols @@ -379,17 +392,17 @@ struct route { struct rtentry *ro_rt; u_long ro_generation; u_long ro_tableid; /* u_long because of alignment */ - struct sockaddr ro_dst; + union { + struct sockaddr rod_sa; + struct sockaddr_in rod_sin; + struct sockaddr_in6 rod_sin6; + } ro_dst; +#define ro_dstsa ro_dst.rod_sa +#define ro_dstsin ro_dst.rod_sin +#define ro_dstsin6 ro_dst.rod_sin6 }; -struct rt_addrinfo { - int rti_addrs; - const struct sockaddr *rti_info[RTAX_MAX]; - int rti_flags; - struct ifaddr *rti_ifa; - struct rt_msghdr *rti_rtm; - u_char rti_mpls; -}; +#endif /* __BSD_VISIBLE */ #ifdef _KERNEL @@ -449,6 +462,8 @@ struct if_ieee80211_data; struct bfd_config; void route_init(void); +int route_cache(struct route *, struct in_addr, u_int); +int route6_cache(struct route *, const struct in6_addr *, u_int); void rtm_ifchg(struct ifnet *); void rtm_ifannounce(struct ifnet *, int); void rtm_bfd(struct bfd_config *); diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 7b75fe8a7cc..f3fd58551c3 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in.h,v 1.147 2024/02/09 14:02:11 bluhm Exp $ */ +/* $OpenBSD: in.h,v 1.148 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */ /* @@ -789,8 +789,6 @@ void in_len2mask(struct in_addr *, int); int in_nam2sin(const struct mbuf *, struct sockaddr_in **); int in_sa2sin(struct sockaddr *, struct sockaddr_in **); -int route_cache(struct route *, struct in_addr, u_int); - char *inet_ntoa(struct in_addr); int inet_nat64(int, const void *, void *, const void *, u_int8_t); int inet_nat46(int, const void *, void *, const void *, u_int8_t); diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 4a600b71774..87241c03e7a 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.292 2024/02/11 01:27:45 bluhm Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.293 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -920,7 +920,7 @@ in_pcbrtentry(struct inpcb *inp) if (inp->inp_faddr.s_addr == INADDR_ANY) return (NULL); if (route_cache(ro, inp->inp_faddr, inp->inp_rtableid)) { - ro->ro_rt = rtalloc_mpath(&ro->ro_dst, + ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, &inp->inp_laddr.s_addr, ro->ro_tableid); } return (ro->ro_rt); @@ -984,7 +984,7 @@ in_pcbselsrc(struct in_addr *insrc, struct sockaddr_in *sin, */ if (route_cache(ro, sin->sin_addr, rtableid)) { /* No route yet, so try to acquire one */ - ro->ro_rt = rtalloc_mpath(&ro->ro_dst, NULL, ro->ro_tableid); + ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL, ro->ro_tableid); } /* diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 6b79f014a65..1d67469c635 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.h,v 1.151 2024/02/11 01:27:45 bluhm Exp $ */ +/* $OpenBSD: in_pcb.h,v 1.152 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */ /* @@ -150,12 +150,7 @@ struct inpcb { u_int16_t inp_lport; /* [t] local port */ struct socket *inp_socket; /* [I] back pointer to socket */ caddr_t inp_ppcb; /* pointer to per-protocol pcb */ - union { /* Route (notice increased size). */ - struct route ru_route; - struct route_in6 ru_route6; - } inp_ru; -#define inp_route inp_ru.ru_route -#define inp_route6 inp_ru.ru_route6 + struct route inp_route; /* cached route */ struct refcnt inp_refcnt; /* refcount PCB, delay memory free */ struct mutex inp_mtx; /* protect PCB and socket members */ int inp_flags; /* generic IP/datagram flags */ diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index f2aee3e422b..41e9d34cebf 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.360 2023/12/23 10:52:54 bluhm Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.361 2024/02/13 12:22:09 bluhm Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -54,6 +54,7 @@ #include #include #include +#include #include diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 6bbbcf63ce3..60c6e6a422b 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.388 2024/01/31 14:56:42 bluhm Exp $ */ +/* $OpenBSD: ip_input.c,v 1.389 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -1494,7 +1494,7 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) route_cache(&ro, ip->ip_dst, m->m_pkthdr.ph_rtableid); if (!rtisvalid(rt)) { rtfree(rt); - rt = rtalloc_mpath(&ro.ro_dst, &ip->ip_src.s_addr, + rt = rtalloc_mpath(&ro.ro_dstsa, &ip->ip_src.s_addr, m->m_pkthdr.ph_rtableid); if (rt == NULL) { ipstat_inc(ips_noroute); diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 98d0cd54fbc..561b690c765 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.394 2024/01/31 14:56:43 bluhm Exp $ */ +/* $OpenBSD: ip_output.c,v 1.395 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -167,7 +167,7 @@ reroute: * destination and is still up. If not, free it and try again. */ route_cache(ro, ip->ip_dst, m->m_pkthdr.ph_rtableid); - dst = satosin(&ro->ro_dst); + dst = &ro->ro_dstsin; if ((IN_MULTICAST(ip->ip_dst.s_addr) || (ip->ip_dst.s_addr == INADDR_BROADCAST)) && @@ -185,7 +185,7 @@ reroute: struct in_ifaddr *ia; if (ro->ro_rt == NULL) - ro->ro_rt = rtalloc_mpath(&ro->ro_dst, + ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, &ip->ip_src.s_addr, ro->ro_tableid); if (ro->ro_rt == NULL) { @@ -253,7 +253,7 @@ reroute: * still points to the address in "ro". (It may have been * changed to point to a gateway address, above.) */ - dst = satosin(&ro->ro_dst); + dst = &ro->ro_dstsin; /* * See if the caller provided any multicast options @@ -455,7 +455,7 @@ sendit: rtfree(ro->ro_rt); ro->ro_tableid = orig_rtableid; ro->ro_rt = icmp_mtudisc_clone( - satosin(&ro->ro_dst)->sin_addr, ro->ro_tableid, 0); + ro->ro_dstsin.sin_addr, ro->ro_tableid, 0); } #endif /* @@ -558,7 +558,8 @@ ip_output_ipsec_pmtu_update(struct tdb *tdb, struct route *ro, rt->rt_mtu = tdb->tdb_mtu; if (ro != NULL && ro->ro_rt != NULL) { rtfree(ro->ro_rt); - ro->ro_rt = rtalloc(&ro->ro_dst, RT_RESOLVE, rtableid); + ro->ro_rt = rtalloc(&ro->ro_dstsa, RT_RESOLVE, + rtableid); } if (rt_mtucloned) rtfree(rt); diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index cbe670b7fef..b0e6ba89106 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_var.h,v 1.112 2024/02/05 23:16:39 bluhm Exp $ */ +/* $OpenBSD: ip_var.h,v 1.113 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */ /* @@ -227,6 +227,7 @@ extern const struct pr_usrreqs rip_usrreqs; extern struct rttimer_queue ip_mtudisc_timeout_q; extern struct pool ipqent_pool; +struct rtentry; struct route; struct inpcb; diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index ec593cc2853..a828508b127 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.400 2024/02/11 01:27:45 bluhm Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.401 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -145,8 +145,8 @@ struct timeval tcp_ackdrop_ppslim_last; #define ND6_HINT(tp) \ do { \ if (tp && tp->t_inpcb && (tp->t_inpcb->inp_flags & INP_IPV6) && \ - rtisvalid(tp->t_inpcb->inp_route6.ro_rt)) { \ - nd6_nud_hint(tp->t_inpcb->inp_route6.ro_rt); \ + rtisvalid(tp->t_inpcb->inp_route.ro_rt)) { \ + nd6_nud_hint(tp->t_inpcb->inp_route.ro_rt); \ } \ } while (0) #else @@ -3166,7 +3166,7 @@ syn_cache_put(struct syn_cache *sc) /* Dealing with last reference, no lock needed. */ m_free(sc->sc_ipopts); - rtfree(sc->sc_route4.ro_rt); + rtfree(sc->sc_route.ro_rt); pool_put(&syn_cache_pool, sc); } @@ -3578,13 +3578,8 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, /* * Give the new socket our cached route reference. */ - if (src->sa_family == AF_INET) - inp->inp_route = sc->sc_route4; /* struct assignment */ -#ifdef INET6 - else - inp->inp_route6 = sc->sc_route6; -#endif - sc->sc_route4.ro_rt = NULL; + inp->inp_route = sc->sc_route; /* struct assignment */ + sc->sc_route.ro_rt = NULL; am = m_get(M_DONTWAIT, MT_SONAME); /* XXX */ if (am == NULL) @@ -4152,7 +4147,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now) if (inp != NULL) ip->ip_tos = inp->inp_ip.ip_tos; - error = ip_output(m, sc->sc_ipopts, &sc->sc_route4, + error = ip_output(m, sc->sc_ipopts, &sc->sc_route, (ip_mtudisc ? IP_MTUDISC : 0), NULL, inp ? inp->inp_seclevel : NULL, 0); break; @@ -4164,7 +4159,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now) ip6->ip6_hlim = in6_selecthlim(inp); /* leave flowlabel = 0, it is legal and require no state mgmt */ - error = ip6_output(m, NULL /*XXX*/, &sc->sc_route6, 0, + error = ip6_output(m, NULL /*XXX*/, &sc->sc_route, 0, NULL, inp ? inp->inp_seclevel : NULL); break; #endif diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index c89b3a8cf8f..cd21dfe9cff 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_output.c,v 1.142 2024/02/11 01:27:45 bluhm Exp $ */ +/* $OpenBSD: tcp_output.c,v 1.143 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */ /* @@ -1109,7 +1109,7 @@ send: #endif } error = ip6_output(m, tp->t_inpcb->inp_outputopts6, - &tp->t_inpcb->inp_route6, 0, NULL, + &tp->t_inpcb->inp_route, 0, NULL, tp->t_inpcb->inp_seclevel); break; #endif /* INET6 */ diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 0fa13da4b49..e8256d04235 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.198 2024/02/11 01:27:45 bluhm Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.199 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -401,7 +401,7 @@ tcp_respond(struct tcpcb *tp, caddr_t template, struct tcphdr *th0, ip6->ip6_plen = tlen - sizeof(struct ip6_hdr); ip6->ip6_plen = htons(ip6->ip6_plen); ip6_output(m, tp ? tp->t_inpcb->inp_outputopts6 : NULL, - tp ? &tp->t_inpcb->inp_route6 : NULL, + tp ? &tp->t_inpcb->inp_route : NULL, 0, NULL, tp ? tp->t_inpcb->inp_seclevel : NULL); break; diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 0c5263f2799..f96f39eefd2 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_var.h,v 1.175 2024/01/27 21:13:46 bluhm Exp $ */ +/* $OpenBSD: tcp_var.h,v 1.176 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */ /* @@ -247,16 +247,7 @@ struct syn_cache { TAILQ_ENTRY(syn_cache) sc_bucketq; /* [S] link on bucket list */ struct refcnt sc_refcnt; /* ref count list and timer */ struct timeout sc_timer; /* rexmt timer */ - union { /* cached route */ - struct route route4; -#ifdef INET6 - struct route_in6 route6; -#endif - } sc_route_u; -#define sc_route4 sc_route_u.route4 /* [N] */ -#ifdef INET6 -#define sc_route6 sc_route_u.route6 /* [N] */ -#endif + struct route sc_route; /* [N] cached route */ long sc_win; /* [I] advertised window */ struct syn_cache_head *sc_buckethead; /* [S] our bucket index */ struct syn_cache_set *sc_set; /* [S] our syn cache set */ diff --git a/sys/netinet6/dest6.c b/sys/netinet6/dest6.c index edd22339589..32db8b9ede8 100644 --- a/sys/netinet6/dest6.c +++ b/sys/netinet6/dest6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dest6.c,v 1.19 2022/06/29 22:45:24 bluhm Exp $ */ +/* $OpenBSD: dest6.c,v 1.20 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: dest6.c,v 1.25 2001/02/22 01:39:16 itojun Exp $ */ /* @@ -38,6 +38,8 @@ #include #include +#include + #include #include #include diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index da02561288d..642a24b1999 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.h,v 1.115 2024/02/09 14:02:12 bluhm Exp $ */ +/* $OpenBSD: in6.h,v 1.116 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -144,16 +144,6 @@ extern const struct in6_addr in6addr_linklocal_allnodes; extern const struct in6_addr in6addr_linklocal_allrouters; #if __BSD_VISIBLE -/* - * IPv6 route structure, keep fields in sync with struct route - */ -struct route_in6 { - struct rtentry *ro_rt; - u_long ro_generation; - u_long ro_tableid; /* padded to long for alignment */ - struct sockaddr_in6 ro_dst; -}; - /* * Definition of some useful macros to handle IP6 addresses */ @@ -428,8 +418,6 @@ int in6_mask2len(struct in6_addr *, u_char *); int in6_nam2sin6(const struct mbuf *, struct sockaddr_in6 **); int in6_sa2sin6(struct sockaddr *, struct sockaddr_in6 **); -int route6_cache(struct route_in6 *, const struct in6_addr *, u_int); - struct ip6_pktopts; struct ip6_moptions; diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index caa902a11f8..d622c5dcc43 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.137 2024/02/11 01:27:45 bluhm Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.138 2024/02/13 12:22:09 bluhm Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -114,13 +114,12 @@ #include #include +#include #include #include #include #include -#include - #if NSTOEPLITZ > 0 #include #endif @@ -517,13 +516,10 @@ in6_pcbnotify(struct inpcbtable *table, const struct sockaddr_in6 *dst, if ((PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) && IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) && inp->inp_route.ro_rt && - !(inp->inp_route.ro_rt->rt_flags & RTF_HOST)) { - struct sockaddr_in6 *dst6; - - dst6 = satosin6(&inp->inp_route.ro_dst); - if (IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, - &dst->sin6_addr)) - goto do_notify; + !(inp->inp_route.ro_rt->rt_flags & RTF_HOST) && + IN6_ARE_ADDR_EQUAL(&inp->inp_route.ro_dstsin6.sin6_addr, + &dst->sin6_addr)) { + goto do_notify; } /* @@ -565,12 +561,12 @@ in6_pcbnotify(struct inpcbtable *table, const struct sockaddr_in6 *dst, struct rtentry * in6_pcbrtentry(struct inpcb *inp) { - struct route_in6 *ro = &inp->inp_route6; + struct route *ro = &inp->inp_route; if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) return (NULL); if (route6_cache(ro, &inp->inp_faddr6, inp->inp_rtableid)) { - ro->ro_rt = rtalloc_mpath(sin6tosa(&ro->ro_dst), + ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, &inp->inp_laddr6.s6_addr32[0], ro->ro_tableid); } return (ro->ro_rt); diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index d34af50652d..470ad67ebbc 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.93 2024/02/09 14:02:12 bluhm Exp $ */ +/* $OpenBSD: in6_src.c,v 1.94 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -83,7 +83,7 @@ #include int in6_selectif(const struct in6_addr *, struct ip6_pktopts *, - struct ip6_moptions *, struct route_in6 *, struct ifnet **, u_int); + struct ip6_moptions *, struct route *, struct ifnet **, u_int); /* * Return an IPv6 address, which is the most appropriate for a given @@ -95,7 +95,7 @@ in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, struct inpcb *inp, struct ip6_pktopts *opts) { struct ip6_moptions *mopts = inp->inp_moptions6; - struct route_in6 *ro = &inp->inp_route6; + struct route *ro = &inp->inp_route; const struct in6_addr *laddr = &inp->inp_laddr6; u_int rtableid = inp->inp_rtableid; struct ifnet *ifp = NULL; @@ -180,8 +180,7 @@ in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, * our src addr is taken from the i/f, else punt. */ if (route6_cache(ro, dst, rtableid)) { - ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst), - RT_RESOLVE, ro->ro_tableid); + ro->ro_rt = rtalloc(&ro->ro_dstsa, RT_RESOLVE, ro->ro_tableid); } /* @@ -298,7 +297,7 @@ in6_selectsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, struct rtentry * in6_selectroute(const struct in6_addr *dst, struct ip6_pktopts *opts, - struct route_in6 *ro, unsigned int rtableid) + struct route *ro, unsigned int rtableid) { /* * Use a cached route if it exists and is valid, else try to allocate @@ -307,8 +306,8 @@ in6_selectroute(const struct in6_addr *dst, struct ip6_pktopts *opts, if (ro) { if (route6_cache(ro, dst, rtableid)) { /* No route yet, so try to acquire one */ - ro->ro_rt = rtalloc_mpath(sin6tosa(&ro->ro_dst), - NULL, ro->ro_tableid); + ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL, + ro->ro_tableid); } /* @@ -336,7 +335,7 @@ in6_selectroute(const struct in6_addr *dst, struct ip6_pktopts *opts, int in6_selectif(const struct in6_addr *dst, struct ip6_pktopts *opts, - struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp, + struct ip6_moptions *mopts, struct route *ro, struct ifnet **retifp, u_int rtableid) { struct rtentry *rt = NULL; diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c index c7b3e3ed740..0bd114ba390 100644 --- a/sys/netinet6/ip6_divert.c +++ b/sys/netinet6/ip6_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_divert.c,v 1.94 2024/02/11 18:14:27 mvs Exp $ */ +/* $OpenBSD: ip6_divert.c,v 1.95 2024/02/13 12:22:09 bluhm Exp $ */ /* * Copyright (c) 2009 Michele Marchetto @@ -30,13 +30,13 @@ #include #include +#include #include #include -#include -#include #include #include -#include +#include +#include #include #include #include @@ -180,7 +180,7 @@ divert6_output(struct inpcb *inp, struct mbuf *m, struct mbuf *nam, } else { m->m_pkthdr.ph_rtableid = inp->inp_rtableid; - error = ip6_output(m, NULL, &inp->inp_route6, + error = ip6_output(m, NULL, &inp->inp_route, IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL); } diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 54b7615f517..cdb2fb417d1 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.113 2024/02/07 23:40:40 bluhm Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.114 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -86,7 +86,7 @@ ip6_forward(struct mbuf *m, struct rtentry *rt, int srcrt) { struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); struct sockaddr *dst; - struct route_in6 ro; + struct route ro; struct ifnet *ifp = NULL; int error = 0, type = 0, code = 0, destmtu = 0; struct mbuf *mcopy = NULL; @@ -167,7 +167,7 @@ reroute: ro.ro_rt = NULL; route6_cache(&ro, &ip6->ip6_dst, m->m_pkthdr.ph_rtableid); - dst = sin6tosa(&ro.ro_dst); + dst = &ro.ro_dstsa; if (!rtisvalid(rt)) { rtfree(rt); rt = rtalloc_mpath(dst, &ip6->ip6_src.s6_addr32[0], @@ -253,7 +253,7 @@ reroute: ip6_sendredirects && (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) { if ((ifp->if_flags & IFF_POINTOPOINT) && - nd6_is_addr_neighbor(&ro.ro_dst, ifp)) { + nd6_is_addr_neighbor(&ro.ro_dstsin6, ifp)) { /* * If the incoming interface is equal to the outgoing * one, the link attached to the interface is diff --git a/sys/netinet6/ip6_id.c b/sys/netinet6/ip6_id.c index dd0b172c714..7fa5a9fdef1 100644 --- a/sys/netinet6/ip6_id.c +++ b/sys/netinet6/ip6_id.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_id.c,v 1.16 2021/03/10 10:21:49 jsg Exp $ */ +/* $OpenBSD: ip6_id.c,v 1.17 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: ip6_id.c,v 1.7 2003/09/13 21:32:59 itojun Exp $ */ /* $KAME: ip6_id.c,v 1.8 2003/09/06 13:41:06 itojun Exp $ */ @@ -89,7 +89,6 @@ #include #include -#include struct randomtab { const int ru_bits; /* resulting bits */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 3efd26129cb..adb5f30554d 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.285 2024/02/07 23:40:40 bluhm Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.286 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -143,7 +143,7 @@ static __inline u_int16_t __attribute__((__unused__)) u_int32_t, u_int32_t); void in6_delayed_cksum(struct mbuf *, u_int8_t); -int ip6_output_ipsec_pmtu_update(struct tdb *, struct route_in6 *, +int ip6_output_ipsec_pmtu_update(struct tdb *, struct route *, struct in6_addr *, int, int, int); /* Context for non-repeating IDs */ @@ -160,14 +160,14 @@ struct idgen32_ctx ip6_id_ctx; * We use u_long to hold largest one, * which is rt_mtu. */ int -ip6_output(struct mbuf *m, struct ip6_pktopts *opt, struct route_in6 *ro, +ip6_output(struct mbuf *m, struct ip6_pktopts *opt, struct route *ro, int flags, struct ip6_moptions *im6o, const u_char seclevel[]) { struct ip6_hdr *ip6; struct ifnet *ifp = NULL; struct mbuf_list ml; int hlen, tlen; - struct route_in6 ip6route; + struct route iproute; struct rtentry *rt = NULL; struct sockaddr_in6 *dst; int error = 0; @@ -177,7 +177,7 @@ ip6_output(struct mbuf *m, struct ip6_pktopts *opt, struct route_in6 *ro, u_int32_t optlen = 0, plen = 0, unfragpartlen = 0; struct ip6_exthdrs exthdrs; struct in6_addr finaldst; - struct route_in6 *ro_pmtu = NULL; + struct route *ro_pmtu = NULL; int hdrsplit = 0; u_int8_t sproto = 0; u_char nextproto; @@ -390,13 +390,13 @@ reroute: /* initialize cached route */ if (ro == NULL) { - ro = &ip6route; + ro = &iproute; bzero((caddr_t)ro, sizeof(*ro)); } ro_pmtu = ro; if (opt && opt->ip6po_rthdr) ro = &opt->ip6po_route; - dst = &ro->ro_dst; + dst = &ro->ro_dstsin6; /* * if specified, try to fill in the traffic class field. @@ -750,9 +750,9 @@ reroute: ip6stat_inc(ip6s_fragmented); done: - if (ro == &ip6route && ro->ro_rt) { + if (ro == &iproute && ro->ro_rt) { rtfree(ro->ro_rt); - } else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt) { + } else if (ro_pmtu == &iproute && ro_pmtu->ro_rt) { rtfree(ro_pmtu->ro_rt); } if_put(ifp); @@ -2772,7 +2772,7 @@ ip6_output_ipsec_lookup(struct mbuf *m, const u_char seclevel[], } int -ip6_output_ipsec_pmtu_update(struct tdb *tdb, struct route_in6 *ro, +ip6_output_ipsec_pmtu_update(struct tdb *tdb, struct route *ro, struct in6_addr *dst, int ifidx, int rtableid, int transportmode) { struct rtentry *rt = NULL; @@ -2807,7 +2807,7 @@ ip6_output_ipsec_pmtu_update(struct tdb *tdb, struct route_in6 *ro, rt->rt_mtu = tdb->tdb_mtu; if (ro != NULL && ro->ro_rt != NULL) { rtfree(ro->ro_rt); - ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst), RT_RESOLVE, + ro->ro_rt = rtalloc(&ro->ro_dstsa, RT_RESOLVE, rtableid); } if (rt_mtucloned) @@ -2817,7 +2817,7 @@ ip6_output_ipsec_pmtu_update(struct tdb *tdb, struct route_in6 *ro, } int -ip6_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route_in6 *ro, +ip6_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route *ro, int tunalready, int fwd) { struct mbuf_list ml; diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index f23287b6f28..f4c068dc03a 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.112 2024/02/07 23:40:40 bluhm Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.113 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -103,7 +103,7 @@ struct ip6_moptions { /* Routing header related info */ struct ip6po_rhinfo { struct ip6_rthdr *ip6po_rhi_rthdr; /* Routing header */ - struct route_in6 ip6po_rhi_route; /* Route to the 1st hop */ + struct route ip6po_rhi_route; /* Route to the 1st hop */ }; #define ip6po_rthdr ip6po_rhinfo.ip6po_rhi_rthdr #define ip6po_route ip6po_rhinfo.ip6po_rhi_route @@ -323,7 +323,7 @@ int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); void ip6_forward(struct mbuf *, struct rtentry *, int); void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *); -int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route_in6 *, int, +int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int, struct ip6_moptions *, const u_char[]); int ip6_fragment(struct mbuf *, struct mbuf_list *, int, u_char, u_long); int ip6_ctloutput(int, struct socket *, int, int, struct mbuf *); @@ -370,14 +370,14 @@ int in6_pcbselsrc(const struct in6_addr **, struct sockaddr_in6 *, int in6_selectsrc(const struct in6_addr **, struct sockaddr_in6 *, struct ip6_moptions *, unsigned int); struct rtentry *in6_selectroute(const struct in6_addr *, struct ip6_pktopts *, - struct route_in6 *, unsigned int rtableid); + struct route *, unsigned int rtableid); u_int32_t ip6_randomflowlabel(void); #ifdef IPSEC struct tdb; int ip6_output_ipsec_lookup(struct mbuf *, const u_char[], struct tdb **); -int ip6_output_ipsec_send(struct tdb *, struct mbuf *, struct route_in6 *, +int ip6_output_ipsec_send(struct tdb *, struct mbuf *, struct route *, int, int); #endif /* IPSEC */ diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index f05224db192..0c5b49e022e 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mld6.c,v 1.61 2022/09/08 10:22:07 kn Exp $ */ +/* $OpenBSD: mld6.c,v 1.62 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: mld6.c,v 1.26 2001/02/16 14:50:35 itojun Exp $ */ /* @@ -74,6 +74,7 @@ #include #include +#include #include #include diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 653c3005608..177eeb8e88b 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.181 2024/02/11 18:14:27 mvs Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.182 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -512,7 +512,7 @@ rip6_output(struct mbuf *m, struct socket *so, struct sockaddr *dstaddr, pf_mbuf_link_inpcb(m, inp); #endif - error = ip6_output(m, optp, &inp->inp_route6, flags, + error = ip6_output(m, optp, &inp->inp_route, flags, inp->inp_moptions6, inp->inp_seclevel); if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { icmp6stat_inc(icp6s_outhist + type); diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c index 914059abc69..f07334d3f8c 100644 --- a/sys/netinet6/route6.c +++ b/sys/netinet6/route6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route6.c,v 1.21 2017/04/14 20:46:31 bluhm Exp $ */ +/* $OpenBSD: route6.c,v 1.22 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: route6.c,v 1.22 2000/12/03 00:54:00 itojun Exp $ */ /* @@ -37,6 +37,7 @@ #include #include +#include #include #include diff --git a/sys/netinet6/udp6_output.c b/sys/netinet6/udp6_output.c index f655f445dd1..324092ce7dd 100644 --- a/sys/netinet6/udp6_output.c +++ b/sys/netinet6/udp6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp6_output.c,v 1.63 2023/12/03 20:36:24 bluhm Exp $ */ +/* $OpenBSD: udp6_output.c,v 1.64 2024/02/13 12:22:09 bluhm Exp $ */ /* $KAME: udp6_output.c,v 1.21 2001/02/07 11:51:54 itojun Exp $ */ /* @@ -232,7 +232,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct mbuf *addr6, pf_mbuf_link_inpcb(m, inp); #endif - error = ip6_output(m, optp, &inp->inp_route6, + error = ip6_output(m, optp, &inp->inp_route, flags, inp->inp_moptions6, inp->inp_seclevel); goto releaseopt; diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index 560b8594bd8..a5bcd793822 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inet.c,v 1.180 2024/02/05 23:16:39 bluhm Exp $ */ +/* $OpenBSD: inet.c,v 1.181 2024/02/13 12:22:09 bluhm Exp $ */ /* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */ /* @@ -1461,14 +1461,14 @@ inpcb_dump(u_long off, short protocol, int af) case AF_INET: inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr)); inet_ntop(af, &inp.inp_laddr, laddr, sizeof(laddr)); - inet_ntop(af, &((struct sockaddr_in *) - (&inp.inp_route.ro_dst))->sin_addr, raddr, sizeof(raddr)); + inet_ntop(af, &inp.inp_route.ro_dstsin.sin_addr, raddr, + sizeof(raddr)); break; case AF_INET6: inet_ntop(af, &inp.inp_faddr6, faddr, sizeof(faddr)); inet_ntop(af, &inp.inp_laddr6, laddr, sizeof(laddr)); - inet_ntop(af, &inp.inp_route6.ro_dst.sin6_addr, - raddr, sizeof(raddr)); + inet_ntop(af, &inp.inp_route.ro_dstsin6.sin6_addr, raddr, + sizeof(raddr)); break; default: faddr[0] = laddr[0] = '\0'; -- 2.20.1