mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 14:34:22 +00:00
zebra: data plane FPM add support RMAC VNI
Store VNI information in the data plane context so we can use it to build the FPM netlink update with that information later. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
770a8d284c
commit
f2a0ba3a50
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "mpls.h"
|
#include "mpls.h"
|
||||||
|
#include "vxlan.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -60,6 +61,10 @@ enum blackhole_type {
|
|||||||
? (type) \
|
? (type) \
|
||||||
: ((type) | 1)
|
: ((type) | 1)
|
||||||
|
|
||||||
|
enum nh_encap_type {
|
||||||
|
NET_VXLAN = 100, /* value copied from FPM_NH_ENCAP_VXLAN. */
|
||||||
|
};
|
||||||
|
|
||||||
/* Nexthop structure. */
|
/* Nexthop structure. */
|
||||||
struct nexthop {
|
struct nexthop {
|
||||||
struct nexthop *next;
|
struct nexthop *next;
|
||||||
@ -123,6 +128,12 @@ struct nexthop {
|
|||||||
* only meaningful if the HAS_BACKUP flag is set.
|
* only meaningful if the HAS_BACKUP flag is set.
|
||||||
*/
|
*/
|
||||||
uint8_t backup_idx;
|
uint8_t backup_idx;
|
||||||
|
|
||||||
|
/* Encapsulation information. */
|
||||||
|
enum nh_encap_type nh_encap_type;
|
||||||
|
union {
|
||||||
|
vni_t vni;
|
||||||
|
} nh_encap;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Backup index value is limited */
|
/* Backup index value is limited */
|
||||||
|
@ -626,7 +626,7 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
|
|||||||
case DPLANE_OP_ROUTE_UPDATE:
|
case DPLANE_OP_ROUTE_UPDATE:
|
||||||
case DPLANE_OP_ROUTE_DELETE:
|
case DPLANE_OP_ROUTE_DELETE:
|
||||||
rv = netlink_route_multipath(RTM_DELROUTE, ctx, nl_buf,
|
rv = netlink_route_multipath(RTM_DELROUTE, ctx, nl_buf,
|
||||||
sizeof(nl_buf));
|
sizeof(nl_buf), true);
|
||||||
if (rv <= 0) {
|
if (rv <= 0) {
|
||||||
zlog_debug("%s: netlink_route_multipath failed",
|
zlog_debug("%s: netlink_route_multipath failed",
|
||||||
__func__);
|
__func__);
|
||||||
@ -643,7 +643,7 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
|
|||||||
case DPLANE_OP_ROUTE_INSTALL:
|
case DPLANE_OP_ROUTE_INSTALL:
|
||||||
rv = netlink_route_multipath(RTM_NEWROUTE, ctx,
|
rv = netlink_route_multipath(RTM_NEWROUTE, ctx,
|
||||||
&nl_buf[nl_buf_len],
|
&nl_buf[nl_buf_len],
|
||||||
sizeof(nl_buf) - nl_buf_len);
|
sizeof(nl_buf) - nl_buf_len, true);
|
||||||
if (rv <= 0) {
|
if (rv <= 0) {
|
||||||
zlog_debug("%s: netlink_route_multipath failed",
|
zlog_debug("%s: netlink_route_multipath failed",
|
||||||
__func__);
|
__func__);
|
||||||
@ -829,8 +829,8 @@ static void fpm_enqueue_rmac_table(struct hash_backet *backet, void *arg)
|
|||||||
dplane_ctx_reset(fra->ctx);
|
dplane_ctx_reset(fra->ctx);
|
||||||
dplane_ctx_set_op(fra->ctx, DPLANE_OP_MAC_INSTALL);
|
dplane_ctx_set_op(fra->ctx, DPLANE_OP_MAC_INSTALL);
|
||||||
dplane_mac_init(fra->ctx, fra->zl3vni->vxlan_if,
|
dplane_mac_init(fra->ctx, fra->zl3vni->vxlan_if,
|
||||||
zif->brslave_info.br_if, vid, &zrmac->macaddr,
|
zif->brslave_info.br_if, vid,
|
||||||
zrmac->fwd_info.r_vtep_ip, sticky);
|
&zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, sticky);
|
||||||
if (fpm_nl_enqueue(fra->fnc, fra->ctx) == -1) {
|
if (fpm_nl_enqueue(fra->fnc, fra->ctx) == -1) {
|
||||||
thread_add_timer(zrouter.master, fpm_rmac_send,
|
thread_add_timer(zrouter.master, fpm_rmac_send,
|
||||||
fra->fnc, 1, &fra->fnc->t_rmacwalk);
|
fra->fnc, 1, &fra->fnc->t_rmacwalk);
|
||||||
|
@ -1528,11 +1528,28 @@ static bool nexthop_set_src(const struct nexthop *nexthop, int family,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen,
|
||||||
|
struct nexthop *nh)
|
||||||
|
{
|
||||||
|
struct rtattr *nest;
|
||||||
|
|
||||||
|
switch (nh->nh_encap_type) {
|
||||||
|
case NET_VXLAN:
|
||||||
|
addattr_l(n, nlen, RTA_ENCAP_TYPE, &nh->nh_encap_type,
|
||||||
|
sizeof(uint16_t));
|
||||||
|
|
||||||
|
nest = addattr_nest(n, nlen, RTA_ENCAP);
|
||||||
|
addattr32(n, nlen, 0 /* VXLAN_VNI */, nh->nh_encap.vni);
|
||||||
|
addattr_nest_end(n, nest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routing table change via netlink interface, using a dataplane context object
|
* Routing table change via netlink interface, using a dataplane context object
|
||||||
*/
|
*/
|
||||||
ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
|
ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
|
||||||
uint8_t *data, size_t datalen)
|
uint8_t *data, size_t datalen, bool fpm)
|
||||||
{
|
{
|
||||||
int bytelen;
|
int bytelen;
|
||||||
struct nexthop *nexthop = NULL;
|
struct nexthop *nexthop = NULL;
|
||||||
@ -1744,7 +1761,16 @@ ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
|
|||||||
nexthop_num++;
|
nexthop_num++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add encapsulation information when installing via
|
||||||
|
* FPM.
|
||||||
|
*/
|
||||||
|
if (fpm)
|
||||||
|
netlink_route_nexthop_encap(&req->n, datalen,
|
||||||
|
nexthop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setsrc) {
|
if (setsrc) {
|
||||||
if (p->family == AF_INET)
|
if (p->family == AF_INET)
|
||||||
addattr_l(&req->n, datalen, RTA_PREFSRC,
|
addattr_l(&req->n, datalen, RTA_PREFSRC,
|
||||||
@ -1796,7 +1822,16 @@ ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
|
|||||||
setsrc = 1;
|
setsrc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add encapsulation information when installing via
|
||||||
|
* FPM.
|
||||||
|
*/
|
||||||
|
if (fpm)
|
||||||
|
netlink_route_nexthop_encap(&req->n, datalen,
|
||||||
|
nexthop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setsrc) {
|
if (setsrc) {
|
||||||
if (p->family == AF_INET)
|
if (p->family == AF_INET)
|
||||||
addattr_l(&req->n, datalen, RTA_PREFSRC,
|
addattr_l(&req->n, datalen, RTA_PREFSRC,
|
||||||
@ -2149,7 +2184,8 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
|
|||||||
if (RSYSTEM_ROUTE(dplane_ctx_get_type(ctx)) &&
|
if (RSYSTEM_ROUTE(dplane_ctx_get_type(ctx)) &&
|
||||||
!RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx))) {
|
!RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx))) {
|
||||||
netlink_route_multipath(RTM_DELROUTE, ctx,
|
netlink_route_multipath(RTM_DELROUTE, ctx,
|
||||||
nl_pkt, sizeof(nl_pkt));
|
nl_pkt, sizeof(nl_pkt),
|
||||||
|
false);
|
||||||
netlink_talk_info(netlink_talk_filter,
|
netlink_talk_info(netlink_talk_filter,
|
||||||
(struct nlmsghdr *)nl_pkt,
|
(struct nlmsghdr *)nl_pkt,
|
||||||
dplane_ctx_get_ns(ctx), 0);
|
dplane_ctx_get_ns(ctx), 0);
|
||||||
@ -2169,7 +2205,8 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
|
|||||||
*/
|
*/
|
||||||
if (!RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx))) {
|
if (!RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx))) {
|
||||||
netlink_route_multipath(RTM_DELROUTE, ctx,
|
netlink_route_multipath(RTM_DELROUTE, ctx,
|
||||||
nl_pkt, sizeof(nl_pkt));
|
nl_pkt, sizeof(nl_pkt),
|
||||||
|
false);
|
||||||
netlink_talk_info(netlink_talk_filter,
|
netlink_talk_info(netlink_talk_filter,
|
||||||
(struct nlmsghdr *)nl_pkt,
|
(struct nlmsghdr *)nl_pkt,
|
||||||
dplane_ctx_get_ns(ctx), 0);
|
dplane_ctx_get_ns(ctx), 0);
|
||||||
@ -2182,7 +2219,8 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!RSYSTEM_ROUTE(dplane_ctx_get_type(ctx))) {
|
if (!RSYSTEM_ROUTE(dplane_ctx_get_type(ctx))) {
|
||||||
netlink_route_multipath(cmd, ctx, nl_pkt, sizeof(nl_pkt));
|
netlink_route_multipath(cmd, ctx, nl_pkt, sizeof(nl_pkt),
|
||||||
|
false);
|
||||||
ret = netlink_talk_info(netlink_talk_filter,
|
ret = netlink_talk_info(netlink_talk_filter,
|
||||||
(struct nlmsghdr *)nl_pkt,
|
(struct nlmsghdr *)nl_pkt,
|
||||||
dplane_ctx_get_ns(ctx), 0);
|
dplane_ctx_get_ns(ctx), 0);
|
||||||
|
@ -67,7 +67,8 @@ void rt_netlink_init(void);
|
|||||||
extern int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx);
|
extern int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx);
|
||||||
|
|
||||||
extern ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
|
extern ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
|
||||||
uint8_t *data, size_t datalen);
|
uint8_t *data, size_t datalen,
|
||||||
|
bool fpm);
|
||||||
extern ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx,
|
extern ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx,
|
||||||
uint8_t *data, size_t datalen);
|
uint8_t *data, size_t datalen);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "zebra/zebra_memory.h"
|
#include "zebra/zebra_memory.h"
|
||||||
#include "zebra/zebra_router.h"
|
#include "zebra/zebra_router.h"
|
||||||
#include "zebra/zebra_dplane.h"
|
#include "zebra/zebra_dplane.h"
|
||||||
|
#include "zebra/zebra_vxlan_private.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
|
|
||||||
@ -178,7 +179,6 @@ struct dplane_mac_info {
|
|||||||
struct ethaddr mac;
|
struct ethaddr mac;
|
||||||
struct in_addr vtep_ip;
|
struct in_addr vtep_ip;
|
||||||
bool is_sticky;
|
bool is_sticky;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1535,6 +1535,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
|
|||||||
struct zebra_ns *zns;
|
struct zebra_ns *zns;
|
||||||
struct zebra_vrf *zvrf;
|
struct zebra_vrf *zvrf;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
|
zebra_l3vni_t *zl3vni;
|
||||||
|
|
||||||
if (!ctx || !rn || !re)
|
if (!ctx || !rn || !re)
|
||||||
goto done;
|
goto done;
|
||||||
@ -1584,10 +1585,24 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
|
|||||||
re->nhe->backup_info->nhe->nhg.nexthop, NULL);
|
re->nhe->backup_info->nhe->nhg.nexthop, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that the dplane nexthops' flags are clear. */
|
/*
|
||||||
for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop))
|
* Ensure that the dplane nexthops' flags are clear and copy
|
||||||
|
* encapsulation information.
|
||||||
|
*/
|
||||||
|
for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop)) {
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||||
|
|
||||||
|
/* Check for available encapsulations. */
|
||||||
|
if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
zl3vni = zl3vni_from_vrf(nexthop->vrf_id);
|
||||||
|
if (zl3vni && is_l3vni_oper_up(zl3vni)) {
|
||||||
|
nexthop->nh_encap_type = NET_VXLAN;
|
||||||
|
nexthop->nh_encap.vni = zl3vni->vni;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't need some info when capturing a system notification */
|
/* Don't need some info when capturing a system notification */
|
||||||
if (op == DPLANE_OP_SYS_ROUTE_ADD ||
|
if (op == DPLANE_OP_SYS_ROUTE_ADD ||
|
||||||
op == DPLANE_OP_SYS_ROUTE_DELETE) {
|
op == DPLANE_OP_SYS_ROUTE_DELETE) {
|
||||||
|
Loading…
Reference in New Issue
Block a user