tell pfctl(8) route-to and reply-to accept next-hop only

2021-01-12 Thread Alexandr Nedvedicky
Hello,

proposed diff follows stuff discussed here [1] (pf route-to issues).  I think
we've reached a consensus to change route-to/reply-to such the only supported
option will be next-hop (and list and table of next-hop addresses).

I think bluhm@ and dlg@ have committed part of that change already.
the proposed diff updates pfctl(8) so parser will do 'a right thing',
namely:

specifying host using form as 1.2.3.4@em0 is not supporte
anymore

diff introduces a next_hop() function, which is a clone of
existing host(). unlike host(), the next_hop() does not accept
a name of local network interface.

the diff also breaks existing regression tests. We can update
them once, we will agree on proposed diff.

thanks and
regards
sashan

[1] https://marc.info/?l=openbsd-tech&m=160308583701259&w=2

8<---8<---8<--8<
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 2b3e62b1a7e..536aec3286b 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -3745,23 +3745,13 @@ pool_opt: BITMASK   {
;
 
 route_host : STRING{
-   /* try to find @if0 address specs */
-   if (strrchr($1, '@') != NULL) {
-   if (($$ = host($1, pf->opts)) == NULL)  {
-   yyerror("invalid host for route spec");
-   YYERROR;
-   }
+   if (($$ = next_hop($1, pf->opts)) == NULL)  {
+   /* error. "any" is handled elsewhere */
free($1);
-   } else {
-   $$ = calloc(1, sizeof(struct node_host));
-   if ($$ == NULL)
-   err(1, "route_host: calloc");
-   $$->ifname = $1;
-   $$->addr.type = PF_ADDR_NONE;
-   set_ipmask($$, 128);
-   $$->next = NULL;
-   $$->tail = $$;
+   yyerror("could not parse host specification");
+   YYERROR;
}
+   free($1);
}
| STRING '/' STRING {
char*buf;
@@ -3769,7 +3759,7 @@ route_host: STRING{
if (asprintf(&buf, "%s/%s", $1, $3) == -1)
err(1, "host: asprintf");
free($1);
-   if (($$ = host(buf, pf->opts)) == NULL) {
+   if (($$ = next_hop(buf, pf->opts)) == NULL) {
/* error. "any" is handled elsewhere */
free(buf);
yyerror("could not parse host specification");
@@ -3795,33 +3785,6 @@ route_host   : STRING{
$$->next = NULL;
$$->tail = $$;
}
-   | dynaddr '/' NUMBER{
-   struct node_host*n;
-
-   if ($3 < 0 || $3 > 128) {
-   yyerror("bit number too big");
-   YYERROR;
-   }
-   $$ = $1;
-   for (n = $1; n != NULL; n = n->next)
-   set_ipmask(n, $3);
-   }
-   | '(' STRING host ')'   {
-   struct node_host*n;
-
-   $$ = $3;
-   /* XXX check masks, only full mask should be allowed */
-   for (n = $3; n != NULL; n = n->next) {
-   if ($$->ifname) {
-   yyerror("cannot specify interface twice 
"
-   "in route spec");
-   YYERROR;
-   }
-   if (($$->ifname = strdup($2)) == NULL)
-   errx(1, "host: strdup");
-   }
-   free($2);
-   }
;
 
 route_host_list: route_host optweight optnl{ 
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 03317844e91..534b53b1198 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1615,17 +1615,16 @@ host(const char *s, int opts)
 {
struct node_host*h = NULL, *n;
int  mask = -1;
-   char*p, *ps, *if_name;
+   char*p, *ps;
const char  *errstr;
 
+   if (strchr(s, '@') !

bgpd refactor route decision process

2021-01-12 Thread Claudio Jeker
This diff changes two things:
- First, it move the kroute update into rde_generate_updates() simplifying
prefix_evaluate a little bit.

- Second, it changes prefix_evaluate to take an additional argument for the
old prefix (to be removed). Instead of doing this outside of
prefix_evaluate() with some drawbacks in case the same prefix is removed
and readded, the code is now in prefix_evaluate() and does all the magic
itself.

This is a necessary step to finally fix MED sorting.
-- 
:wq Claudio

Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.511
diff -u -p -r1.511 rde.c
--- rde.c   9 Jan 2021 16:49:41 -   1.511
+++ rde.c   12 Jan 2021 16:17:31 -
@@ -2825,6 +2825,9 @@ rde_generate_updates(struct rib *rib, st
if (old == NULL && new == NULL)
return;
 
+   if ((rib->flags & F_RIB_NOFIB) == 0)
+   rde_send_kroute(rib, new, old);
+
if (new)
aid = new->pt->aid;
else
@@ -3533,8 +3536,7 @@ rde_softreconfig_sync_reeval(struct rib_
/* need to re-link the nexthop if not already linked */
if ((p->flags & PREFIX_NEXTHOP_LINKED) == 0)
nexthop_link(p);
-   LIST_REMOVE(p, entry.list.rib);
-   prefix_evaluate(p, re);
+   prefix_evaluate(re, p, p);
}
 }
 
Index: rde.h
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.235
diff -u -p -r1.235 rde.h
--- rde.h   4 Dec 2020 11:57:13 -   1.235
+++ rde.h   12 Jan 2021 16:17:31 -
@@ -483,10 +483,10 @@ communities_unref(struct rde_community *
communities_unlink(comm);
 }
 
-int community_to_rd(struct community *, u_int64_t *);
+intcommunity_to_rd(struct community *, u_int64_t *);
 
 /* rde_decide.c */
-voidprefix_evaluate(struct prefix *, struct rib_entry *);
+void   prefix_evaluate(struct rib_entry *, struct prefix *, struct prefix *);
 
 /* rde_filter.c */
 void   rde_apply_set(struct filter_set_head *, struct rde_peer *,
Index: rde_decide.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_decide.c,v
retrieving revision 1.78
diff -u -p -r1.78 rde_decide.c
--- rde_decide.c9 Aug 2019 13:44:27 -   1.78
+++ rde_decide.c12 Jan 2021 16:24:36 -
@@ -238,14 +238,16 @@ prefix_cmp(struct prefix *p1, struct pre
  * The to evaluate prefix must not be in the prefix list.
  */
 void
-prefix_evaluate(struct prefix *p, struct rib_entry *re)
+prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old)
 {
struct prefix   *xp;
 
if (re_rib(re)->flags & F_RIB_NOEVALUATE) {
/* decision process is turned off */
-   if (p != NULL)
-   LIST_INSERT_HEAD(&re->prefix_h, p, entry.list.rib);
+   if (old != NULL)
+   LIST_REMOVE(old, entry.list.rib);
+   if (new != NULL)
+   LIST_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
if (re->active) {
/*
 * During reloads it is possible that the decision
@@ -259,19 +261,22 @@ prefix_evaluate(struct prefix *p, struct
return;
}
 
-   if (p != NULL) {
+   if (old != NULL)
+   LIST_REMOVE(old, entry.list.rib);
+   
+   if (new != NULL) {
if (LIST_EMPTY(&re->prefix_h))
-   LIST_INSERT_HEAD(&re->prefix_h, p, entry.list.rib);
+   LIST_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
else {
LIST_FOREACH(xp, &re->prefix_h, entry.list.rib) {
-   if (prefix_cmp(p, xp) > 0) {
-   LIST_INSERT_BEFORE(xp, p,
+   if (prefix_cmp(new, xp) > 0) {
+   LIST_INSERT_BEFORE(xp, new,
entry.list.rib);
break;
} else if (LIST_NEXT(xp, entry.list.rib) ==
NULL) {
/* if xp last element ... */
-   LIST_INSERT_AFTER(xp, p,
+   LIST_INSERT_AFTER(xp, new,
entry.list.rib);
break;
}
@@ -290,18 +295,17 @@ prefix_evaluate(struct prefix *p, struct
xp = NULL;
}
 
-   if (re->active != xp) {
-   /* need to generate an update */
-
+   /*
+* If the active prefix changed or the active prefix was remo

uvm_fault: access_type fixup for wired mapping

2021-01-12 Thread Martin Pieuchot
Diff below moves `access_type' to the context structure passed down to
the various routines and fix a regression introduced in a previous
refactoring.

`access_type' is overwritten for wired mapping and the value of
`enter_prot' is used instead.

ok?

Index: uvm/uvm_fault.c
===
RCS file: /cvs/src/sys/uvm/uvm_fault.c,v
retrieving revision 1.111
diff -u -p -r1.111 uvm_fault.c
--- uvm/uvm_fault.c 2 Jan 2021 02:39:59 -   1.111
+++ uvm/uvm_fault.c 12 Jan 2021 12:36:38 -
@@ -477,6 +477,7 @@ struct uvm_faultctx {
 * read-only after that.
 */
vm_prot_t enter_prot;
+   vm_prot_t access_type;
vaddr_t startva;
int npages;
int centeridx;
@@ -486,7 +487,7 @@ struct uvm_faultctx {
 };
 
 intuvm_fault_lower(struct uvm_faultinfo *, struct uvm_faultctx *,
-   struct vm_page **, vm_fault_t, vm_prot_t);
+   struct vm_page **, vm_fault_t);
 
 /*
  * uvm_fault_check: check prot, handle needs-copy, etc.
@@ -505,7 +506,7 @@ int uvm_fault_lower(struct uvm_faultinfo
  */
 int
 uvm_fault_check(struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
-struct vm_anon ***ranons, vm_prot_t access_type)
+struct vm_anon ***ranons)
 {
struct vm_amap *amap;
struct uvm_object *uobj;
@@ -523,7 +524,7 @@ uvm_fault_check(struct uvm_faultinfo *uf
 #endif
 
/* check protection */
-   if ((ufi->entry->protection & access_type) != access_type) {
+   if ((ufi->entry->protection & flt->access_type) != flt->access_type) {
uvmfault_unlockmaps(ufi, FALSE);
return (EACCES);
}
@@ -539,11 +540,11 @@ uvm_fault_check(struct uvm_faultinfo *uf
flt->pa_flags = UVM_ET_ISWC(ufi->entry) ? PMAP_WC : 0;
flt->wired = VM_MAPENT_ISWIRED(ufi->entry) || (flt->narrow == TRUE);
if (flt->wired)
-   access_type = flt->enter_prot; /* full access for wired */
+   flt->access_type = flt->enter_prot; /* full access for wired */
 
/* handle "needs_copy" case. */
if (UVM_ET_ISNEEDSCOPY(ufi->entry)) {
-   if ((access_type & PROT_WRITE) ||
+   if ((flt->access_type & PROT_WRITE) ||
(ufi->entry->object.uvm_obj == NULL)) {
/* need to clear */
uvmfault_unlockmaps(ufi, FALSE);
@@ -648,7 +649,7 @@ uvm_fault_check(struct uvm_faultinfo *uf
  */
 int
 uvm_fault_upper(struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
-   struct vm_anon **anons, vm_fault_t fault_type, vm_prot_t access_type)
+   struct vm_anon **anons, vm_fault_t fault_type)
 {
struct vm_amap *amap = ufi->entry->aref.ar_amap;
struct vm_anon *oanon, *anon = anons[flt->centeridx];
@@ -699,7 +700,7 @@ uvm_fault_upper(struct uvm_faultinfo *uf
 * if we are out of anon VM we wait for RAM to become available.
 */
 
-   if ((access_type & PROT_WRITE) != 0 && anon->an_ref > 1) {
+   if ((flt->access_type & PROT_WRITE) != 0 && anon->an_ref > 1) {
counters_inc(uvmexp_counters, flt_acow);
oanon = anon;   /* oanon = old */
anon = uvm_analloc();
@@ -761,7 +762,7 @@ uvm_fault_upper(struct uvm_faultinfo *uf
 */
if (pmap_enter(ufi->orig_map->pmap, ufi->orig_rvaddr,
VM_PAGE_TO_PHYS(pg) | flt->pa_flags, flt->enter_prot,
-   access_type | PMAP_CANFAIL | (flt->wired ? PMAP_WIRED : 0)) != 0) {
+   flt->access_type | PMAP_CANFAIL | (flt->wired ? PMAP_WIRED : 0)) != 
0) {
/*
 * No need to undo what we did; we can simply think of
 * this as the pmap throwing away the mapping information.
@@ -922,6 +923,7 @@ uvm_fault(vm_map_t orig_map, vaddr_t vad
 * pages on wire */
else
flt.narrow = FALSE; /* normal fault */
+   flt.access_type = access_type;
 
 
/*
@@ -930,7 +932,7 @@ uvm_fault(vm_map_t orig_map, vaddr_t vad
while (error == ERESTART) {
anons = anons_store;
 
-   error = uvm_fault_check(&ufi, &flt, &anons, access_type);
+   error = uvm_fault_check(&ufi, &flt, &anons);
if (error != 0)
continue;
 
@@ -938,13 +940,11 @@ uvm_fault(vm_map_t orig_map, vaddr_t vad
shadowed = uvm_fault_upper_lookup(&ufi, &flt, anons, pages);
if (shadowed == TRUE) {
/* case 1: fault on an anon in our amap */
-   error = uvm_fault_upper(&ufi, &flt, anons, fault_type,
-   access_type);
+   error = uvm_fault_upper(&ufi, &flt, anons, fault_type);
} else {
/* case 2: fault on backing object or zero fill */
KERNEL_LOCK();
-   error = uvm_fault_low

Re: Make ospf6d work on point-to-point links

2021-01-12 Thread Sebastian Benoit
Claudio Jeker(cje...@diehard.n-r-g.com) on 2021.01.12 10:07:57 +0100:
> On Wed, Jan 06, 2021 at 01:02:50PM +0100, Claudio Jeker wrote:
> > The code in ospf6d is a bit broken when it comes to point-to-point links.
> > This diff fixes this by a) using the neighbor address instead of the unset
> > interface destination address and by b) matching the incomming packet
> > against all possible IPs of that interface.
> > 
> > I tripped on b) because my P2P interface has more than one link-local
> > address and the code just likes to select the wrong one.
> > 
> > This works for my case, please check I did not break something else.
> 
> So this seems to work. Anyone wants to OK else I will commit this later
> today.

Code reads ok.
Did not get around to testing it.

> 
> > -- 
> > :wq Claudio
> > 
> > Index: lsupdate.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v
> > retrieving revision 1.18
> > diff -u -p -r1.18 lsupdate.c
> > --- lsupdate.c  15 Jul 2020 14:47:41 -  1.18
> > +++ lsupdate.c  6 Jan 2021 11:28:43 -
> > @@ -474,7 +474,7 @@ ls_retrans_timer(int fd, short event, vo
> > /* ls_retrans_list_free retriggers the timer */
> > return;
> > } else if (nbr->iface->type == IF_TYPE_POINTOPOINT)
> > -   memcpy(&addr, &nbr->iface->dst, sizeof(addr));
> > +   memcpy(&addr, &nbr->addr, sizeof(addr));
> > else
> > inet_pton(AF_INET6, AllDRouters, &addr);
> > } else
> > Index: packet.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v
> > retrieving revision 1.17
> > diff -u -p -r1.17 packet.c
> > --- packet.c23 Dec 2019 07:33:49 -  1.17
> > +++ packet.c6 Jan 2021 11:52:08 -
> > @@ -82,12 +82,9 @@ send_packet(struct iface *iface, struct 
> >  struct in6_addr *dst)
> >  {
> > struct sockaddr_in6 sa6;
> > -   struct msghdr   msg;
> > -   struct ioveciov[1];
> >  
> > -   /* setup buffer */
> > +   /* setup sockaddr */
> > bzero(&sa6, sizeof(sa6));
> > -
> > sa6.sin6_family = AF_INET6;
> > sa6.sin6_len = sizeof(sa6);
> > sa6.sin6_addr = *dst;
> > @@ -104,15 +101,8 @@ send_packet(struct iface *iface, struct 
> > return (-1);
> > }
> >  
> > -   bzero(&msg, sizeof(msg));
> > -   msg.msg_name = &sa6;
> > -   msg.msg_namelen = sizeof(sa6);
> > -   iov[0].iov_base = buf->buf;
> > -   iov[0].iov_len = ibuf_size(buf);
> > -   msg.msg_iov = iov;
> > -   msg.msg_iovlen = 1;
> > -
> > -   if (sendmsg(iface->fd, &msg, 0) == -1) {
> > +   if (sendto(iface->fd, buf->buf, ibuf_size(buf), 0,
> > +   (struct sockaddr *)&sa6, sizeof(sa6)) == -1) {
> > log_warn("send_packet: error sending packet on interface %s",
> > iface->name);
> > return (-1);
> > @@ -186,11 +176,16 @@ recv_packet(int fd, short event, void *b
> >  * AllDRouters is only valid for DR and BDR but this is checked later.
> >  */
> > inet_pton(AF_INET6, AllSPFRouters, &addr);
> > -
> > if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) {
> > inet_pton(AF_INET6, AllDRouters, &addr);
> > if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) {
> > -   if (!IN6_ARE_ADDR_EQUAL(&dest, &iface->addr)) {
> > +   struct iface_addr *ia;
> > +
> > +   TAILQ_FOREACH(ia, &iface->ifa_list, entry) {
> > +   if (IN6_ARE_ADDR_EQUAL(&dest, &ia->addr))
> > +   break;
> > +   }
> > +   if (ia == NULL) {
> > log_debug("recv_packet: packet sent to wrong "
> > "address %s, interface %s",
> > log_in6addr(&dest), iface->name);
> > 
> 



Re: Make ospf6d work on point-to-point links

2021-01-12 Thread Claudio Jeker
On Wed, Jan 06, 2021 at 01:02:50PM +0100, Claudio Jeker wrote:
> The code in ospf6d is a bit broken when it comes to point-to-point links.
> This diff fixes this by a) using the neighbor address instead of the unset
> interface destination address and by b) matching the incomming packet
> against all possible IPs of that interface.
> 
> I tripped on b) because my P2P interface has more than one link-local
> address and the code just likes to select the wrong one.
> 
> This works for my case, please check I did not break something else.

So this seems to work. Anyone wants to OK else I will commit this later
today.

> -- 
> :wq Claudio
> 
> Index: lsupdate.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/lsupdate.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 lsupdate.c
> --- lsupdate.c15 Jul 2020 14:47:41 -  1.18
> +++ lsupdate.c6 Jan 2021 11:28:43 -
> @@ -474,7 +474,7 @@ ls_retrans_timer(int fd, short event, vo
>   /* ls_retrans_list_free retriggers the timer */
>   return;
>   } else if (nbr->iface->type == IF_TYPE_POINTOPOINT)
> - memcpy(&addr, &nbr->iface->dst, sizeof(addr));
> + memcpy(&addr, &nbr->addr, sizeof(addr));
>   else
>   inet_pton(AF_INET6, AllDRouters, &addr);
>   } else
> Index: packet.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 packet.c
> --- packet.c  23 Dec 2019 07:33:49 -  1.17
> +++ packet.c  6 Jan 2021 11:52:08 -
> @@ -82,12 +82,9 @@ send_packet(struct iface *iface, struct 
>  struct in6_addr *dst)
>  {
>   struct sockaddr_in6 sa6;
> - struct msghdr   msg;
> - struct ioveciov[1];
>  
> - /* setup buffer */
> + /* setup sockaddr */
>   bzero(&sa6, sizeof(sa6));
> -
>   sa6.sin6_family = AF_INET6;
>   sa6.sin6_len = sizeof(sa6);
>   sa6.sin6_addr = *dst;
> @@ -104,15 +101,8 @@ send_packet(struct iface *iface, struct 
>   return (-1);
>   }
>  
> - bzero(&msg, sizeof(msg));
> - msg.msg_name = &sa6;
> - msg.msg_namelen = sizeof(sa6);
> - iov[0].iov_base = buf->buf;
> - iov[0].iov_len = ibuf_size(buf);
> - msg.msg_iov = iov;
> - msg.msg_iovlen = 1;
> -
> - if (sendmsg(iface->fd, &msg, 0) == -1) {
> + if (sendto(iface->fd, buf->buf, ibuf_size(buf), 0,
> + (struct sockaddr *)&sa6, sizeof(sa6)) == -1) {
>   log_warn("send_packet: error sending packet on interface %s",
>   iface->name);
>   return (-1);
> @@ -186,11 +176,16 @@ recv_packet(int fd, short event, void *b
>* AllDRouters is only valid for DR and BDR but this is checked later.
>*/
>   inet_pton(AF_INET6, AllSPFRouters, &addr);
> -
>   if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) {
>   inet_pton(AF_INET6, AllDRouters, &addr);
>   if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) {
> - if (!IN6_ARE_ADDR_EQUAL(&dest, &iface->addr)) {
> + struct iface_addr *ia;
> +
> + TAILQ_FOREACH(ia, &iface->ifa_list, entry) {
> + if (IN6_ARE_ADDR_EQUAL(&dest, &ia->addr))
> + break;
> + }
> + if (ia == NULL) {
>   log_debug("recv_packet: packet sent to wrong "
>   "address %s, interface %s",
>   log_in6addr(&dest), iface->name);
> 



Re: Change bgpd_addr encoding of VPN v4 and v6 addresses

2021-01-12 Thread Claudio Jeker
On Tue, Jan 05, 2021 at 11:17:22AM +0100, Claudio Jeker wrote:
> While changing log_addr() I noticed that struct bgpd_addr could benefit
> from changing the encoding of AID_VPN_IPv4 and AID_VPN_IPv6 addrs.
> Instead of having independent route distinguishers and labelstacks use
> common fields for those and use the v4 and v6 addresses for the prefix.
> This is a bit more compact but also simplifies some code since the
> handling of AID_VPN_IPv4 and AID_VPN_IPv6 can be handled in the same
> switch case.
> 
> I reduced the labelstack size from 21 to 18 (6 instead of 7 labels). Now
> in theory you could pack 7 labels into an IPv4 VPN NLRI (8bit prefixlen +
> 64bit RD + 16bit prefix + 21 * 8bit label = 256) but that is quite silly.
> Even 6 labels is more than enough. bgpd itself only allows a single MPLS
> label when announcing such networks.

Ping
 
-- 
:wq Claudio

PS: diff is based of /usr/src/usr.sbin

Index: bgpctl/mrtparser.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/mrtparser.c,v
retrieving revision 1.13
diff -u -p -r1.13 mrtparser.c
--- bgpctl/mrtparser.c  3 Jul 2019 06:22:01 -   1.13
+++ bgpctl/mrtparser.c  5 Jan 2021 09:19:09 -
@@ -833,14 +833,14 @@ mrt_extract_attr(struct mrt_rib_entry *r
re->nexthop.aid = aid;
memcpy(&tmp, a + 1 + sizeof(u_int64_t),
sizeof(tmp));
-   re->nexthop.vpn4.addr.s_addr = tmp;
+   re->nexthop.v4.s_addr = tmp;
break;
case AID_VPN_IPv6:
if (attr_len < sizeof(u_int64_t) +
sizeof(struct in6_addr))
return (-1);
re->nexthop.aid = aid;
-   memcpy(&re->nexthop.vpn6.addr,
+   memcpy(&re->nexthop.v6,
a + 1 + sizeof(u_int64_t),
sizeof(struct in6_addr));
break;
@@ -979,7 +979,7 @@ mrt_extract_addr(void *msg, u_int len, s
return (-1);
addr->aid = aid;
/* XXX labelstack and rd missing */
-   memcpy(&addr->vpn4.addr, b + sizeof(u_int64_t),
+   memcpy(&addr->v4, b + sizeof(u_int64_t),
sizeof(struct in_addr));
return (sizeof(u_int64_t) + sizeof(struct in_addr));
case AID_VPN_IPv6:
@@ -987,7 +987,7 @@ mrt_extract_addr(void *msg, u_int len, s
return (-1);
addr->aid = aid;
/* XXX labelstack and rd missing */
-   memcpy(&addr->vpn6.addr, b + sizeof(u_int64_t),
+   memcpy(&addr->v6, b + sizeof(u_int64_t),
sizeof(struct in6_addr));
return (sizeof(u_int64_t) + sizeof(struct in6_addr));
default:
Index: bgpd/bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.409
diff -u -p -r1.409 bgpd.h
--- bgpd/bgpd.h 4 Jan 2021 13:40:32 -   1.409
+++ bgpd/bgpd.h 5 Jan 2021 08:23:39 -
@@ -176,23 +176,6 @@ extern const struct aid aid_vals[];
sizeof(struct pt_entry_vpn6)\
 }
 
-struct vpn4_addr {
-   u_int64_t   rd;
-   struct in_addr  addr;
-   u_int8_tlabelstack[21]; /* max that makes sense */
-   u_int8_tlabellen;
-   u_int8_tpad1;
-   u_int8_tpad2;
-};
-
-struct vpn6_addr {
-   u_int64_t   rd;
-   struct in6_addr addr;
-   u_int8_tlabelstack[21]; /* max that makes sense */
-   u_int8_tlabellen;
-   u_int8_tpad1;
-   u_int8_tpad2;
-};
 
 #define BGP_MPLS_BOS   0x01
 
@@ -200,22 +183,15 @@ struct bgpd_addr {
union {
struct in_addr  v4;
struct in6_addr v6;
-   struct vpn4_addrvpn4;
-   struct vpn6_addrvpn6;
/* maximum size for a prefix is 256 bits */
-   u_int8_taddr8[32];
-   u_int16_t   addr16[16];
-   u_int32_t   addr32[8];
} ba;   /* 128-bit address */
+   u_int64_t   rd; /* route distinguisher for VPN addrs */
u_int32_t   scope_id;   /* iface scope id for v6 */
u_int8_taid;
+   u_int8_tlabellen;   /* size of the labelstack */
+   u_int8_tlabelstack[18]; /* max that makes sense */
 #definev4  ba.v4
 #definev6  ba.v6
-#definevpn4ba.vpn4
-#definevpn6ba.vpn6
-#defineaddr8   ba.addr8
-#defineaddr16  ba.addr1