summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ip.h5
-rw-r--r--proto/bgp/packets.c3
2 files changed, 7 insertions, 1 deletions
diff --git a/lib/ip.h b/lib/ip.h
index b78a5e22..abd825ae 100644
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -226,6 +226,9 @@ int ip6_compare(ip6_addr a, ip6_addr b);
int ip4_classify(ip4_addr ad);
int ip6_classify(ip6_addr *a);
+static inline int ip4_is_link_local(ip6_addr a)
+{ return (_I3(a) & 0xffff0000) == 0xa9fe0000; }
+
static inline int ip6_is_link_local(ip6_addr a)
{ return (_I0(a) & 0xffc00000) == 0xfe800000; }
@@ -233,7 +236,7 @@ static inline int ip6_is_v4mapped(ip6_addr a)
{ return _I0(a) == 0 && _I1(a) == 0 && _I2(a) == 0xffff; }
#define ipa_classify(x) ip6_classify(&(x))
-#define ipa_is_link_local(x) ip6_is_link_local(x)
+#define ipa_is_link_local(x) (ipa_is_ip4(x) ? ip4_is_link_local(x) : ip6_is_link_local(x))
static inline int ip4_is_unicast(ip4_addr a)
{ return _I(a) < 0xe0000000; }
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index 26716573..8f667d9f 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -1024,6 +1024,9 @@ bgp_decode_next_hop_ip(struct bgp_parse_state *s, byte *data, uint len, rta *a)
{
nh[0] = ipa_from_ip4(get_ip4(data));
nh[1] = IPA_NONE;
+
+ if (ipa_is_link_local(nh[0]))
+ { nh[1] = nh[0]; nh[0] = IPA_NONE; }
}
else if (len == 16)
{