summaryrefslogtreecommitdiff
path: root/proto/babel/babel.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2023-04-14 13:42:42 +0200
committerMaria Matejka <mq@ucw.cz>2023-04-14 13:42:42 +0200
commitea30d596d3732b3d2c4b1f55ebdc7cc018dd20bb (patch)
treef408b421d857a17791a0dc79c38ea9e60de4dc67 /proto/babel/babel.c
parenteb978f3a8357e53fcfeede1caf355e80d782ca6a (diff)
parentee919658948772105d0bd3b4535ba28883484f2c (diff)
Merge commit 'ee919658' into thread-next-iface
Diffstat (limited to 'proto/babel/babel.c')
-rw-r--r--proto/babel/babel.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 83a87d8f..cf625819 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -1002,8 +1002,18 @@ babel_send_update_(struct babel_iface *ifa, btime changed, struct fib *rtable)
msg.update.router_id = e->router_id;
net_copy(&msg.update.net, e->n.addr);
- msg.update.next_hop = ((e->n.addr->type == NET_IP4) ?
- ifa->next_hop_ip4 : ifa->next_hop_ip6);
+ if (e->n.addr->type == NET_IP4)
+ {
+ /* Always prefer IPv4 nexthop if set */
+ if (ipa_nonzero(ifa->next_hop_ip4))
+ msg.update.next_hop = ifa->next_hop_ip4;
+
+ /* Only send IPv6 nexthop if enabled */
+ else if (ifa->cf->ext_next_hop)
+ msg.update.next_hop = ifa->next_hop_ip6;
+ }
+ else
+ msg.update.next_hop = ifa->next_hop_ip6;
/* Do not send route if next hop is unknown, e.g. no configured IPv4 address */
if (ipa_zero(msg.update.next_hop))
@@ -1262,6 +1272,13 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa)
return;
}
+ /* Reject IPv4 via IPv6 routes if disabled */
+ if ((msg->net.type == NET_IP4) && ipa_is_ip6(msg->next_hop) && !ifa->cf->ext_next_hop)
+ {
+ DBG("Babel: Ignoring disabled IPv4 via IPv6 route.\n");
+ return;
+ }
+
/* Retraction */
if (msg->metric == BABEL_INFINITY)
{
@@ -1548,7 +1565,8 @@ babel_auth_check_pc(struct babel_iface *ifa, struct babel_msg_auth *msg)
n->auth_index_len = msg->index_len;
memcpy(n->auth_index, msg->index, msg->index_len);
- n->auth_pc = msg->pc;
+ n->auth_pc_unicast = msg->pc;
+ n->auth_pc_multicast = msg->pc;
n->auth_passed = 1;
return 1;
@@ -1567,16 +1585,30 @@ babel_auth_check_pc(struct babel_iface *ifa, struct babel_msg_auth *msg)
return 0;
}
- /* (6) Index matches; only accept if PC is greater than last */
- if (n->auth_pc >= msg->pc)
+ /*
+ * (6) Index matches; only accept if PC is greater than last. We keep separate
+ * counters for unicast and multicast because multicast packets can be delayed
+ * significantly on wireless networks (enough to be received out of order).
+ * Separate counters are safe because the packet destination address is part
+ * of the MAC pseudo-header (so unicast packets can't be replayed as multicast
+ * and vice versa).
+ */
+ u32 auth_pc = msg->unicast ? n->auth_pc_unicast : n->auth_pc_multicast;
+ if (auth_pc >= msg->pc)
{
LOG_PKT_AUTH("Authentication failed for %I on %s - "
- "lower packet counter (rcv %u, old %u)",
- msg->sender, ifa->ifname, msg->pc, n->auth_pc);
+ "lower %s packet counter (rcv %u, old %u)",
+ msg->sender, ifa->ifname,
+ msg->unicast ? "unicast" : "multicast",
+ msg->pc, auth_pc);
return 0;
}
- n->auth_pc = msg->pc;
+ if (msg->unicast)
+ n->auth_pc_unicast = msg->pc;
+ else
+ n->auth_pc_multicast = msg->pc;
+
n->auth_passed = 1;
return 1;
@@ -1728,7 +1760,7 @@ babel_iface_update_addr4(struct babel_iface *ifa)
ip_addr addr4 = ifa->iface->addr4 ? ifa->iface->addr4->ip : IPA_NONE;
ifa->next_hop_ip4 = ipa_nonzero(ifa->cf->next_hop_ip4) ? ifa->cf->next_hop_ip4 : addr4;
- if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel)
+ if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel && !ifa->cf->ext_next_hop)
log(L_WARN "%s: Missing IPv4 next hop address for %s", p->p.name, ifa->ifname);
if (ifa->up)
@@ -1805,8 +1837,8 @@ babel_add_iface(struct babel_proto *p, struct iface *new, struct babel_iface_con
ifa->next_hop_ip4 = ipa_nonzero(ic->next_hop_ip4) ? ic->next_hop_ip4 : addr4;
ifa->next_hop_ip6 = ipa_nonzero(ic->next_hop_ip6) ? ic->next_hop_ip6 : ifa->addr;
- if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel)
- log(L_WARN "%s: Missing IPv4 next hop address for %s", p->p.name, new->name);
+ if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel && !ic->ext_next_hop)
+ log(L_WARN "%s: Missing IPv4 next hop address for %s", p->p.name, ifa->ifname);
init_list(&ifa->neigh_list);
ifa->hello_seqno = 1;
@@ -1929,7 +1961,7 @@ babel_reconfigure_iface(struct babel_proto *p, struct babel_iface *ifa, struct b
if ((new->auth_type != BABEL_AUTH_NONE) && (new->auth_type != old->auth_type))
babel_auth_reset_index(ifa);
- if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel)
+ if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel && !new->ext_next_hop)
log(L_WARN "%s: Missing IPv4 next hop address for %s", p->p.name, ifa->ifname);
if (ifa->next_hello > (current_time() + new->hello_interval))