Re: ospf6d: refactor kernel route message handling

2019-12-11 Thread Remi Locherer
On Wed, Dec 11, 2019 at 04:38:38PM +0100, Denis Fondras wrote:
> On Tue, Dec 10, 2019 at 09:51:12PM +0100, Remi Locherer wrote:
> > Unfortunately redistribute does not work anymore.
> > 
> 
> Indeed, simple tests are too simple...
> 
> Here is an updated diff.

ok remi@

> 
> Index: kroute.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
> retrieving revision 1.60
> diff -u -p -r1.60 kroute.c
> --- kroute.c  2 Jan 2019 21:32:55 -   1.60
> +++ kroute.c  11 Dec 2019 14:51:25 -
> @@ -80,7 +80,7 @@ struct kroute_node  *kroute_match(struct 
>  
>  int  protect_lo(void);
>  void get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
> -void if_change(u_short, int, struct if_data *);
> +void if_change(u_short, int, struct if_data *, struct sockaddr_dl *);
>  void if_newaddr(u_short, struct sockaddr_in6 *,
>   struct sockaddr_in6 *, struct sockaddr_in6 *);
>  void if_deladdr(u_short, struct sockaddr_in6 *,
> @@ -90,6 +90,7 @@ voidif_announce(void *);
>  int  send_rtmsg(int, int, struct kroute *);
>  int  dispatch_rtmsg(void);
>  int  fetchtable(void);
> +int  rtmsg_process(char *, size_t); 
>  
>  RB_HEAD(kroute_tree, kroute_node)krt;
>  RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
> @@ -801,7 +802,8 @@ get_rtaddrs(int addrs, struct sockaddr *
>  }
>  
>  void
> -if_change(u_short ifindex, int flags, struct if_data *ifd)
> +if_change(u_short ifindex, int flags, struct if_data *ifd,
> +struct sockaddr_dl *sdl)
>  {
>   struct kroute_node  *kr, *tkr;
>   struct iface*iface;
> @@ -809,7 +811,7 @@ if_change(u_short ifindex, int flags, st
>  
>   wasvalid = kif_validate(ifindex);
>  
> - if ((iface = kif_update(ifindex, flags, ifd, NULL)) == NULL) {
> + if ((iface = kif_update(ifindex, flags, ifd, sdl)) == NULL) {
>   log_warn("if_change: kif_update(%u)", ifindex);
>   return;
>   }
> @@ -1135,12 +1137,8 @@ fetchtable(void)
>  {
>   size_t   len;
>   int  mib[7];
> - char*buf, *next, *lim;
> - struct rt_msghdr*rtm;
> - struct sockaddr *sa, *rti_info[RTAX_MAX];
> - struct sockaddr_in6 *sa_in6;
> - struct sockaddr_rtlabel *label;
> - struct kroute_node  *kr;
> + char*buf;
> + int  rv;
>  
>   mib[0] = CTL_NET;
>   mib[1] = PF_ROUTE;
> @@ -1164,102 +1162,10 @@ fetchtable(void)
>   return (-1);
>   }
>  
> - lim = buf + len;
> - for (next = buf; next < lim; next += rtm->rtm_msglen) {
> - rtm = (struct rt_msghdr *)next;
> - if (rtm->rtm_version != RTM_VERSION)
> - continue;
> - sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
> - get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
> -
> - if ((sa = rti_info[RTAX_DST]) == NULL)
> - continue;
> -
> - /* Skip ARP/ND cache and broadcast routes. */
> - if (rtm->rtm_flags & (RTF_LLINFO|RTF_BROADCAST))
> - continue;
> -
> - if ((kr = calloc(1, sizeof(struct kroute_node))) == NULL) {
> - log_warn("fetchtable");
> - free(buf);
> - return (-1);
> - }
> -
> - kr->r.flags = F_KERNEL;
> - kr->r.priority = rtm->rtm_priority;
> -
> - switch (sa->sa_family) {
> - case AF_INET6:
> - kr->r.prefix =
> - ((struct sockaddr_in6 *)sa)->sin6_addr;
> - sa_in6 = (struct sockaddr_in6 *)rti_info[RTAX_NETMASK];
> - if (rtm->rtm_flags & RTF_STATIC)
> - kr->r.flags |= F_STATIC;
> - if (rtm->rtm_flags & RTF_BLACKHOLE)
> - kr->r.flags |= F_BLACKHOLE;
> - if (rtm->rtm_flags & RTF_REJECT)
> - kr->r.flags |= F_REJECT;
> - if (rtm->rtm_flags & RTF_DYNAMIC)
> - kr->r.flags |= F_DYNAMIC;
> - if (sa_in6 != NULL) {
> - if (sa_in6->sin6_len == 0)
> - break;
> - kr->r.prefixlen =
> - mask2prefixlen(sa_in6);
> - } else if (rtm->rtm_flags & RTF_HOST)
> - kr->r.prefixlen = 128;
> - else
> - fatalx("classful IPv6 route?!!");
> - break;
> - default:
> - free(kr);
> - continue;
> - }
> -
> - kr->r.ifindex = 

Re: ospf6d: refactor kernel route message handling

2019-12-11 Thread Denis Fondras
On Tue, Dec 10, 2019 at 09:51:12PM +0100, Remi Locherer wrote:
> Unfortunately redistribute does not work anymore.
> 

Indeed, simple tests are too simple...

Here is an updated diff.

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
retrieving revision 1.60
diff -u -p -r1.60 kroute.c
--- kroute.c2 Jan 2019 21:32:55 -   1.60
+++ kroute.c11 Dec 2019 14:51:25 -
@@ -80,7 +80,7 @@ struct kroute_node*kroute_match(struct 
 
 intprotect_lo(void);
 void   get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
-void   if_change(u_short, int, struct if_data *);
+void   if_change(u_short, int, struct if_data *, struct sockaddr_dl *);
 void   if_newaddr(u_short, struct sockaddr_in6 *,
struct sockaddr_in6 *, struct sockaddr_in6 *);
 void   if_deladdr(u_short, struct sockaddr_in6 *,
@@ -90,6 +90,7 @@ void  if_announce(void *);
 intsend_rtmsg(int, int, struct kroute *);
 intdispatch_rtmsg(void);
 intfetchtable(void);
+intrtmsg_process(char *, size_t); 
 
 RB_HEAD(kroute_tree, kroute_node)  krt;
 RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
@@ -801,7 +802,8 @@ get_rtaddrs(int addrs, struct sockaddr *
 }
 
 void
-if_change(u_short ifindex, int flags, struct if_data *ifd)
+if_change(u_short ifindex, int flags, struct if_data *ifd,
+struct sockaddr_dl *sdl)
 {
struct kroute_node  *kr, *tkr;
struct iface*iface;
@@ -809,7 +811,7 @@ if_change(u_short ifindex, int flags, st
 
wasvalid = kif_validate(ifindex);
 
-   if ((iface = kif_update(ifindex, flags, ifd, NULL)) == NULL) {
+   if ((iface = kif_update(ifindex, flags, ifd, sdl)) == NULL) {
log_warn("if_change: kif_update(%u)", ifindex);
return;
}
@@ -1135,12 +1137,8 @@ fetchtable(void)
 {
size_t   len;
int  mib[7];
-   char*buf, *next, *lim;
-   struct rt_msghdr*rtm;
-   struct sockaddr *sa, *rti_info[RTAX_MAX];
-   struct sockaddr_in6 *sa_in6;
-   struct sockaddr_rtlabel *label;
-   struct kroute_node  *kr;
+   char*buf;
+   int  rv;
 
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@@ -1164,102 +1162,10 @@ fetchtable(void)
return (-1);
}
 
-   lim = buf + len;
-   for (next = buf; next < lim; next += rtm->rtm_msglen) {
-   rtm = (struct rt_msghdr *)next;
-   if (rtm->rtm_version != RTM_VERSION)
-   continue;
-   sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
-   get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
-
-   if ((sa = rti_info[RTAX_DST]) == NULL)
-   continue;
-
-   /* Skip ARP/ND cache and broadcast routes. */
-   if (rtm->rtm_flags & (RTF_LLINFO|RTF_BROADCAST))
-   continue;
-
-   if ((kr = calloc(1, sizeof(struct kroute_node))) == NULL) {
-   log_warn("fetchtable");
-   free(buf);
-   return (-1);
-   }
-
-   kr->r.flags = F_KERNEL;
-   kr->r.priority = rtm->rtm_priority;
-
-   switch (sa->sa_family) {
-   case AF_INET6:
-   kr->r.prefix =
-   ((struct sockaddr_in6 *)sa)->sin6_addr;
-   sa_in6 = (struct sockaddr_in6 *)rti_info[RTAX_NETMASK];
-   if (rtm->rtm_flags & RTF_STATIC)
-   kr->r.flags |= F_STATIC;
-   if (rtm->rtm_flags & RTF_BLACKHOLE)
-   kr->r.flags |= F_BLACKHOLE;
-   if (rtm->rtm_flags & RTF_REJECT)
-   kr->r.flags |= F_REJECT;
-   if (rtm->rtm_flags & RTF_DYNAMIC)
-   kr->r.flags |= F_DYNAMIC;
-   if (sa_in6 != NULL) {
-   if (sa_in6->sin6_len == 0)
-   break;
-   kr->r.prefixlen =
-   mask2prefixlen(sa_in6);
-   } else if (rtm->rtm_flags & RTF_HOST)
-   kr->r.prefixlen = 128;
-   else
-   fatalx("classful IPv6 route?!!");
-   break;
-   default:
-   free(kr);
-   continue;
-   }
-
-   kr->r.ifindex = rtm->rtm_index;
-   if ((sa = rti_info[RTAX_GATEWAY]) != NULL)
-   switch (sa->sa_family) {
-   case 

Re: ospf6d: refactor kernel route message handling

2019-12-10 Thread Remi Locherer
On Mon, Dec 09, 2019 at 07:31:11PM +0100, Denis Fondras wrote:
> Give some love to ospf6d.
> 
> The goal is to have ospf6d looks like ospfd, this could be useful to have
> changes made in one daemon from one go inside the other.
> 
> I will do it step by step until I get to the point where "ospf6ctl reload"
> works.

I like this a lot!
 
> First step is to refactor kernel route message handling, no functionnal 
> change.

I tested your diff with the following configuration:

--
router-id 192.168.250.7
fib-priority 38
redistribute default
redistribute rtlabel toOSPF depend on carp0
area 0 {
interface vether0 {
metric 55
depend on carp0
}
interface iwm0 { passive }
}
--

Unfortunately redistribute does not work anymore.

Remi



ospf6d: refactor kernel route message handling

2019-12-09 Thread Denis Fondras
Give some love to ospf6d.

The goal is to have ospf6d looks like ospfd, this could be useful to have
changes made in one daemon from one go inside the other.

I will do it step by step until I get to the point where "ospf6ctl reload"
works.

First step is to refactor kernel route message handling, no functionnal change.

Denis

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
retrieving revision 1.60
diff -u -p -r1.60 kroute.c
--- kroute.c2 Jan 2019 21:32:55 -   1.60
+++ kroute.c9 Dec 2019 17:35:33 -
@@ -80,7 +80,7 @@ struct kroute_node*kroute_match(struct 
 
 intprotect_lo(void);
 void   get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
-void   if_change(u_short, int, struct if_data *);
+void   if_change(u_short, int, struct if_data *, struct sockaddr_dl *);
 void   if_newaddr(u_short, struct sockaddr_in6 *,
struct sockaddr_in6 *, struct sockaddr_in6 *);
 void   if_deladdr(u_short, struct sockaddr_in6 *,
@@ -90,6 +90,7 @@ void  if_announce(void *);
 intsend_rtmsg(int, int, struct kroute *);
 intdispatch_rtmsg(void);
 intfetchtable(void);
+intrtmsg_process(char *, size_t); 
 
 RB_HEAD(kroute_tree, kroute_node)  krt;
 RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
@@ -801,7 +802,8 @@ get_rtaddrs(int addrs, struct sockaddr *
 }
 
 void
-if_change(u_short ifindex, int flags, struct if_data *ifd)
+if_change(u_short ifindex, int flags, struct if_data *ifd,
+struct sockaddr_dl *sdl)
 {
struct kroute_node  *kr, *tkr;
struct iface*iface;
@@ -809,7 +811,7 @@ if_change(u_short ifindex, int flags, st
 
wasvalid = kif_validate(ifindex);
 
-   if ((iface = kif_update(ifindex, flags, ifd, NULL)) == NULL) {
+   if ((iface = kif_update(ifindex, flags, ifd, sdl)) == NULL) {
log_warn("if_change: kif_update(%u)", ifindex);
return;
}
@@ -1135,12 +1137,8 @@ fetchtable(void)
 {
size_t   len;
int  mib[7];
-   char*buf, *next, *lim;
-   struct rt_msghdr*rtm;
-   struct sockaddr *sa, *rti_info[RTAX_MAX];
-   struct sockaddr_in6 *sa_in6;
-   struct sockaddr_rtlabel *label;
-   struct kroute_node  *kr;
+   char*buf;
+   int  rv;
 
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@@ -1164,102 +1162,10 @@ fetchtable(void)
return (-1);
}
 
-   lim = buf + len;
-   for (next = buf; next < lim; next += rtm->rtm_msglen) {
-   rtm = (struct rt_msghdr *)next;
-   if (rtm->rtm_version != RTM_VERSION)
-   continue;
-   sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
-   get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
-
-   if ((sa = rti_info[RTAX_DST]) == NULL)
-   continue;
-
-   /* Skip ARP/ND cache and broadcast routes. */
-   if (rtm->rtm_flags & (RTF_LLINFO|RTF_BROADCAST))
-   continue;
-
-   if ((kr = calloc(1, sizeof(struct kroute_node))) == NULL) {
-   log_warn("fetchtable");
-   free(buf);
-   return (-1);
-   }
-
-   kr->r.flags = F_KERNEL;
-   kr->r.priority = rtm->rtm_priority;
-
-   switch (sa->sa_family) {
-   case AF_INET6:
-   kr->r.prefix =
-   ((struct sockaddr_in6 *)sa)->sin6_addr;
-   sa_in6 = (struct sockaddr_in6 *)rti_info[RTAX_NETMASK];
-   if (rtm->rtm_flags & RTF_STATIC)
-   kr->r.flags |= F_STATIC;
-   if (rtm->rtm_flags & RTF_BLACKHOLE)
-   kr->r.flags |= F_BLACKHOLE;
-   if (rtm->rtm_flags & RTF_REJECT)
-   kr->r.flags |= F_REJECT;
-   if (rtm->rtm_flags & RTF_DYNAMIC)
-   kr->r.flags |= F_DYNAMIC;
-   if (sa_in6 != NULL) {
-   if (sa_in6->sin6_len == 0)
-   break;
-   kr->r.prefixlen =
-   mask2prefixlen(sa_in6);
-   } else if (rtm->rtm_flags & RTF_HOST)
-   kr->r.prefixlen = 128;
-   else
-   fatalx("classful IPv6 route?!!");
-   break;
-   default:
-   free(kr);
-   continue;
-   }
-
-   kr->r.ifindex = rtm->rtm_index;