]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: VRF of protocol can be explicitly specified as 'default'
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 24 Jul 2019 13:08:03 +0000 (15:08 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 24 Jul 2019 13:08:03 +0000 (15:08 +0200)
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.

nest/config.Y
nest/iface.c
nest/neighbor.c
nest/proto.c
nest/protocol.h
proto/bfd/bfd.c

index aef5ed46377830586441111052cb7a5e3734c725..053e59743c56aec2f045e7dfd1ae1c5d9c68eb1f 100644 (file)
@@ -65,7 +65,7 @@ proto_postconfig(void)
 CF_DECLS
 
 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(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
 CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
@@ -209,7 +209,8 @@ proto_item:
  | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
  | ROUTER ID idval { this_proto->router_id = $3; }
  | 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; }
  ;
 
 
index c1966ac65f59ad4f28822c62a437cfd3ac3b54e4..00dfc2ca305faaeebf58e9d3c08f0f3e899fa258 100644 (file)
@@ -147,7 +147,7 @@ ifa_send_notify(struct proto *p, unsigned c, struct ifa *a)
 {
   if (p->ifa_notify &&
       (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)
        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 &&
       (p->proto_state != PS_DOWN) &&
-      (!p->vrf || p->vrf == i->master))
+      (!p->vrf_set || p->vrf == i->master))
     {
       if (p->debug & D_IFACES)
        log(L_TRACE "%s < interface %s %s", p->name, i->name,
index 872538575e34f9063179768a52b793d50255c2fb..00a8e8a531154f51f053428f6521aa812839e570 100644 (file)
@@ -116,7 +116,7 @@ if_connected(ip_addr a, struct iface *i, struct ifa **ap, uint flags)
 }
 
 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 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 */
   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)))
       {
        *iface = i;
@@ -192,7 +192,7 @@ neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
     iface = (scope < 0) ? NULL : iface;
   }
   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  <=>  iface != NULL */
@@ -309,6 +309,7 @@ neigh_free(neighbor *n)
 void
 neigh_update(neighbor *n, struct iface *iface)
 {
+  struct proto *p = n->proto;
   struct ifa *ifa = NULL;
   int scope = -1;
 
@@ -317,14 +318,14 @@ neigh_update(neighbor *n, struct iface *iface)
     return;
 
   /* 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;
 
   scope = if_connected(n->addr, iface, &ifa, n->flags);
 
   /* When neighbor is going down, try to respawn it on other ifaces */
   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 */
   if ((scope == n->scope) && (iface == n->iface))
index beb3f393680ba6df4d8d6a2e61b659d34d13e604..696616509613933809cd9ddd1f04e4df51e6a6a2 100644 (file)
@@ -765,6 +765,7 @@ proto_init(struct proto_config *c, node *n)
   p->proto_state = PS_DOWN;
   p->last_state_change = current_time();
   p->vrf = c->vrf;
+  p->vrf_set = c->vrf_set;
   insert_node(&p->n, n);
 
   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) ||
       (nc->net_type != oc->net_type) ||
       (nc->disabled != p->disabled) ||
-      (nc->vrf != oc->vrf))
+      (nc->vrf != oc->vrf) ||
+      (nc->vrf_set != oc->vrf_set))
     return 0;
 
   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);
     if (p->cf->router_id)
       cli_msg(-1006, "  Router ID:      %R", p->cf->router_id);
-    if (p->vrf)
-      cli_msg(-1006, "  VRF:            %s", p->vrf->name);
+    if (p->vrf_set)
+      cli_msg(-1006, "  VRF:            %s", p->vrf ? p->vrf->name : "default");
 
     if (p->proto->show_proto_info)
       p->proto->show_proto_info(p);
index 53cccd5b63587dc59becf303ad730fa6189f8194..c8110f3cd663459a1ba76cf2052ed7cafee15997 100644 (file)
@@ -120,6 +120,7 @@ struct proto_config {
   int class;                           /* SYM_PROTO or SYM_TEMPLATE */
   u8 net_type;                         /* Protocol network type (NET_*), 0 for undefined */
   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 router_id;                       /* Protocol specific router ID */
 
@@ -176,6 +177,7 @@ struct proto {
   uint active_channels;                        /* Number of active channels */
   byte net_type;                       /* Protocol network type (NET_*), 0 for undefined */
   byte disabled;                       /* Manually disabled */
+  byte vrf_set;                                /* Related VRF instance (above) is defined */
   byte proto_state;                    /* Protocol state machine (PS_*, see below) */
   byte active;                         /* From PS_START to cleanup after PS_STOP */
   byte do_start;                       /* Start actions are scheduled */
index 151e0e1d528de8cb89f0a5bc74ea029adcd1dc96..930730705a1886ca364d0c02ba75c86acb73b50d 100644 (file)
@@ -624,7 +624,7 @@ bfd_request_notify(struct bfd_request *req, u8 state, u8 diag)
 static int
 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;
 
   struct bfd_session *s = bfd_find_session_by_addr(p, req->addr);