diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2c1f71756811effe065ea95f6498bc33c150c9b0..6753e8f6d990052131886396e0c6fba4420a91a6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -557,6 +557,11 @@ test-ospf-custom:
   variables:
     TEST_NAME: cf-ospf-custom
 
+test-ospf-area:
+  <<: *test-base
+  variables:
+    TEST_NAME: cf-ospf-area
+
 test-ospf-vrf:
   <<: *test-base
   variables:
@@ -611,3 +616,8 @@ test-babel-auth:
   <<: *test-base
   variables:
     TEST_NAME: cf-babel-auth
+
+test-rip-base:
+  <<: *test-base
+  variables:
+    TEST_NAME: cf-rip-base
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 704a1750f010608a055b71fc3b988251426e8e83..c9d2f5a5acd5241bce5e0f932ebb1fc644460ea7 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -255,7 +255,7 @@ WHITE [ \t]
   return IP4;
 }
 
-{XIGIT}{2}(:{XIGIT}{2}|{XIGIT}{2}){15,} {
+{XIGIT}{2}((:{XIGIT}{2}){15,}|({XIGIT}{2}){15,}) {
   char *s = yytext;
   size_t len = 0, i;
   struct bytestring *bytes;
diff --git a/filter/test.conf b/filter/test.conf
index f373bac5be767553ed90708840d54cec894fd009..5d766a8ec2e3f138207cd6f0bdec12ccf4eb617f 100644
--- a/filter/test.conf
+++ b/filter/test.conf
@@ -335,6 +335,26 @@ ip p;
 	p = 1234:5678::;
 	bt_assert(!p.is_v4);
 	bt_assert(p.mask(24) = 1234:5600::);
+
+	p = 1:2:3:4:5:6:7:8;
+	bt_assert(!p.is_v4);
+	bt_assert(format(p) = "1:2:3:4:5:6:7:8");
+	bt_assert(p.mask(64) = 1:2:3:4::);
+
+	p = 10:20:30:40:50:60:70:80;
+	bt_assert(!p.is_v4);
+	bt_assert(format(p) = "10:20:30:40:50:60:70:80");
+	bt_assert(p.mask(64) = 10:20:30:40::);
+
+	p = 1090:20a0:30b0:40c0:50d0:60e0:70f0:8000;
+	bt_assert(!p.is_v4);
+	bt_assert(format(p) = "1090:20a0:30b0:40c0:50d0:60e0:70f0:8000");
+	bt_assert(p.mask(64) = 1090:20a0:30b0:40c0::);
+
+	p = ::fffe:6:c0c:936d:88c7:35d3;
+	bt_assert(!p.is_v4);
+	bt_assert(format(p) = "::fffe:6:c0c:936d:88c7:35d3");
+	bt_assert(p.mask(64) = 0:0:fffe:6::);
 }
 
 bt_test_suite(t_ip, "Testing ip address");
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index f52a796f14da212bc5dc2756240916be7a038c90..c18c51da149b13acc13a1d437539496686d9ae4f 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -681,7 +681,7 @@ nl_add_multipath(struct nlmsghdr *h, uint bufsize, struct nexthop *nh, int af, e
 }
 
 static struct nexthop *
-nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr *ra, int af)
+nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, const net_addr *n, struct rtattr *ra, int af, int krt_src)
 {
   struct rtattr *a[BIRD_RTA_MAX];
   struct rtnexthop *nh = RTA_DATA(ra);
@@ -695,9 +695,9 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
     {
       /* Use RTNH_OK(nh,len) ?? */
       if ((len < sizeof(*nh)) || (len < nh->rtnh_len))
-	return NULL;
+	goto err;
 
-      if (nh->rtnh_flags & RTNH_F_DEAD)
+      if ((nh->rtnh_flags & RTNH_F_DEAD) && (krt_src != KRT_SRC_BIRD))
 	goto next;
 
       *last = rv = lp_allocz(s->pool, NEXTHOP_MAX_SIZE);
@@ -706,7 +706,10 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
       rv->weight = nh->rtnh_hops;
       rv->iface = if_find_by_index(nh->rtnh_ifindex);
       if (!rv->iface)
-	return NULL;
+	{
+	  log(L_ERR "KRT: Received route %N with unknown ifindex %u", n, nh->rtnh_ifindex);
+	  return NULL;
+	}
 
       /* Nonexistent RTNH_PAYLOAD ?? */
       nl_attr_len = nh->rtnh_len - RTNH_LENGTH(0);
@@ -714,18 +717,18 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
         {
 	case AF_INET:
 	  if (!nl_parse_attrs(RTNH_DATA(nh), nexthop_attr_want4, a, sizeof(a)))
-	    return NULL;
+	    goto err;
 	  break;
 
 	case AF_INET6:
 	  if (!nl_parse_attrs(RTNH_DATA(nh), nexthop_attr_want6, a, sizeof(a)))
-	    return NULL;
+	    goto err;
 	  break;
 
 #ifdef HAVE_MPLS_KERNEL
 	case AF_MPLS:
 	  if (!nl_parse_attrs(RTNH_DATA(nh), nexthop_attr_want_mpls, a, sizeof(a)))
-	    return NULL;
+	    goto err;
 
 	  if (a[RTA_NEWDST])
 	    rv->labels = rta_get_mpls(a[RTA_NEWDST], rv->label);
@@ -734,7 +737,7 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
 #endif
 
 	default:
-	  return NULL;
+	  goto err;
 	}
 
       if (a[RTA_GATEWAY])
@@ -757,14 +760,19 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
 	  nbr = neigh_find(&p->p, rv->gw, rv->iface,
 			   (rv->flags & RNF_ONLINK) ? NEF_ONLINK : 0);
 	  if (!nbr || (nbr->scope == SCOPE_HOST))
-	    return NULL;
+	    {
+	        log(L_ERR "KRT: Received route %N with strange next-hop %I", n, rv->gw);
+	        return NULL;
+	    }
 	}
 
 #ifdef HAVE_MPLS_KERNEL
       if (a[RTA_ENCAP] && a[RTA_ENCAP_TYPE])
       {
-	if (rta_get_u16(a[RTA_ENCAP_TYPE]) != LWTUNNEL_ENCAP_MPLS) {
-	  log(L_WARN "KRT: Unknown encapsulation method %d in multipath", rta_get_u16(a[RTA_ENCAP_TYPE]));
+	if (rta_get_u16(a[RTA_ENCAP_TYPE]) != LWTUNNEL_ENCAP_MPLS)
+	{
+	  log(L_WARN "KRT: Received route %N with unknown encapsulation method %d",
+	      n, rta_get_u16(a[RTA_ENCAP_TYPE]));
 	  return NULL;
 	}
 
@@ -785,6 +793,10 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
     first = nexthop_sort(first);
 
   return first;
+
+err:
+  log(L_ERR "KRT: Received strange multipath route %N", n);
+  return NULL;
 }
 
 static void
@@ -1682,19 +1694,16 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
 
       if (a[RTA_MULTIPATH])
         {
-	  struct nexthop *nh = nl_parse_multipath(s, p, a[RTA_MULTIPATH], i->rtm_family);
+	  struct nexthop *nh = nl_parse_multipath(s, p, net, a[RTA_MULTIPATH], i->rtm_family, krt_src);
 	  if (!nh)
-	    {
-	      log(L_ERR "KRT: Received strange multipath route %N", net);
-	      return;
-	    }
+	    SKIP("strange RTA_MULTIPATH\n");
 
 	  nexthop_link(ra, nh);
 	  break;
 	}
 
-      if (i->rtm_flags & RTNH_F_DEAD)
-	return;
+      if ((i->rtm_flags & RTNH_F_DEAD) && (krt_src != KRT_SRC_BIRD))
+	SKIP("ignore RTNH_F_DEAD\n");
 
       ra->nh.iface = if_find_by_index(oif);
       if (!ra->nh.iface)