]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/rt_netlink.c
zebra: let /32 host route with same IP cross VRF
[mirror_frr.git] / zebra / rt_netlink.c
index b3f04e421e1f6194883d35984bc18582bb834360..c6423dce99cc8d74a9a1c8d539760682ae901301 100644 (file)
@@ -438,6 +438,10 @@ parse_encap_seg6local(struct rtattr *tb,
        if (tb_encap[SEG6_LOCAL_TABLE])
                ctx->table = *(uint32_t *)RTA_DATA(tb_encap[SEG6_LOCAL_TABLE]);
 
+       if (tb_encap[SEG6_LOCAL_VRFTABLE])
+               ctx->table =
+                       *(uint32_t *)RTA_DATA(tb_encap[SEG6_LOCAL_VRFTABLE]);
+
        return act;
 }
 
@@ -507,7 +511,7 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
        if (index) {
                ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), index);
                if (ifp)
-                       nh_vrf_id = ifp->vrf_id;
+                       nh_vrf_id = ifp->vrf->vrf_id;
        }
        nh.vrf_id = nh_vrf_id;
 
@@ -581,7 +585,7 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
                        ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
                                                        index);
                        if (ifp)
-                               nh_vrf_id = ifp->vrf_id;
+                               nh_vrf_id = ifp->vrf->vrf_id;
                        else {
                                flog_warn(
                                        EC_ZEBRA_UNKNOWN_INTERFACE,
@@ -920,7 +924,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                        }
                        rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p,
                                &src_p, &nh, nhe_id, table, metric, mtu,
-                               distance, tag);
+                               distance, tag, startup);
                } else {
                        /* This is a multipath route */
                        struct route_entry *re;
@@ -964,7 +968,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
 
                        if (nhe_id || ng)
                                rib_add_multipath(afi, SAFI_UNICAST, &p,
-                                                 &src_p, re, ng);
+                                                 &src_p, re, ng, startup);
                        else
                                XFREE(MTYPE_RE, re);
                }
@@ -1467,6 +1471,16 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
                                                   ctx->table))
                                        return false;
                                break;
+                       case ZEBRA_SEG6_LOCAL_ACTION_END_DT4:
+                               if (!nl_attr_put32(nlmsg, req_size,
+                                                  SEG6_LOCAL_ACTION,
+                                                  SEG6_LOCAL_ACTION_END_DT4))
+                                       return false;
+                               if (!nl_attr_put32(nlmsg, req_size,
+                                                  SEG6_LOCAL_VRFTABLE,
+                                                  ctx->table))
+                                       return false;
+                               break;
                        default:
                                zlog_err("%s: unsupport seg6local behaviour action=%u",
                                         __func__,
@@ -1884,6 +1898,7 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
        union g_addr src;
        const struct prefix *p, *src_p;
        uint32_t table_id;
+       struct nlsock *nl;
 
        struct {
                struct nlmsghdr n;
@@ -1897,6 +1912,8 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
        if (datalen < sizeof(*req))
                return 0;
 
+       nl = kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
+
        memset(req, 0, sizeof(*req));
 
        bytelen = (p->family == AF_INET ? 4 : 16);
@@ -1910,7 +1927,7 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
 
        req->n.nlmsg_type = cmd;
 
-       req->n.nlmsg_pid = dplane_ctx_get_ns(ctx)->nls.snl.nl_pid;
+       req->n.nlmsg_pid = nl->snl.nl_pid;
 
        req->r.rtm_family = p->family;
        req->r.rtm_dst_len = p->prefixlen;
@@ -2346,6 +2363,8 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
        int type = dplane_ctx_get_nhe_type(ctx);
        struct rtattr *nest;
        uint16_t encap;
+       struct nlsock *nl =
+               kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
 
        if (!id) {
                flog_err(
@@ -2388,7 +2407,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
                req->n.nlmsg_flags |= NLM_F_REPLACE;
 
        req->n.nlmsg_type = cmd;
-       req->n.nlmsg_pid = dplane_ctx_get_ns(ctx)->nls.snl.nl_pid;
+       req->n.nlmsg_pid = nl->snl.nl_pid;
 
        req->nhm.nh_family = AF_UNSPEC;
        /* TODO: Scope? */
@@ -2570,6 +2589,18 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
                                                    ctx->table))
                                                        return 0;
                                                break;
+                                       case SEG6_LOCAL_ACTION_END_DT4:
+                                               if (!nl_attr_put32(
+                                                           &req->n, buflen,
+                                                           SEG6_LOCAL_ACTION,
+                                                           SEG6_LOCAL_ACTION_END_DT4))
+                                                       return 0;
+                                               if (!nl_attr_put32(
+                                                           &req->n, buflen,
+                                                           SEG6_LOCAL_VRFTABLE,
+                                                           ctx->table))
+                                                       return 0;
+                                               break;
                                        default:
                                                zlog_err("%s: unsupport seg6local behaviour action=%u",
                                                         __func__, action);
@@ -2799,7 +2830,7 @@ static struct nexthop netlink_nexthop_process_nh(struct rtattr **tb,
        if (ifp)
                *ifp = ifp_lookup;
        if (ifp_lookup)
-               nh.vrf_id = ifp_lookup->vrf_id;
+               nh.vrf_id = ifp_lookup->vrf->vrf_id;
        else {
                flog_warn(
                        EC_ZEBRA_UNKNOWN_INTERFACE,
@@ -3027,11 +3058,12 @@ int netlink_nexthop_read(struct zebra_ns *zns)
                 * this kernel must support them.
                 */
                supports_nh = true;
-
        if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_NHG)
                zlog_debug("Nexthop objects %ssupported on this kernel",
                           supports_nh ? "" : "not ");
 
+       zebra_router_set_supports_nhgs(supports_nh);
+
        return ret;
 }
 
@@ -3503,8 +3535,8 @@ static int netlink_request_specific_mac_in_bridge(struct zebra_ns *zns,
                zlog_debug(
                        "%s: Tx family %s IF %s(%u) vrf %s(%u) MAC %pEA vid %u",
                        __func__, nl_family_to_str(req.ndm.ndm_family),
-                       br_if->name, br_if->ifindex,
-                       vrf_id_to_name(br_if->vrf_id), br_if->vrf_id, mac, vid);
+                       br_if->name, br_if->ifindex, br_if->vrf->name,
+                       br_if->vrf->vrf_id, mac, vid);
 
        return netlink_request(&zns->netlink_cmd, &req);
 }
@@ -3676,7 +3708,6 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
        struct interface *link_if;
        struct ethaddr mac;
        struct ipaddr ip;
-       struct vrf *vrf;
        char buf[ETHER_ADDR_STRLEN];
        int mac_present = 0;
        bool is_ext;
@@ -3695,7 +3726,6 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
        if (!ifp || !ifp->info)
                return 0;
 
-       vrf = vrf_lookup_by_id(ifp->vrf_id);
        zif = (struct zebra_if *)ifp->info;
 
        /* Parse attributes and extract fields of interest. */
@@ -3705,7 +3735,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
                zlog_debug("%s family %s IF %s(%u) vrf %s(%u) - no DST",
                           nl_msg_type_to_str(h->nlmsg_type),
                           nl_family_to_str(ndm->ndm_family), ifp->name,
-                          ndm->ndm_ifindex, VRF_LOGNAME(vrf), ifp->vrf_id);
+                          ndm->ndm_ifindex, ifp->vrf->name, ifp->vrf->vrf_id);
                return 0;
        }
 
