Nest: VRF of protocol can be explicitly specified as 'default'

Protocol can have specified VRF, in such case it is restricted to a set
of ifaces associated with the VRF, otherwise it can use all interfaces.

The patch allows to specify VRF as 'default', in which case it is
restricted to a set of iface not associated with any VRF.
This commit is contained in:
Ondrej Zajicek (work) 2019-07-24 15:08:03 +02:00
parent 048c2f0e8c
commit 18f70a6229
6 changed files with 19 additions and 13 deletions

View file

@ -65,7 +65,7 @@ proto_postconfig(void)
CF_DECLS CF_DECLS
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT) CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS) CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, DEFAULT, TABLE, STATES, ROUTES, FILTERS)
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS) CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED) CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES) CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
@ -209,7 +209,8 @@ proto_item:
| MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; } | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
| ROUTER ID idval { this_proto->router_id = $3; } | ROUTER ID idval { this_proto->router_id = $3; }
| DESCRIPTION text { this_proto->dsc = $2; } | DESCRIPTION text { this_proto->dsc = $2; }
| VRF text { this_proto->vrf = if_get_by_name($2); } | VRF text { this_proto->vrf = if_get_by_name($2); this_proto->vrf_set = 1; }
| VRF DEFAULT { this_proto->vrf = NULL; this_proto->vrf_set = 1; }
; ;

View file

