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 *);