]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Babel: Implement IPv6 prefix compression on outgoing updates
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 9 Jun 2017 11:00:20 +0000 (13:00 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 9 Jun 2017 11:00:20 +0000 (13:00 +0200)
Previously, the Babel protocol would never use prefix compression on outgoing
updates (but would parse it on incoming ones). This adds compression of IPv6
addresses of outgoing updates.

The compression only works to the extent that the FIB is walked in lexicographic
order; i.e. a prefix is only compressed if it shares bytes with the previous
prefix in the same packet.

Thanks to Toke Høiland-Jørgensen <toke@toke.dk> for the patch.

proto/babel/packets.c

index b52c2ddfaf10a75ea82896cb8e7b9050499fbce6..72ac4f2948cf21fdaee00b12724a6ab494ccb51a 100644 (file)
@@ -133,6 +133,8 @@ struct babel_write_state {
   u8 router_id_seen;
   ip_addr next_hop_ip4;
   ip_addr next_hop_ip6;
+  u8 def_ip6_prefix[16];       /* Implicit IPv6 prefix in network order */
+  u8 def_ip6_pxlen;
 };
 
 
@@ -150,6 +152,14 @@ struct babel_write_state {
 
 #define NET_SIZE(n) BYTES(net_pxlen(n))
 
+static inline uint
+bytes_equal(u8 *b1, u8 *b2, uint maxlen)
+{
+  uint i;
+  for (i = 0; (i < maxlen) && (*b1 == *b2); i++, b1++, b2++)
+    ;
+  return i;
+}
 
 static inline u16
 get_time16(const void *p)
@@ -696,7 +706,29 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
   {
     tlv->ae = BABEL_AE_IP6;
     tlv->plen = net6_pxlen(&msg->net);
-    put_ip6_px(tlv->addr, &msg->net);
+
+    /* Address compression - omit initial matching bytes */
+    u8 buf[16], omit;
+    put_ip6(buf, net6_prefix(&msg->net));
+    omit = bytes_equal(buf, state->def_ip6_prefix,
+                      MIN(tlv->plen, state->def_ip6_pxlen) / 8);
+
+    if (omit > 0)
+    {
+      memcpy(tlv->addr, buf + omit, NET_SIZE(&msg->net) - omit);
+
+      tlv->omitted = omit;
+      tlv->length -= omit;
+      len -= omit;
+    }
+    else
+    {
+      put_ip6_px(tlv->addr, &msg->net);
+      tlv->flags |= BABEL_FLAG_DEF_PREFIX;
+
+      put_ip6(state->def_ip6_prefix, net6_prefix(&msg->net));
+      state->def_ip6_pxlen = tlv->plen;
+    }
   }
 
   put_time16(&tlv->interval, msg->interval);