Sometimes (mainly for tests) it can be useful to run bgpd on something
different than port 179. The following diff does mostly that. It allows
to define a port with 'listen on' and makes it possible to set the port
on a neighbor like it is done for rtr sessions.

The only thing not working are IPsec flows. Those assume that the default
port is used and changing that is way to complex for the limited usecase.

-- 
:wq Claudio

Index: bgpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v
retrieving revision 1.216
diff -u -p -r1.216 bgpd.conf.5
--- bgpd.conf.5 22 Feb 2022 12:08:22 -0000      1.216
+++ bgpd.conf.5 22 Feb 2022 16:30:59 -0000
@@ -237,8 +237,8 @@ The default is 90 seconds.
 The minimum acceptable holdtime in seconds.
 This value must be at least 3.
 .Pp
-.It Ic listen on Ar address
-Specify the local IP address for
+.It Ic listen on Ar address Op Ic port Ar port
+Specify the local IP address and optional port for
 .Xr bgpd 8
 to listen on.
 The default is to listen on all local addresses on the current default
@@ -1078,6 +1078,9 @@ aes-128-cbc <key>
 .Pp
 Keys must be given in hexadecimal format.
 After changing settings a session needs to be reset to use the new keys.
+The
+.Ic ipsec
+flows only work with session using the default port 179.
 .Pp
 .It Xo
 .Ic ipsec
@@ -1113,6 +1116,9 @@ and
 .Xr bgpd 8
 daemons on both sides, the session should be established.
 After changing settings a session needs to be reset to use the new keys.
+The
+.Ic ipsec
+flows only work with session using the default port 179.
 .Pp
 .It Ic local-address Ar address
 .It Ic no local-address
@@ -1183,6 +1189,11 @@ statement defines the maximum hops the n
 .Pp
 .It Ic passive
 Do not attempt to actively open a TCP connection to the neighbor system.
+.Pp
+.It Ic port Ar port
+Connect to the peer using
+.Ar port
+instead of the default BGP port 179.
 .Pp
 .It Xo
 .Ic reject Ic as-set
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.419
diff -u -p -r1.419 bgpd.h
--- bgpd.h      6 Feb 2022 09:51:19 -0000       1.419
+++ bgpd.h      22 Feb 2022 15:11:13 -0000
@@ -36,6 +36,7 @@
 
 #define        BGP_VERSION                     4
 #define        BGP_PORT                        179
+#define        RTR_PORT                        323
 #define        CONFFILE                        "/etc/bgpd.conf"
 #define        BGPD_USER                       "_bgpd"
 #define        PEER_DESCR_LEN                  32
