}
/* Singlepath case. */
- if (nexthop_num == 1 || multipath_num == 1) {
+ if (nexthop_num == 1) {
nexthop_num = 0;
for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
/*
nexthop_num = 0;
for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
- if (nexthop_num >= multipath_num)
- break;
-
if (CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_RECURSIVE)) {
/* This only works for IPv4 now */
setsrc = 1;
}
}
+
+ continue;
}
if ((cmd == RTM_NEWROUTE
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
-
- /* If we're only allowed a single nh, don't
- * continue.
- */
- if (multipath_num == 1)
- break;
}
}
}
0);
}
+/*
+ * In the event the kernel deletes ipv4 link-local neighbor entries created for
+ * 5549 support, re-install them.
+ */
+static void netlink_handle_5549(struct ndmsg *ndm, struct zebra_if *zif,
+ struct interface *ifp, struct ipaddr *ip)
+{
+ if (ndm->ndm_family != AF_INET)
+ return;
+
+ if (!zif->v6_2_v4_ll_neigh_entry)
+ return;
+
+ if (ipv4_ll.s_addr != ip->ip._v4_addr.s_addr)
+ return;
+
+ if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, &zif->v6_2_v4_ll_addr6, true);
+}
+
#define NUD_VALID \
(NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE | NUD_PROBE | NUD_STALE \
| NUD_DELAY)
ip.ipa_type = (ndm->ndm_family == AF_INET) ? IPADDR_V4 : IPADDR_V6;
memcpy(&ip.ip.addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST]));
- /* Drop some "permanent" entries. */
- if (ndm->ndm_state & NUD_PERMANENT) {
- char b[16] = "169.254.0.1";
- struct in_addr ipv4_ll;
-
- if (ndm->ndm_family != AF_INET)
- return 0;
-
- if (!zif->v6_2_v4_ll_neigh_entry)
- return 0;
-
- if (h->nlmsg_type != RTM_DELNEIGH)
- return 0;
-
- inet_pton(AF_INET, b, &ipv4_ll);
- if (ipv4_ll.s_addr != ip.ip._v4_addr.s_addr)
- return 0;
-
- if_nbr_ipv6ll_to_ipv4ll_neigh_update(
- ifp, &zif->v6_2_v4_ll_addr6, true);
+ /* if kernel deletes our rfc5549 neighbor entry, re-install it */
+ if (h->nlmsg_type == RTM_DELNEIGH && (ndm->ndm_state & NUD_PERMANENT)) {
+ netlink_handle_5549(ndm, zif, ifp, &ip);
return 0;
}
+ /* if kernel marks our rfc5549 neighbor entry invalid, re-install it */
+ if (h->nlmsg_type == RTM_NEWNEIGH && !(ndm->ndm_state & NUD_VALID))
+ netlink_handle_5549(ndm, zif, ifp, &ip);
+
/* The neighbor is present on an SVI. From this, we locate the
* underlying
* bridge because we're only interested in neighbors on a VxLAN bridge.
/* Fill nexthops (paths) based on single-path or multipath. The paths
* chosen depend on the operation.
*/
- if (nexthop_num == 1 || multipath_num == 1) {
+ if (nexthop_num == 1) {
routedesc = "single-path";
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
if (!nexthop)
continue;
- if (nexthop_num >= multipath_num)
- break;
-
if ((cmd == RTM_NEWROUTE
&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
&& CHECK_FLAG(nexthop->flags,