Is there any interest in allowing "local-address $ip $ip6" and
having the parser choose whichever of these addresses has the
relevant af for a peer?

Mostly it allows prettier/shorter configs and slightly less complex
templates if you generate them programmatically. For example if you
have ibgp connections from loopbacks you might have either set
local-address in each "neighbor" block or used something like:

group "internal" {
        remote-as $foo
        local-address $LOOPBACK
        neighbor 10.0.0.1 {
                descr "r1-v4"
        }
        neighbor 10.0.0.2 {
                descr "r2-v4"
        }
}
group "internal-v6" {
        remote-as $foo
        local-address $LOOPBACK6
        neighbor aaaa::1 {
                descr "r1-v6"
        }
        neighbor aaaa::2 {
                descr "r2-v6"
        }
}

With the diff below that can be collapsed to:

group "internal" {
        remote-as $foo
        local-address $LOOPBACK $LOOPBACK6
        neighbor 10.0.0.1 {
                descr "r1-v4"
        }
        neighbor aaaa::1 {
                descr "r1-v6"
        }
        neighbor 10.0.0.2 {
                descr "r2-v4"
        }
        neighbor aaaa::2 {
                descr "r2-v6"
        }
}

Earlier versions before I added memsets didn't work correctly with some
combinations of overrides, I think I've covered all the possibilities
now but might have missed something..


Index: bgpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v
retrieving revision 1.169
diff -u -p -r1.169 bgpd.conf.5
--- bgpd.conf.5 18 Jun 2018 06:04:25 -0000      1.169
+++ bgpd.conf.5 29 Jun 2018 14:59:16 -0000
@@ -923,7 +923,7 @@ and
 .Xr bgpd 8
 daemons on both sides, the session should be established.
 .Pp
-.It Ic local-address Ar address
+.It Ic local-address Ar address Op address
 When
 .Xr bgpd 8
 initiates the TCP connection to the neighbor system, it normally does not
@@ -933,6 +933,8 @@ If a
 is given,
 .Xr bgpd 8
 binds to this address first.
+If two addresses are given, one is used for IPv4 neighbors,
+the other for IPv6 neighbors.
 .Pp
 .It Ic local-as Ar as-number Op Ar as-number
 Set the AS number sent to the remote system.
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.320
diff -u -p -r1.320 bgpd.h
--- bgpd.h      29 Jun 2018 11:45:50 -0000      1.320
+++ bgpd.h      29 Jun 2018 14:59:16 -0000
@@ -303,6 +303,8 @@ struct capabilities {
 struct peer_config {
        struct bgpd_addr         remote_addr;
        struct bgpd_addr         local_addr;
+       struct bgpd_addr         local_addr_v4;
+       struct bgpd_addr         local_addr_v6;
        struct peer_auth         auth;
        struct capabilities      capabilities;
        char                     group[PEER_DESCR_LEN];
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.323
diff -u -p -r1.323 parse.y
--- parse.y     13 Jun 2018 09:44:59 -0000      1.323
+++ parse.y     29 Jun 2018 14:59:16 -0000
@@ -1045,7 +1045,18 @@ neighbor : {     curpeer = new_peer(); }
                                    curpeer_filter[1], entry);
                        curpeer_filter[0] = NULL;
                        curpeer_filter[1] = NULL;
-
+                       if (!curpeer->conf.local_addr.aid) {
+                               if (curpeer->conf.local_addr_v4.aid ==
+                                   curpeer->conf.remote_addr.aid) {
+                                       memcpy(&curpeer->conf.local_addr,
+                                           &curpeer->conf.local_addr_v4,
+                                           sizeof(curpeer->conf.local_addr));
+                               } else {
+                                       memcpy(&curpeer->conf.local_addr,
+                                           &curpeer->conf.local_addr_v6,
+                                           sizeof(curpeer->conf.local_addr));
+                               }
+                       }
                        if (neighbor_consistent(curpeer) == -1)
                                YYERROR;
                        curpeer->next = peer_l;
@@ -1133,6 +1144,30 @@ peeropts : REMOTEAS as4number    {
                | LOCALADDR address     {
                        memcpy(&curpeer->conf.local_addr, &$2,
                            sizeof(curpeer->conf.local_addr));
+                       memset(&curpeer->conf.local_addr_v4, 0,
+                           sizeof(curpeer->conf.local_addr_v4));
+                       memset(&curpeer->conf.local_addr_v6, 0,
+                           sizeof(curpeer->conf.local_addr_v6));
+               }
+               | LOCALADDR address address     {
+                       if($2.aid == $3.aid) {
+                               yyerror("\"local-address addr addr\" requires "
+                                   "different address families");
+                               YYERROR;
+                       }
+                       memset(&curpeer->conf.local_addr, 0,
+                           sizeof(curpeer->conf.local_addr));
+                       if($2.aid == AF_INET && $3.aid == AF_INET6) {
+                               memcpy(&curpeer->conf.local_addr_v4, &$2,
+                                   sizeof(curpeer->conf.local_addr_v4));
+                               memcpy(&curpeer->conf.local_addr_v6, &$3,
+                                   sizeof(curpeer->conf.local_addr_v6));
+                       } else {
+                               memcpy(&curpeer->conf.local_addr_v4, &$3,
+                                   sizeof(curpeer->conf.local_addr_v4));
+                               memcpy(&curpeer->conf.local_addr_v6, &$2,
+                                   sizeof(curpeer->conf.local_addr_v6));
+                       }
                }
                | MULTIHOP NUMBER       {
                        if ($2 < 2 || $2 > 255) {

Reply via email to