diff options
author | Maria Matejka <mq@ucw.cz> | 2023-04-14 13:42:42 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2023-04-14 13:42:42 +0200 |
commit | ea30d596d3732b3d2c4b1f55ebdc7cc018dd20bb (patch) | |
tree | f408b421d857a17791a0dc79c38ea9e60de4dc67 /proto/babel/babel.c | |
parent | eb978f3a8357e53fcfeede1caf355e80d782ca6a (diff) | |
parent | ee919658948772105d0bd3b4535ba28883484f2c (diff) |
Merge commit 'ee919658' into thread-next-iface
Diffstat (limited to 'proto/babel/babel.c')
-rw-r--r-- | proto/babel/babel.c | 56 |
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)) |