@@ -402,6 +403,7 @@ struct peer_config {
        uint16_t                 holdtime;
        uint16_t                 min_holdtime;
        uint16_t                 local_short_as;
+       uint16_t                 remote_port;
        uint8_t                  template;
        uint8_t                  remote_masklen;
        uint8_t                  ebgp;          /* 0 = ibgp else ebgp */
Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
retrieving revision 1.100
diff -u -p -r1.100 config.c
--- config.c    6 Feb 2022 09:51:19 -0000       1.100
+++ config.c    22 Feb 2022 11:00:43 -0000
@@ -447,30 +447,6 @@ prepare_listeners(struct bgpd_config *co
        int                      opt = 1;
        int                      r = 0;
 
-       if (TAILQ_EMPTY(conf->listen_addrs)) {
-               if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
-                       fatal("setup_listeners calloc");
-               la->fd = -1;
-               la->flags = DEFAULT_LISTENER;
-               la->reconf = RECONF_REINIT;
-               la->sa_len = sizeof(struct sockaddr_in);
-               ((struct sockaddr_in *)&la->sa)->sin_family = AF_INET;
-               ((struct sockaddr_in *)&la->sa)->sin_addr.s_addr =
-                   htonl(INADDR_ANY);
-               ((struct sockaddr_in *)&la->sa)->sin_port = htons(BGP_PORT);
-               TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
-
-               if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
-                       fatal("setup_listeners calloc");
-               la->fd = -1;
-               la->flags = DEFAULT_LISTENER;
-               la->reconf = RECONF_REINIT;
-               la->sa_len = sizeof(struct sockaddr_in6);
-               ((struct sockaddr_in6 *)&la->sa)->sin6_family = AF_INET6;
-               ((struct sockaddr_in6 *)&la->sa)->sin6_port = htons(BGP_PORT);
-               TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
-       }
-
        for (la = TAILQ_FIRST(conf->listen_addrs); la != NULL; la = next) {
                next = TAILQ_NEXT(la, entry);
                if (la->reconf != RECONF_REINIT)
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.420
diff -u -p -r1.420 parse.y
--- parse.y     15 Oct 2021 15:01:27 -0000      1.420
+++ parse.y     22 Feb 2022 15:54:57 -0000
@@ -575,7 +575,7 @@ roa_set_l   : prefixset_item SOURCEAS as4n
 
 rtr            : RTR address   {
                        currtr = get_rtr(&$2);
-                       currtr->remote_port = 323;
+                       currtr->remote_port = RTR_PORT;
                        if (insert_rtr(currtr) == -1) {
                                free(currtr);
                                YYERROR;
@@ -584,7 +584,7 @@ rtr         : RTR address   {
                }
                | RTR address   {
                        currtr = get_rtr(&$2);
-                       currtr->remote_port = 323;
+                       currtr->remote_port = RTR_PORT;
                } '{' optnl rtropt_l optnl '}' {
                        if (insert_rtr(currtr) == -1) {
                                free(currtr);
@@ -618,7 +618,7 @@ rtropt              : DESCR STRING          {
                }
                | PORT NUMBER {
                        if ($2 < 1 || $2 > USHRT_MAX) {
-                               yyerror("local-port must be between %u and %u",
+                               yyerror("port must be between %u and %u",
                                    1, USHRT_MAX);
                                YYERROR;
                        }
@@ -674,6 +674,26 @@ conf_main  : AS as4number          {
                        memcpy(&la->sa, sa, la->sa_len);
                        TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
                }
+               | LISTEN ON address PORT NUMBER {
+                       struct listen_addr      *la;
+                       struct sockaddr         *sa;
+
+                       if ($5 < 1 || $5 > USHRT_MAX) {
+                               yyerror("port must be between %u and %u",
+                                   1, USHRT_MAX);
+                               YYERROR;
+                       }
+
+                       if ((la = calloc(1, sizeof(struct listen_addr))) ==
+                           NULL)
+                               fatal("parse conf_main listen on calloc");
+
+                       la->fd = -1;
+                       la->reconf = RECONF_REINIT;
+                       sa = addr2sa(&$3, $5, &la->sa_len);
+                       memcpy(&la->sa, sa, la->sa_len);
+                       TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
+               }
                | FIBPRIORITY NUMBER            {
                        if ($2 <= RTP_NONE || $2 > RTP_MAX) {
                                yyerror("invalid fib-priority");
@@ -1770,6 +1790,14 @@ peeropts : REMOTEAS as4number    {
                        else
                                curpeer->conf.flags &= ~PEERFLAG_NO_AS_SET;
                }
+               | PORT NUMBER {
+                       if ($2 < 1 || $2 > USHRT_MAX) {
+                               yyerror("port must be between %u and %u",
+                                   1, USHRT_MAX);
+                               YYERROR;
+                       }
+                       curpeer->conf.remote_port = $2;
+               }
                | RDE EVALUATE STRING {
                        if (!strcmp($3, "all"))
                                curpeer->conf.flags |= PEERFLAG_EVALUATE_ALL;
@@ -3497,28 +3525,55 @@ errors:
 
                free_config(conf);
                return (NULL);
-       } else {
-               /* update clusterid in case it was not set explicitly */
-               if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
-                       conf->clusterid = conf->bgpid;
-
-               /*
-                * Concatenate filter list and static group and peer filtersets
-                * together. Static group sets come first then peer sets
-                * last normal filter rules.
-                */
-               TAILQ_CONCAT(conf->filters, groupfilter_l, entry);
-               TAILQ_CONCAT(conf->filters, peerfilter_l, entry);
-               TAILQ_CONCAT(conf->filters, filter_l, entry);
-
-               optimize_filters(conf->filters);
+       }
 
-               free(filter_l);
-               free(peerfilter_l);
-               free(groupfilter_l);
+       /* Create default listeners if none where specified. */
+       if (TAILQ_EMPTY(conf->listen_addrs)) {
+               struct listen_addr *la;
+
+               if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
+                       fatal("setup_listeners calloc");
+               la->fd = -1;
+               la->flags = DEFAULT_LISTENER;
+               la->reconf = RECONF_REINIT;
+               la->sa_len = sizeof(struct sockaddr_in);
+               ((struct sockaddr_in *)&la->sa)->sin_family = AF_INET;
+               ((struct sockaddr_in *)&la->sa)->sin_addr.s_addr =
+                   htonl(INADDR_ANY);
+               ((struct sockaddr_in *)&la->sa)->sin_port = htons(BGP_PORT);
+               TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
+
+               if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
+                       fatal("setup_listeners calloc");
+               la->fd = -1;
+               la->flags = DEFAULT_LISTENER;
+               la->reconf = RECONF_REINIT;
+               la->sa_len = sizeof(struct sockaddr_in6);
+               ((struct sockaddr_in6 *)&la->sa)->sin6_family = AF_INET6;
+               ((struct sockaddr_in6 *)&la->sa)->sin6_port = htons(BGP_PORT);
+               TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
+       }
+
+       /* update clusterid in case it was not set explicitly */
+       if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
+               conf->clusterid = conf->bgpid;
+
+       /*
+        * Concatenate filter list and static group and peer filtersets
+        * together. Static group sets come first then peer sets
+        * last normal filter rules.
+        */
+       TAILQ_CONCAT(conf->filters, groupfilter_l, entry);
+       TAILQ_CONCAT(conf->filters, peerfilter_l, entry);
+       TAILQ_CONCAT(conf->filters, filter_l, entry);
+
+       optimize_filters(conf->filters);
+
+       free(filter_l);
+       free(peerfilter_l);
+       free(groupfilter_l);
 
-               return (conf);
-       }
+       return (conf);
 }
 
 int
@@ -3968,6 +4023,7 @@ alloc_peer(void)
        p->conf.capabilities.as4byte = 1;
        p->conf.local_as = conf->as;
        p->conf.local_short_as = conf->short_as;
+       p->conf.remote_port = BGP_PORT;
 
        if (conf->flags & BGPD_FLAG_DECISION_TRANS_AS)
                p->conf.flags |= PEERFLAG_TRANS_AS;
@@ -3988,12 +4044,6 @@ new_peer(void)
 
        if (curgroup != NULL) {
                memcpy(p, curgroup, sizeof(struct peer));
-               if (strlcpy(p->conf.group, curgroup->conf.group,
-                   sizeof(p->conf.group)) >= sizeof(p->conf.group))
-                       fatalx("new_peer group strlcpy");
-               if (strlcpy(p->conf.descr, curgroup->conf.descr,
-                   sizeof(p->conf.descr)) >= sizeof(p->conf.descr))
-                       fatalx("new_peer descr strlcpy");
                p->conf.groupid = curgroup->conf.id;
        }
        return (p);
Index: printconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.149
diff -u -p -r1.149 printconf.c
--- printconf.c 6 Feb 2022 09:51:19 -0000       1.149
+++ printconf.c 22 Feb 2022 15:52:54 -0000
@@ -401,9 +401,17 @@ print_mainconf(struct bgpd_config *conf)
        if (conf->log & BGPD_LOG_UPDATES)
                printf("log updates\n");
 
-       TAILQ_FOREACH(la, conf->listen_addrs, entry)
-               printf("listen on %s\n",
+       TAILQ_FOREACH(la, conf->listen_addrs, entry) {
+               struct bgpd_addr addr;
+               uint16_t port;
+
+               sa2addr((struct sockaddr *)&la->sa, &addr, &port);
+               printf("listen on %s",
                    log_sockaddr((struct sockaddr *)&la->sa, la->sa_len));
+               if (port != BGP_PORT)
+                       printf(" port %hu", port);
+               printf("\n");
+       }
 
        if (conf->flags & BGPD_FLAG_NEXTHOP_BGP)
                printf("nexthop qualify via bgp\n");
@@ -633,6 +641,8 @@ print_peer(struct peer_config *p, struct
        if (p->local_addr_v6.aid)
                printf("%s\tlocal-address %s\n", c,
                   log_addr(&p->local_addr_v6));
+       if (p->remote_port != BGP_PORT)
+               printf("%s\tport %hu\n", c, p->remote_port);
        if (p->max_prefix) {
                printf("%s\tmax-prefix %u", c, p->max_prefix);
                if (p->max_prefix_restart)
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.426
diff -u -p -r1.426 session.c
--- session.c   6 Feb 2022 09:51:19 -0000       1.426
+++ session.c   22 Feb 2022 11:00:43 -0000
@@ -1101,7 +1101,7 @@ session_connect(struct peer *peer)
                return (-1);
        }
 
-       sa = addr2sa(&peer->conf.remote_addr, BGP_PORT, &sa_len);
+       sa = addr2sa(&peer->conf.remote_addr, peer->conf.remote_port, &sa_len);
        if (connect(peer->fd, sa, sa_len) == -1) {
                if (errno != EINPROGRESS) {
                        if (errno != peer->lasterr)

Reply via email to