]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/rt_netlink.c
isisd: implement the 'lsp-too-large' notification
[mirror_frr.git] / zebra / rt_netlink.c
index a65d477f0379dd84802dff386e188b2599a9279c..8ce963b37b52bce522547d38295d51fd148598cf 100644 (file)
@@ -1584,7 +1584,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
        }
 
        /* 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)) {
                        /*
@@ -1676,9 +1676,6 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
 
                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 */
@@ -1711,6 +1708,8 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
                                                setsrc = 1;
                                        }
                                }
+
+                               continue;
                        }
 
                        if ((cmd == RTM_NEWROUTE
@@ -1874,12 +1873,6 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
 
                        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;
                        }
                }
        }
@@ -2272,6 +2265,25 @@ static int netlink_macfdb_update(struct interface *ifp, vlanid_t vid,
                            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)
@@ -2317,29 +2329,16 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
        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.
@@ -2690,7 +2689,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
        /* 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);
 
@@ -2737,9 +2736,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
                        if (!nexthop)
                                continue;
 
-                       if (nexthop_num >= multipath_num)
-                               break;
-
                        if ((cmd == RTM_NEWROUTE
                             && (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
                                 && CHECK_FLAG(nexthop->flags,