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.

Signed-off-by: Toke Høiland-Jørgensen <[email protected]>
---
 proto/babel/packets.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/proto/babel/packets.c b/proto/babel/packets.c
index 0f70898e..da7d8a50 100644
--- a/proto/babel/packets.c
+++ b/proto/babel/packets.c
@@ -133,6 +133,7 @@ struct babel_write_state {
   u8 router_id_seen;
   u8 next_hop_v4_seen;
   u8 next_hop_v6_seen;
+  net_addr def_ip6_prefix;     /* Previous IPv6 prefix (for compression) */
 };
 
 
@@ -682,9 +683,32 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg 
*m,
   }
   else
   {
+    u8 omit = ip6_common_octets(net6_prefix(&state->def_ip6_prefix),
+                               net6_prefix(&msg->net));
+    DBG("%d bytes common between %I and %I\n", omit,
+       net6_prefix(&state->def_ip6_prefix), net6_prefix(&msg->net));
+
     tlv->ae = BABEL_AE_IP6;
     tlv->plen = net6_pxlen(&msg->net);
-    put_ip6_px(tlv->addr, &msg->net);
+    if (0 < omit)
+    {
+      u8 buf[16] = {};
+      omit = MIN(omit,
+                MIN(tlv->plen, net6_pxlen(&state->def_ip6_prefix)) / 8);
+
+      put_ip6_px(buf, &msg->net);
+      memcpy(tlv->addr, buf+omit, tlv->plen - omit);
+
+      tlv->omitted = omit;
+      tlv->length -= omit;
+      len -= omit;
+    }
+    else
+    {
+      put_ip6_px(tlv->addr, &msg->net);
+      tlv->flags |= BABEL_FLAG_DEF_PREFIX;
+      state->def_ip6_prefix = msg->net;
+    }
   }
 
   put_time16(&tlv->interval, msg->interval);
-- 
2.13.0

Reply via email to