OK, this diff is actually what linux is going to need to be able to
configure TCP MD5SUM on sockets. The listening socket turned out to be a
bit more tricky since the MD5 key for each peer needs to be added to the
socket where the session will be expected (based on local-address) and so
these additions and deletions need to happen when peers are changed or
when new listeners are added. This is why this needs a few more functions.

I renamed the functions a bit but in the end this does not change any
behaviour for bgpd.
-- 
:wq Claudio

? obj
? test
? test.c
Index: pfkey.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/pfkey.c,v
retrieving revision 1.59
diff -u -p -r1.59 pfkey.c
--- pfkey.c     30 Sep 2019 12:10:38 -0000      1.59
+++ pfkey.c     1 Oct 2019 09:13:22 -0000
@@ -805,6 +805,7 @@ pfkey_init(void)
        return (pfkey_fd);
 }
 
+/* verify that connection is using TCP MD5UM if required by config */
 int
 tcp_md5_check(int fd, struct peer *p)
 {
@@ -830,6 +831,7 @@ tcp_md5_check(int fd, struct peer *p)
        return 0;
 }
 
+/* enable or set TCP MD5SIG on a new client connection */
 int
 tcp_md5_set(int fd, struct peer *p)
 {
@@ -850,8 +852,9 @@ tcp_md5_set(int fd, struct peer *p)
        return 0;
 }
 
+/* enable or prepare a new listening socket for TCP MD5SIG usage */
 int
-tcp_md5_listen(struct listen_addr *la, struct peer_head *p)
+tcp_md5_prep_listener(struct listen_addr *la, struct peer_head *p)
 {
        int opt = 1;
 
@@ -865,4 +868,16 @@ tcp_md5_listen(struct listen_addr *la, s
                return -1;
        }
        return 0;
+}
+
+/* add md5 key to all listening sockets, dummy function for portable */
+void
+tcp_md5_add_listener(struct bgpd_config *conf, struct peer *p)
+{
+}
+
+/* delete md5 key form all listening sockets, dummy function for portable */
+void
+tcp_md5_del_listener(struct bgpd_config *conf, struct peer *p)
+{
 }
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.393
diff -u -p -r1.393 session.c
--- session.c   1 Oct 2019 09:03:43 -0000       1.393
+++ session.c   1 Oct 2019 09:13:22 -0000
@@ -152,8 +152,8 @@ setup_listeners(u_int *la_cnt)
                        continue;
                }
 
-               if (tcp_md5_listen(la, &conf->peers) == -1)
-                       fatal("tcp_md5_listen");
+               if (tcp_md5_prep_listener(la, &conf->peers) == -1)
+                       fatal("tcp_md5_prep_listener");
 
                /* set ttl to 255 so that ttl-security works */
                if (la->sa.ss_family == AF_INET && setsockopt(la->fd,
@@ -276,6 +276,7 @@ session_main(int debug, int verbose)
                                        log_peer_warnx(&p->conf, "removed");
                                        RB_REMOVE(peer_head, &conf->peers, p);
                                        timer_remove_all(p);
+                                       tcp_md5_del_listener(conf, p);
                                        free(p);
                                        peer_cnt--;
                                        continue;
@@ -3179,6 +3180,13 @@ merge_peers(struct bgpd_config *c, struc
                        continue;
                }
 
+               /* peer no longer uses TCP MD5SIG so deconfigure */
+               if (p->conf.auth.method == AUTH_MD5SIG &&
+                   np->conf.auth.method != AUTH_MD5SIG)
+                       tcp_md5_del_listener(c, p);
+               else if (np->conf.auth.method == AUTH_MD5SIG)
+                       tcp_md5_add_listener(c, np);
+
                memcpy(&p->conf, &np->conf, sizeof(p->conf));
                RB_REMOVE(peer_head, &nc->peers, np);
                free(np);
@@ -3219,5 +3227,7 @@ merge_peers(struct bgpd_config *c, struc
                RB_REMOVE(peer_head, &nc->peers, np);
                if (RB_INSERT(peer_head, &c->peers, np) != NULL)
                        fatalx("%s: peer tree is corrupt", __func__);
+               if (np->conf.auth.method == AUTH_MD5SIG)
+                       tcp_md5_add_listener(c, np);
        }
 }
Index: session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
retrieving revision 1.140
diff -u -p -r1.140 session.h
--- session.h   30 Sep 2019 12:10:38 -0000      1.140
+++ session.h   1 Oct 2019 09:13:22 -0000
@@ -285,7 +285,9 @@ int pfkey_remove(struct peer *);
 int    pfkey_init(void);
 int    tcp_md5_check(int, struct peer *);
 int    tcp_md5_set(int, struct peer *);
-int    tcp_md5_listen(struct listen_addr *, struct peer_head *);
+int    tcp_md5_prep_listener(struct listen_addr *, struct peer_head *);
+void   tcp_md5_add_listener(struct bgpd_config *, struct peer *);
+void   tcp_md5_del_listener(struct bgpd_config *, struct peer *);
 
 /* printconf.c */
 void   print_config(struct bgpd_config *, struct rib_names *);

Reply via email to