@ -147,7 +147,7 @@ ifa_send_notify(struct proto *p, unsigned c, struct ifa *a)
{ {
if (p->ifa_notify && if (p->ifa_notify &&
(p->proto_state != PS_DOWN) && (p->proto_state != PS_DOWN) &&
(!p->vrf || p->vrf == a->iface->master)) (!p->vrf_set || p->vrf == a->iface->master))
{ {
if (p->debug & D_IFACES) if (p->debug & D_IFACES)
log(L_TRACE "%s < address %N on interface %s %s", log(L_TRACE "%s < address %N on interface %s %s",
@ -185,7 +185,7 @@ if_send_notify(struct proto *p, unsigned c, struct iface *i)
{ {
if (p->if_notify && if (p->if_notify &&
(p->proto_state != PS_DOWN) && (p->proto_state != PS_DOWN) &&
(!p->vrf || p->vrf == i->master)) (!p->vrf_set || p->vrf == i->master))
{ {
if (p->debug & D_IFACES) if (p->debug & D_IFACES)
log(L_TRACE "%s < interface %s %s", p->name, i->name, log(L_TRACE "%s < interface %s %s", p->name, i->name,

View file

@ -116,7 +116,7 @@ if_connected(ip_addr a, struct iface *i, struct ifa **ap, uint flags)
} }
static inline int static inline int
if_connected_any(ip_addr a, struct iface *vrf, struct iface **iface, struct ifa **addr, uint flags) if_connected_any(ip_addr a, struct iface *vrf, uint vrf_set, struct iface **iface, struct ifa **addr, uint flags)
{ {
struct iface *i; struct iface *i;
struct ifa *b; struct ifa *b;
@ -127,7 +127,7 @@ if_connected_any(ip_addr a, struct iface *vrf, struct iface **iface, struct ifa
/* Get first match, but prefer SCOPE_HOST to other matches */ /* Get first match, but prefer SCOPE_HOST to other matches */
WALK_LIST(i, iface_list) WALK_LIST(i, iface_list)
if ((!vrf || vrf == i->master) && ((s = if_connected(a, i, &b, flags)) >= 0)) if ((!vrf_set || vrf == i->master) && ((s = if_connected(a, i, &b, flags)) >= 0))
if ((scope < 0) || ((scope > SCOPE_HOST) && (s == SCOPE_HOST))) if ((scope < 0) || ((scope > SCOPE_HOST) && (s == SCOPE_HOST)))
{ {
*iface = i; *iface = i;
@ -192,7 +192,7 @@ neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
iface = (scope < 0) ? NULL : iface; iface = (scope < 0) ? NULL : iface;
} }
else else
scope = if_connected_any(a, p->vrf, &iface, &addr, flags); scope = if_connected_any(a, p->vrf, p->vrf_set, &iface, &addr, flags);
/* scope < 0 means i don't know neighbor */ /* scope < 0 means i don't know neighbor */
/* scope >= 0 <=> iface != NULL */ /* scope >= 0 <=> iface != NULL */
@ -309,6 +309,7 @@ neigh_free(neighbor *n)
void void
neigh_update(neighbor *n, struct iface *iface) neigh_update(neighbor *n, struct iface *iface)
{ {
struct proto *p = n->proto;
struct ifa *ifa = NULL; struct ifa *ifa = NULL;
int scope = -1; int scope = -1;
@ -317,14 +318,14 @@ neigh_update(neighbor *n, struct iface *iface)
return; return;
/* VRF-bound neighbors ignore changes in other VRFs */ /* VRF-bound neighbors ignore changes in other VRFs */
if (n->proto->vrf && (n->proto->vrf != iface->master)) if (p->vrf_set && (p->vrf != iface->master))
return; return;
scope = if_connected(n->addr, iface, &ifa, n->flags); scope = if_connected(n->addr, iface, &ifa, n->flags);
/* When neighbor is going down, try to respawn it on other ifaces */ /* When neighbor is going down, try to respawn it on other ifaces */
if ((scope < 0) && (n->scope >= 0) && !n->ifreq && (n->flags & NEF_STICKY)) if ((scope < 0) && (n->scope >= 0) && !n->ifreq && (n->flags & NEF_STICKY))
scope = if_connected_any(n->addr, n->proto->vrf, &iface, &ifa, n->flags); scope = if_connected_any(n->addr, p->vrf, p->vrf_set, &iface, &ifa, n->flags);
/* No change or minor change - ignore or notify */ /* No change or minor change - ignore or notify */
if ((scope == n->scope) && (iface == n->iface)) if ((scope == n->scope) && (iface == n->iface))

View file

@ -765,6 +765,7 @@ proto_init(struct proto_config *c, node *n)
p->proto_state = PS_DOWN; p->proto_state = PS_DOWN;
p->last_state_change = current_time(); p->last_state_change = current_time();
p->vrf = c->vrf; p->vrf = c->vrf;
p->vrf_set = c->vrf_set;
insert_node(&p->n, n); insert_node(&p->n, n);
p->event = ev_new_init(proto_pool, proto_event, p); p->event = ev_new_init(proto_pool, proto_event, p);
@ -932,7 +933,8 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
if ((nc->protocol != oc->protocol) || if ((nc->protocol != oc->protocol) ||
(nc->net_type != oc->net_type) || (nc->net_type != oc->net_type) ||
(nc->disabled != p->disabled) || (nc->disabled != p->disabled) ||
(nc->vrf != oc->vrf)) (nc->vrf != oc->vrf) ||
(nc->vrf_set != oc->vrf_set))
return 0; return 0;
p->name = nc->name; p->name = nc->name;
@ -1838,8 +1840,8 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
cli_msg(-1006, " Message: %s", p->message); cli_msg(-1006, " Message: %s", p->message);
if (p->cf->router_id) if (p->cf->router_id)
cli_msg(-1006, " Router ID: %R", p->cf->router_id); cli_msg(-1006, " Router ID: %R", p->cf->router_id);
if (p->vrf) if (p->vrf_set)
cli_msg(-1006, " VRF: %s", p->vrf->name); cli_msg(-1006, " VRF: %s", p->vrf ? p->vrf->name : "default");
if (p->proto->show_proto_info) if (p->proto->show_proto_info)
p->proto->show_proto_info(p); p->proto->show_proto_info(p);

View file

@ -120,6 +120,7 @@ struct proto_config {
int class; /* SYM_PROTO or SYM_TEMPLATE */ int class; /* SYM_PROTO or SYM_TEMPLATE */
u8 net_type; /* Protocol network type (NET_*), 0 for undefined */ u8 net_type; /* Protocol network type (NET_*), 0 for undefined */
u8 disabled; /* Protocol enabled/disabled by default */ u8 disabled; /* Protocol enabled/disabled by default */
u8 vrf_set; /* Related VRF instance (below) is defined */
u32 debug, mrtdump; /* Debugging bitfields, both use D_* constants */ u32 debug, mrtdump; /* Debugging bitfields, both use D_* constants */
u32 router_id; /* Protocol specific router ID */ u32 router_id; /* Protocol specific router ID */
@ -176,6 +177,7 @@ struct proto {
uint active_channels; /* Number of active channels */ uint active_channels; /* Number of active channels */
byte net_type; /* Protocol network type (NET_*), 0 for undefined */ byte net_type; /* Protocol network type (NET_*), 0 for undefined */
byte disabled; /* Manually disabled */ byte disabled; /* Manually disabled */
byte vrf_set; /* Related VRF instance (above) is defined */
byte proto_state; /* Protocol state machine (PS_*, see below) */ byte proto_state; /* Protocol state machine (PS_*, see below) */
byte active; /* From PS_START to cleanup after PS_STOP */ byte active; /* From PS_START to cleanup after PS_STOP */
byte do_start; /* Start actions are scheduled */ byte do_start; /* Start actions are scheduled */

View file

@ -624,7 +624,7 @@ bfd_request_notify(struct bfd_request *req, u8 state, u8 diag)
static int static int
bfd_add_request(struct bfd_proto *p, struct bfd_request *req) bfd_add_request(struct bfd_proto *p, struct bfd_request *req)
{ {
if (p->p.vrf && (p->p.vrf != req->vrf)) if (p->p.vrf_set && (p->p.vrf != req->vrf))
return 0; return 0;
struct bfd_session *s = bfd_find_session_by_addr(p, req->addr); struct bfd_session *s = bfd_find_session_by_addr(p, req->addr);