Re: bgpd, remove getifaddrs call in RDE

2020-01-20 Thread Claudio Jeker
On Thu, Jan 09, 2020 at 02:45:46PM +0100, Claudio Jeker wrote:
> The RDE needs to know the local v4 and v6 address of a session so that
> nexthop self works. Until now the lookup for the other AF address was done
> in the RDE when the session got established. This diff moves this code
> over to the SE where it fits better. Especially this allows to remove the
> route pledge from the RDE.
> 
> This diff works for me but I would like more tests especially on link
> local IPv6 sessions (the KAME embedded scope curse haunts me again).

ping...

-- 
:wq Claudio

? obj
Index: bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.397
diff -u -p -r1.397 bgpd.h
--- bgpd.h  9 Jan 2020 11:55:25 -   1.397
+++ bgpd.h  9 Jan 2020 13:37:19 -
@@ -656,7 +656,8 @@ struct kif {
 };
 
 struct session_up {
-   struct bgpd_addrlocal_addr;
+   struct bgpd_addrlocal_v4_addr;
+   struct bgpd_addrlocal_v6_addr;
struct bgpd_addrremote_addr;
struct capabilities capa;
u_int32_t   remote_bgpid;
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.498
diff -u -p -r1.498 rde.c
--- rde.c   9 Jan 2020 13:31:52 -   1.498
+++ rde.c   9 Jan 2020 13:37:19 -
@@ -177,7 +177,7 @@ rde_main(int debug, int verbose)
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");
 
-   if (pledge("stdio route recvfd", NULL) == -1)
+   if (pledge("stdio recvfd", NULL) == -1)
fatal("pledge");
 
signal(SIGTERM, rde_sighdlr);
Index: rde_peer.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_peer.c,v
retrieving revision 1.2
diff -u -p -r1.2 rde_peer.c
--- rde_peer.c  9 Jan 2020 13:31:52 -   1.2
+++ rde_peer.c  9 Jan 2020 13:37:19 -
@@ -17,9 +17,7 @@
  */
 #include 
 #include 
-#include 
 
-#include 
 #include 
 #include 
 #include 
@@ -306,102 +304,6 @@ rde_up_dump_done(void *ptr, u_int8_t aid
fatal("%s: prefix_dump_new", __func__);
 }
 
-static int
-sa_cmp(struct bgpd_addr *a, struct sockaddr *b)
-{
-   struct sockaddr_in  *in_b;
-   struct sockaddr_in6 *in6_b;
-
-   if (aid2af(a->aid) != b->sa_family)
-   return (1);
-
-   switch (b->sa_family) {
-   case AF_INET:
-   in_b = (struct sockaddr_in *)b;
-   if (a->v4.s_addr != in_b->sin_addr.s_addr)
-   return (1);
-   break;
-   case AF_INET6:
-   in6_b = (struct sockaddr_in6 *)b;
-#ifdef __KAME__
-   /* directly stolen from sbin/ifconfig/ifconfig.c */
-   if (IN6_IS_ADDR_LINKLOCAL(_b->sin6_addr)) {
-   in6_b->sin6_scope_id =
-   ntohs(*(u_int16_t *)_b->sin6_addr.s6_addr[2]);
-   in6_b->sin6_addr.s6_addr[2] =
-   in6_b->sin6_addr.s6_addr[3] = 0;
-   }
-#endif
-   if (bcmp(>v6, _b->sin6_addr,
-   sizeof(struct in6_addr)))
-   return (1);
-   break;
-   default:
-   fatal("king bula sez: unknown address family");
-   /* NOTREACHED */
-   }
-
-   return (0);
-}
-
-/*
- * Figure out the local IP addresses most suitable for this session.
- * This looks up the local address of other address family based on
- * the address of the TCP session.
- */
-static int
-peer_localaddrs(struct rde_peer *peer, struct bgpd_addr *laddr)
-{
-   struct ifaddrs  *ifap, *ifa, *match;
-
-   if (getifaddrs() == -1)
-   fatal("getifaddrs");
-
-   for (match = ifap; match != NULL; match = match->ifa_next)
-   if (sa_cmp(laddr, match->ifa_addr) == 0)
-   break;
-
-   if (match == NULL) {
-   log_warnx("peer_localaddrs: local address not found");
-   return (-1);
-   }
-
-   for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-   if (ifa->ifa_addr->sa_family == AF_INET &&
-   strcmp(ifa->ifa_name, match->ifa_name) == 0) {
-   if (ifa->ifa_addr->sa_family ==
-   match->ifa_addr->sa_family)
-   ifa = match;
-   sa2addr(ifa->ifa_addr, >local_v4_addr, NULL);
-   break;
-   }
-   }
-   for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-   if (ifa->ifa_addr->sa_family == AF_INET6 &&
-   strcmp(ifa->ifa_name, match->ifa_name) == 0) {
-   /*
-* only accept global scope addresses except explicitly
-* specified.
-

bgpd, remove getifaddrs call in RDE

2020-01-09 Thread Claudio Jeker
The RDE needs to know the local v4 and v6 address of a session so that
nexthop self works. Until now the lookup for the other AF address was done
in the RDE when the session got established. This diff moves this code
over to the SE where it fits better. Especially this allows to remove the
route pledge from the RDE.

This diff works for me but I would like more tests especially on link
local IPv6 sessions (the KAME embedded scope curse haunts me again).
-- 
:wq Claudio

? obj
Index: bgpd.h
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.397
diff -u -p -r1.397 bgpd.h
--- bgpd.h  9 Jan 2020 11:55:25 -   1.397
+++ bgpd.h  9 Jan 2020 13:37:19 -
@@ -656,7 +656,8 @@ struct kif {
 };
 
 struct session_up {
-   struct bgpd_addrlocal_addr;
+   struct bgpd_addrlocal_v4_addr;
+   struct bgpd_addrlocal_v6_addr;
struct bgpd_addrremote_addr;
struct capabilities capa;
u_int32_t   remote_bgpid;
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.498
diff -u -p -r1.498 rde.c
--- rde.c   9 Jan 2020 13:31:52 -   1.498
+++ rde.c   9 Jan 2020 13:37:19 -
@@ -177,7 +177,7 @@ rde_main(int debug, int verbose)
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");
 
-   if (pledge("stdio route recvfd", NULL) == -1)
+   if (pledge("stdio recvfd", NULL) == -1)
fatal("pledge");
 
signal(SIGTERM, rde_sighdlr);
Index: rde_peer.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_peer.c,v
retrieving revision 1.2
diff -u -p -r1.2 rde_peer.c
--- rde_peer.c  9 Jan 2020 13:31:52 -   1.2
+++ rde_peer.c  9 Jan 2020 13:37:19 -
@@ -17,9 +17,7 @@
  */
 #include 
 #include 
-#include 
 
-#include 
 #include 
 #include 
 #include 
@@ -306,102 +304,6 @@ rde_up_dump_done(void *ptr, u_int8_t aid
fatal("%s: prefix_dump_new", __func__);
 }
 
-static int
-sa_cmp(struct bgpd_addr *a, struct sockaddr *b)
-{
-   struct sockaddr_in  *in_b;
-   struct sockaddr_in6 *in6_b;
-
-   if (aid2af(a->aid) != b->sa_family)
-   return (1);
-
-   switch (b->sa_family) {
-   case AF_INET:
-   in_b = (struct sockaddr_in *)b;
-   if (a->v4.s_addr != in_b->sin_addr.s_addr)
-   return (1);
-   break;
-   case AF_INET6:
-   in6_b = (struct sockaddr_in6 *)b;
-#ifdef __KAME__
-   /* directly stolen from sbin/ifconfig/ifconfig.c */
-   if (IN6_IS_ADDR_LINKLOCAL(_b->sin6_addr)) {
-   in6_b->sin6_scope_id =
-   ntohs(*(u_int16_t *)_b->sin6_addr.s6_addr[2]);
-   in6_b->sin6_addr.s6_addr[2] =
-   in6_b->sin6_addr.s6_addr[3] = 0;
-   }
-#endif
-   if (bcmp(>v6, _b->sin6_addr,
-   sizeof(struct in6_addr)))
-   return (1);
-   break;
-   default:
-   fatal("king bula sez: unknown address family");
-   /* NOTREACHED */
-   }
-
-   return (0);
-}
-
-/*
- * Figure out the local IP addresses most suitable for this session.
- * This looks up the local address of other address family based on
- * the address of the TCP session.
- */
-static int
-peer_localaddrs(struct rde_peer *peer, struct bgpd_addr *laddr)
-{
-   struct ifaddrs  *ifap, *ifa, *match;
-
-   if (getifaddrs() == -1)
-   fatal("getifaddrs");
-
-   for (match = ifap; match != NULL; match = match->ifa_next)
-   if (sa_cmp(laddr, match->ifa_addr) == 0)
-   break;
-
-   if (match == NULL) {
-   log_warnx("peer_localaddrs: local address not found");
-   return (-1);
-   }
-
-   for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-   if (ifa->ifa_addr->sa_family == AF_INET &&
-   strcmp(ifa->ifa_name, match->ifa_name) == 0) {
-   if (ifa->ifa_addr->sa_family ==
-   match->ifa_addr->sa_family)
-   ifa = match;
-   sa2addr(ifa->ifa_addr, >local_v4_addr, NULL);
-   break;
-   }
-   }
-   for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-   if (ifa->ifa_addr->sa_family == AF_INET6 &&
-   strcmp(ifa->ifa_name, match->ifa_name) == 0) {
-   /*
-* only accept global scope addresses except explicitly
-* specified.
-*/
-   if (ifa->ifa_addr->sa_family ==
-