@@ -3801,7 +3831,8 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
                                                nl_family_to_str(
                                                        ndm->ndm_family),
                                                ifp->name, ndm->ndm_ifindex,
-                                               VRF_LOGNAME(vrf), ifp->vrf_id,
+                                               ifp->vrf->name,
+                                               ifp->vrf->vrf_id,
                                                (unsigned long)RTA_PAYLOAD(
                                                        tb[NDA_LLADDR]));
                                return 0;
@@ -3825,8 +3856,8 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
                                "Rx %s family %s IF %s(%u) vrf %s(%u) IP %pIA MAC %s state 0x%x flags 0x%x ext_flags 0x%x",
                                nl_msg_type_to_str(h->nlmsg_type),
                                nl_family_to_str(ndm->ndm_family), ifp->name,
-                               ndm->ndm_ifindex, VRF_LOGNAME(vrf), ifp->vrf_id,
-                               &ip,
+                               ndm->ndm_ifindex, ifp->vrf->name,
+                               ifp->vrf->vrf_id, &ip,
                                mac_present
                                        ? prefix_mac2str(&mac, buf, sizeof(buf))
                                        : "",
@@ -3861,7 +3892,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
                zlog_debug("Rx %s family %s IF %s(%u) vrf %s(%u) IP %pIA",
                           nl_msg_type_to_str(h->nlmsg_type),
                           nl_family_to_str(ndm->ndm_family), ifp->name,
-                          ndm->ndm_ifindex, VRF_LOGNAME(vrf), ifp->vrf_id,
+                          ndm->ndm_ifindex, ifp->vrf->name, ifp->vrf->vrf_id,
                           &ip);
 
        /* Process the delete - it may result in re-adding the neighbor if it is
@@ -4004,7 +4035,7 @@ int netlink_neigh_read_specific_ip(const struct ipaddr *ip,
 {
        int ret = 0;
        struct zebra_ns *zns;
-       struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vlan_if->vrf_id);
+       struct zebra_vrf *zvrf = vlan_if->vrf->info;
        struct zebra_dplane_info dp_info;
 
        zns = zvrf->zns;
@@ -4014,7 +4045,7 @@ int netlink_neigh_read_specific_ip(const struct ipaddr *ip,
        if (IS_ZEBRA_DEBUG_KERNEL)
                zlog_debug("%s: neigh request IF %s(%u) IP %pIA vrf %s(%u)",
                           __func__, vlan_if->name, vlan_if->ifindex, ip,
-                          vrf_id_to_name(vlan_if->vrf_id), vlan_if->vrf_id);
+                          vlan_if->vrf->name, vlan_if->vrf->vrf_id);
 
        ret = netlink_request_specific_neigh_in_vlan(zns, RTM_GETNEIGH, ip,
                                            vlan_if->ifindex);
@@ -4257,6 +4288,8 @@ ssize_t netlink_mpls_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
        const char *routedesc;
        int route_type;
        struct prefix p = {0};
+       struct nlsock *nl =
+               kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
 
        struct {
                struct nlmsghdr n;
@@ -4299,7 +4332,7 @@ ssize_t netlink_mpls_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
        req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
        req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
        req->n.nlmsg_type = cmd;
-       req->n.nlmsg_pid = dplane_ctx_get_ns(ctx)->nls.snl.nl_pid;
+       req->n.nlmsg_pid = nl->snl.nl_pid;
 
        req->r.rtm_family = AF_MPLS;
        req->r.rtm_table = RT_TABLE_MAIN;