Re: ospf6d: refactor kernel route message handling
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
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
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
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;