Is there anywhere a good reference to netlink? On Mon, Mar 16, 2015 at 11:32 AM, Henning Rogge <hro...@gmail.com> wrote: > On Mon, Mar 16, 2015 at 7:25 PM, Dave Taht <dave.t...@gmail.com> wrote: >> got code? > > I just used the same code I use for IPv4 (which has been working for > atomic replacement for ages). > > I got confused when someone reported "multiple IPv6 routes" which I > could not reproduce. > > http://olsr.org/git/?p=oonf.git;a=blob;f=src-plugins/subsystems/os_linux/os_routing_linux.c;h=4194fd04f8f259b686a1343cc906fc8649c6a7b6;hb=master > > If I understand it correctly you just need to set the routes with > NLM_F_CREATE | NLM_F_REPLACE to get the atomic replacement.
Well, I tried a naive approach to that for babel after looking over the olsr code and did not succeed at this level. I am curious as to whether this sequence of events works for olsr, in the first place. start it up on two machines add an ipv6 address on machine A) wait for it to show up in the routing table for B) delete the ipv6 address on machine A) See if it is unreachable, then gone on B) What happens with the patch below (and variants), is that babel thinks it has modified the route but it is not gone. I dont understand how the operation could work in the first place actually... don´t you have to feed both the old route and the new into the netmsg? I am going to go read the iproute2 code for bedtime sleepies. and git clone a fresh tree from git://github.com/jech/babeld.git root@ranger:/sys/class/net/eth0# ip -6 addr add 2601:9:4e01:9200::4/128 dev eth3 root@ranger:/sys/class/net/eth0# ip -6 addr del 2601:9:4e01:9200::4/128 dev eth3 on nuc: 2601:9:4e01:9200::4/128 from ::/0 metric 65535 (65535) refmetric 65535 id 02:25:90:ff:fe:f4:a5:c2 seqno 62322 chan (255) age 58 via eth0 neigh fe80::2ac6:8eff:febb:9ff1 (installed) but not gone in the FIB. I am running linux-3.18. The too simple babel patch: diff --git a/Makefile b/Makefile index 1bbb100..81f77cb 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ VERSION := $(shell ./get-version) CDEBUGFLAGS = -Os -g -Wall -DEFINES = $(PLATFORM_DEFINES) -DVERSION=\"$(VERSION)\" +DEFINES = $(PLATFORM_DEFINES) -DVERSION=\"$(VERSION)\" -DIPV6_SUBTREES CFLAGS = $(CDEBUGFLAGS) $(DEFINES) $(EXTRA_DEFINES) diff --git a/kernel_netlink.c b/kernel_netlink.c index eb2e801..47a9c56 100644 --- a/kernel_netlink.c +++ b/kernel_netlink.c @@ -966,6 +966,9 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, if(newmetric == metric && memcmp(newgate, gate, 16) == 0 && newifindex == ifindex) return 0; + /* If a kernel is new enough to do IPV6_SUBTREES it can do + atomic updates if only I knew how */ +#ifndef IPV6_SUBTREES /* It would be better to add the new route before removing the old one, to avoid losing packets. However, this causes problems with non-multipath kernels, which sometimes @@ -987,6 +990,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, Error handling is hard. */ } return rc; +#endif } @@ -1006,7 +1010,8 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, kdebugf("kernel_route: %s %s from %s " "table %d metric %d dev %d nexthop %s\n", operation == ROUTE_ADD ? "add" : - operation == ROUTE_FLUSH ? "flush" : "???", + operation == ROUTE_FLUSH ? "flush" : + operation == ROUTE_MODIFY ? "modify" : "???", format_prefix(dest, plen), format_prefix(src, src_plen), table, metric, ifindex, format_address(gate)); @@ -1016,14 +1021,20 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, return 0; memset(buf.raw, 0, sizeof(buf.raw)); - if(operation == ROUTE_ADD) { - buf.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL; + switch(operation) { + case ROUTE_ADD: + buf.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE; buf.nh.nlmsg_type = RTM_NEWROUTE; - } else { + break; + case ROUTE_FLUSH: buf.nh.nlmsg_flags = NLM_F_REQUEST; buf.nh.nlmsg_type = RTM_DELROUTE; - } - + break; + case ROUTE_MODIFY: + buf.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE; + buf.nh.nlmsg_type = RTM_NEWROUTE; + break; + } rtm = NLMSG_DATA(&buf.nh); rtm->rtm_family = ipv4 ? AF_INET : AF_INET6; rtm->rtm_dst_len = ipv4 ? plen - 96 : plen; @@ -1031,6 +1042,9 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, rtm->rtm_src_len = src_plen; rtm->rtm_table = table; rtm->rtm_scope = RT_SCOPE_UNIVERSE; + if(operation == ROUTE_FLUSH) { + rtm->rtm_scope = RT_SCOPE_NOWHERE; + } if(metric < KERNEL_INFINITY) rtm->rtm_type = RTN_UNICAST; else @@ -1067,8 +1081,11 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, rta = RTA_NEXT(rta, len); rta->rta_len = RTA_LENGTH(sizeof(int)); rta->rta_type = RTA_OIF; + if(operation == ROUTE_FLUSH) { + *(int*)RTA_DATA(rta) = 0; + } else { *(int*)RTA_DATA(rta) = ifindex; - + } if(ipv4) { rta = RTA_NEXT(rta, len); rta->rta_len = RTA_LENGTH(sizeof(struct in_addr)); -- Dave Täht Let's make wifi fast, less jittery and reliable again! https://plus.google.com/u/0/107942175615993706558/posts/TVX3o84jjmb _______________________________________________ Babel-users mailing list Babel-users@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/babel-users