mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-17 08:38:42 +00:00
Merge commit '7b2c5f3d2826e3175bf31b1c36056c9efc587a2b' into int-new
This commit is contained in:
commit
46434a3cad
@ -600,6 +600,15 @@ agreement").
|
|||||||
|
|
||||||
<tag><label id="proto-table">table <m/name/</tag>
|
<tag><label id="proto-table">table <m/name/</tag>
|
||||||
Connect this protocol to a non-default routing table.
|
Connect this protocol to a non-default routing table.
|
||||||
|
|
||||||
|
<tag><label id="proto-vrf">vrf "<m/text/"</tag>
|
||||||
|
Associate the protocol with specific VRF. The protocol will be
|
||||||
|
restricted to interfaces assigned to the VRF and will use sockets bound
|
||||||
|
to the VRF. Appropriate VRF interface must exist on OS level. For kernel
|
||||||
|
protocol, an appropriate table still must be explicitly selected by
|
||||||
|
<cf/table/ option. Note that the VRF support in BIRD and Linux kernel
|
||||||
|
(4.11) is still in development and is currently problematic outside of
|
||||||
|
multihop BGP.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
<p>There are several options that give sense only with certain protocols:
|
<p>There are several options that give sense only with certain protocols:
|
||||||
@ -1331,6 +1340,8 @@ foot).
|
|||||||
|
|
||||||
<cf><m/P/.len</cf> returns the length of path <m/P/.
|
<cf><m/P/.len</cf> returns the length of path <m/P/.
|
||||||
|
|
||||||
|
<cf><m/P/.empty</cf> resets path <m/P/ to empty path.
|
||||||
|
|
||||||
<cf>prepend(<m/P/,<m/A/)</cf> prepends ASN <m/A/ to path <m/P/ and
|
<cf>prepend(<m/P/,<m/A/)</cf> prepends ASN <m/A/ to path <m/P/ and
|
||||||
returns the result.
|
returns the result.
|
||||||
|
|
||||||
@ -1369,6 +1380,8 @@ foot).
|
|||||||
|
|
||||||
<cf><m/C/.len</cf> returns the length of clist <m/C/.
|
<cf><m/C/.len</cf> returns the length of clist <m/C/.
|
||||||
|
|
||||||
|
<cf><m/C/.empty</cf> resets clist <m/C/ to empty clist.
|
||||||
|
|
||||||
<cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist <m/C/ and
|
<cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist <m/C/ and
|
||||||
returns the result. If item <m/P/ is already in clist <m/C/, it does
|
returns the result. If item <m/P/ is already in clist <m/C/, it does
|
||||||
nothing. <m/P/ may also be a clist, in that case all its members are
|
nothing. <m/P/ may also be a clist, in that case all its members are
|
||||||
|
@ -50,6 +50,7 @@ typedef struct birdsock {
|
|||||||
int ttl; /* Time To Live, -1 = default */
|
int ttl; /* Time To Live, -1 = default */
|
||||||
u32 flags;
|
u32 flags;
|
||||||
struct iface *iface; /* Interface; specify this for broad/multicast sockets */
|
struct iface *iface; /* Interface; specify this for broad/multicast sockets */
|
||||||
|
struct iface *vrf; /* Related VRF instance, NULL if global */
|
||||||
|
|
||||||
byte *rbuf, *rpos; /* NULL=allocate automatically */
|
byte *rbuf, *rpos; /* NULL=allocate automatically */
|
||||||
uint fast_rx; /* RX has higher priority in event loop */
|
uint fast_rx; /* RX has higher priority in event loop */
|
||||||
|
@ -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, TABLE, STATES, ROUTES, FILTERS)
|
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS)
|
||||||
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6)
|
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6)
|
||||||
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)
|
||||||
@ -225,6 +225,7 @@ 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); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
24
nest/iface.c
24
nest/iface.c
@ -120,7 +120,7 @@ if_what_changed(struct iface *i, struct iface *j)
|
|||||||
unsigned c;
|
unsigned c;
|
||||||
|
|
||||||
if (((i->flags ^ j->flags) & ~(IF_UP | IF_SHUTDOWN | IF_UPDATED | IF_ADMIN_UP | IF_LINK_UP | IF_TMP_DOWN | IF_JUST_CREATED))
|
if (((i->flags ^ j->flags) & ~(IF_UP | IF_SHUTDOWN | IF_UPDATED | IF_ADMIN_UP | IF_LINK_UP | IF_TMP_DOWN | IF_JUST_CREATED))
|
||||||
|| i->index != j->index)
|
|| (i->index != j->index) || (i->master != j->master))
|
||||||
return IF_CHANGE_TOO_MUCH;
|
return IF_CHANGE_TOO_MUCH;
|
||||||
c = 0;
|
c = 0;
|
||||||
if ((i->flags ^ j->flags) & IF_UP)
|
if ((i->flags ^ j->flags) & IF_UP)
|
||||||
@ -137,12 +137,16 @@ if_copy(struct iface *to, struct iface *from)
|
|||||||
{
|
{
|
||||||
to->flags = from->flags | (to->flags & IF_TMP_DOWN);
|
to->flags = from->flags | (to->flags & IF_TMP_DOWN);
|
||||||
to->mtu = from->mtu;
|
to->mtu = from->mtu;
|
||||||
|
to->master_index = from->master_index;
|
||||||
|
to->master = from->master;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
ifa_send_notify(struct proto *p, unsigned c, struct ifa *a)
|
ifa_send_notify(struct proto *p, unsigned c, struct ifa *a)
|
||||||
{
|
{
|
||||||
if (p->ifa_notify && (p->proto_state != PS_DOWN))
|
if (p->ifa_notify &&
|
||||||
|
(p->proto_state != PS_DOWN) &&
|
||||||
|
(!p->vrf || 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",
|
||||||
@ -178,7 +182,9 @@ ifa_notify_change(unsigned c, struct ifa *a)
|
|||||||
static inline void
|
static inline void
|
||||||
if_send_notify(struct proto *p, unsigned c, struct iface *i)
|
if_send_notify(struct proto *p, unsigned c, struct iface *i)
|
||||||
{
|
{
|
||||||
if (p->if_notify && (p->proto_state != PS_DOWN))
|
if (p->if_notify &&
|
||||||
|
(p->proto_state != PS_DOWN) &&
|
||||||
|
(!p->vrf || 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,
|
||||||
@ -234,7 +240,9 @@ if_notify_change(unsigned c, struct iface *i)
|
|||||||
static uint
|
static uint
|
||||||
if_recalc_flags(struct iface *i UNUSED, uint flags)
|
if_recalc_flags(struct iface *i UNUSED, uint flags)
|
||||||
{
|
{
|
||||||
if ((flags & IF_ADMIN_UP) && !(flags & (IF_SHUTDOWN | IF_TMP_DOWN)))
|
if ((flags & IF_ADMIN_UP) &&
|
||||||
|
!(flags & (IF_SHUTDOWN | IF_TMP_DOWN)) &&
|
||||||
|
!(i->master_index && !i->master))
|
||||||
flags |= IF_UP;
|
flags |= IF_UP;
|
||||||
else
|
else
|
||||||
flags &= ~IF_UP;
|
flags &= ~IF_UP;
|
||||||
@ -835,7 +843,13 @@ if_show(void)
|
|||||||
if (i->flags & IF_SHUTDOWN)
|
if (i->flags & IF_SHUTDOWN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cli_msg(-1001, "%s %s (index=%d)", i->name, (i->flags & IF_UP) ? "Up" : "Down", i->index);
|
char mbuf[16 + sizeof(i->name)] = {};
|
||||||
|
if (i->master)
|
||||||
|
bsprintf(mbuf, " master=%s", i->master->name);
|
||||||
|
else if (i->master_index)
|
||||||
|
bsprintf(mbuf, " master=#%u", i->master_index);
|
||||||
|
|
||||||
|
cli_msg(-1001, "%s %s (index=%d%s)", i->name, (i->flags & IF_UP) ? "Up" : "Down", i->index, mbuf);
|
||||||
if (!(i->flags & IF_MULTIACCESS))
|
if (!(i->flags & IF_MULTIACCESS))
|
||||||
type = "PtP";
|
type = "PtP";
|
||||||
else
|
else
|
||||||
|
@ -34,6 +34,8 @@ struct iface {
|
|||||||
unsigned flags;
|
unsigned flags;
|
||||||
unsigned mtu;
|
unsigned mtu;
|
||||||
unsigned index; /* OS-dependent interface index */
|
unsigned index; /* OS-dependent interface index */
|
||||||
|
unsigned master_index; /* Interface index of master iface */
|
||||||
|
struct iface *master; /* Master iface (e.g. for VRF) */
|
||||||
list addrs; /* Addresses assigned to this interface */
|
list addrs; /* Addresses assigned to this interface */
|
||||||
struct ifa *addr4; /* Primary address for IPv4 */
|
struct ifa *addr4; /* Primary address for IPv4 */
|
||||||
struct ifa *addr6; /* Primary address for IPv6 */
|
struct ifa *addr6; /* Primary address for IPv6 */
|
||||||
|
@ -45,6 +45,7 @@ olock_same(struct object_lock *x, struct object_lock *y)
|
|||||||
return
|
return
|
||||||
x->type == y->type &&
|
x->type == y->type &&
|
||||||
x->iface == y->iface &&
|
x->iface == y->iface &&
|
||||||
|
x->vrf == y->vrf &&
|
||||||
x->port == y->port &&
|
x->port == y->port &&
|
||||||
x->inst == y->inst &&
|
x->inst == y->inst &&
|
||||||
ipa_equal(x->addr, y->addr);
|
ipa_equal(x->addr, y->addr);
|
||||||
|
@ -30,6 +30,7 @@ struct object_lock {
|
|||||||
uint port; /* ... port number */
|
uint port; /* ... port number */
|
||||||
uint inst; /* ... instance ID */
|
uint inst; /* ... instance ID */
|
||||||
struct iface *iface; /* ... interface */
|
struct iface *iface; /* ... interface */
|
||||||
|
struct iface *vrf; /* ... or VRF (if iface is unknown) */
|
||||||
void (*hook)(struct object_lock *); /* Called when the lock succeeds */
|
void (*hook)(struct object_lock *); /* Called when the lock succeeds */
|
||||||
void *data; /* User data */
|
void *data; /* User data */
|
||||||
/* ... internal to lock manager, don't touch ... */
|
/* ... internal to lock manager, don't touch ... */
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
* when the protocol has explicitly requested it via the %NEF_STICKY
|
* when the protocol has explicitly requested it via the %NEF_STICKY
|
||||||
* flag because it wishes to be notified when the node will again become
|
* flag because it wishes to be notified when the node will again become
|
||||||
* a neighbor. Such entries are enqueued in a special list which is walked
|
* a neighbor. Such entries are enqueued in a special list which is walked
|
||||||
* whenever an interface changes its state to up.
|
* whenever an interface changes its state to up. Neighbor entry VRF
|
||||||
|
* association is implied by respective protocol.
|
||||||
*
|
*
|
||||||
* When a neighbor event occurs (a neighbor gets disconnected or a sticky
|
* When a neighbor event occurs (a neighbor gets disconnected or a sticky
|
||||||
* inactive neighbor becomes connected), the protocol hook neigh_notify()
|
* inactive neighbor becomes connected), the protocol hook neigh_notify()
|
||||||
@ -153,8 +154,9 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
WALK_LIST(i, iface_list)
|
WALK_LIST(i, iface_list)
|
||||||
if ((scope = if_connected(a, i, &addr)) >= 0)
|
if ((!p->vrf || p->vrf == i->master) &&
|
||||||
{
|
((scope = if_connected(a, i, &addr)) >= 0))
|
||||||
|
{
|
||||||
ifa = i;
|
ifa = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "lib/resource.h"
|
#include "lib/resource.h"
|
||||||
#include "lib/lists.h"
|
#include "lib/lists.h"
|
||||||
#include "lib/event.h"
|
#include "lib/event.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
#include "lib/string.h"
|
#include "lib/string.h"
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
#include "nest/route.h"
|
#include "nest/route.h"
|
||||||
@ -673,6 +674,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;
|
||||||
insert_node(&p->n, n);
|
insert_node(&p->n, n);
|
||||||
|
|
||||||
p->event = ev_new(proto_pool);
|
p->event = ev_new(proto_pool);
|
||||||
@ -819,7 +821,8 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
|
|||||||
/* If there is a too big change in core attributes, ... */
|
/* If there is a too big change in core attributes, ... */
|
||||||
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))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
p->name = nc->name;
|
p->name = nc->name;
|
||||||
@ -1645,6 +1648,8 @@ proto_cmd_show(struct proto *p, uint verbose, int cnt)
|
|||||||
cli_msg(-1006, " Description: %s", p->cf->dsc);
|
cli_msg(-1006, " Description: %s", p->cf->dsc);
|
||||||
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)
|
||||||
|
cli_msg(-1006, " VRF: %s", p->vrf->name);
|
||||||
|
|
||||||
if (p->proto->show_proto_info)
|
if (p->proto->show_proto_info)
|
||||||
p->proto->show_proto_info(p);
|
p->proto->show_proto_info(p);
|
||||||
|
@ -100,6 +100,7 @@ struct proto_config {
|
|||||||
u32 router_id; /* Protocol specific router ID */
|
u32 router_id; /* Protocol specific router ID */
|
||||||
|
|
||||||
list channels; /* List of channel configs (struct channel_config) */
|
list channels; /* List of channel configs (struct channel_config) */
|
||||||
|
struct iface *vrf; /* Related VRF instance, NULL if global */
|
||||||
|
|
||||||
/* Check proto_reconfigure() and proto_copy_config() after changing struct proto_config */
|
/* Check proto_reconfigure() and proto_copy_config() after changing struct proto_config */
|
||||||
|
|
||||||
@ -142,6 +143,7 @@ struct proto {
|
|||||||
list channels; /* List of channels to rtables (struct channel) */
|
list channels; /* List of channels to rtables (struct channel) */
|
||||||
struct channel *main_channel; /* Primary channel */
|
struct channel *main_channel; /* Primary channel */
|
||||||
struct rte_src *main_source; /* Primary route source */
|
struct rte_src *main_source; /* Primary route source */
|
||||||
|
struct iface *vrf; /* Related VRF instance, NULL if global */
|
||||||
|
|
||||||
char *name; /* Name of this instance (== cf->name) */
|
char *name; /* Name of this instance (== cf->name) */
|
||||||
u32 debug; /* Debugging flags */
|
u32 debug; /* Debugging flags */
|
||||||
|
@ -32,6 +32,24 @@
|
|||||||
* Basic FIB operations are performed by functions defined by this module,
|
* Basic FIB operations are performed by functions defined by this module,
|
||||||
* enumerating of FIB contents is accomplished by using the FIB_WALK() macro
|
* enumerating of FIB contents is accomplished by using the FIB_WALK() macro
|
||||||
* or FIB_ITERATE_START() if you want to do it asynchronously.
|
* or FIB_ITERATE_START() if you want to do it asynchronously.
|
||||||
|
*
|
||||||
|
* For simple iteration just place the body of the loop between FIB_WALK() and
|
||||||
|
* FIB_WALK_END(). You can't modify the FIB during the iteration (you can modify
|
||||||
|
* data in the node, but not add or remove nodes).
|
||||||
|
*
|
||||||
|
* If you need more freedom, you can use the FIB_ITERATE_*() group of macros.
|
||||||
|
* First, you initialize an iterator with FIB_ITERATE_INIT(). Then you can put
|
||||||
|
* the loop body in between FIB_ITERATE_START() and FIB_ITERATE_END(). In
|
||||||
|
* addition, the iteration can be suspended by calling FIB_ITERATE_PUT().
|
||||||
|
* This'll link the iterator inside the FIB. While suspended, you may modify the
|
||||||
|
* FIB, exit the current function, etc. To resume the iteration, enter the loop
|
||||||
|
* again. You can use FIB_ITERATE_UNLINK() to unlink the iterator (while
|
||||||
|
* iteration is suspended) in cases like premature end of FIB iteration.
|
||||||
|
*
|
||||||
|
* Note that the iterator must not be destroyed when the iteration is suspended,
|
||||||
|
* the FIB would then contain a pointer to invalid memory. Therefore, after each
|
||||||
|
* FIB_ITERATE_INIT() or FIB_ITERATE_PUT() there must be either
|
||||||
|
* FIB_ITERATE_START() or FIB_ITERATE_UNLINK() before the iterator is destroyed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef LOCAL_DEBUG
|
#undef LOCAL_DEBUG
|
||||||
|
@ -1332,6 +1332,7 @@ babel_open_socket(struct babel_iface *ifa)
|
|||||||
sk->dport = ifa->cf->port;
|
sk->dport = ifa->cf->port;
|
||||||
sk->iface = ifa->iface;
|
sk->iface = ifa->iface;
|
||||||
sk->saddr = ifa->addr;
|
sk->saddr = ifa->addr;
|
||||||
|
sk->vrf = p->p.vrf;
|
||||||
|
|
||||||
sk->rx_hook = babel_rx_hook;
|
sk->rx_hook = babel_rx_hook;
|
||||||
sk->tx_hook = babel_tx_hook;
|
sk->tx_hook = babel_tx_hook;
|
||||||
|
@ -939,6 +939,7 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c
|
|||||||
s->daddr = p->cf->remote_ip;
|
s->daddr = p->cf->remote_ip;
|
||||||
s->dport = p->cf->remote_port;
|
s->dport = p->cf->remote_port;
|
||||||
s->iface = p->neigh ? p->neigh->iface : NULL;
|
s->iface = p->neigh ? p->neigh->iface : NULL;
|
||||||
|
s->vrf = p->p.vrf;
|
||||||
s->ttl = p->cf->ttl_security ? 255 : hops;
|
s->ttl = p->cf->ttl_security ? 255 : hops;
|
||||||
s->rbsize = p->cf->enable_extended_messages ? BGP_RX_BUFFER_EXT_SIZE : BGP_RX_BUFFER_SIZE;
|
s->rbsize = p->cf->enable_extended_messages ? BGP_RX_BUFFER_EXT_SIZE : BGP_RX_BUFFER_SIZE;
|
||||||
s->tbsize = p->cf->enable_extended_messages ? BGP_TX_BUFFER_EXT_SIZE : BGP_TX_BUFFER_SIZE;
|
s->tbsize = p->cf->enable_extended_messages ? BGP_TX_BUFFER_EXT_SIZE : BGP_TX_BUFFER_SIZE;
|
||||||
@ -1331,6 +1332,7 @@ bgp_start(struct proto *P)
|
|||||||
lock->addr = p->cf->remote_ip;
|
lock->addr = p->cf->remote_ip;
|
||||||
lock->port = p->cf->remote_port;
|
lock->port = p->cf->remote_port;
|
||||||
lock->iface = p->cf->iface;
|
lock->iface = p->cf->iface;
|
||||||
|
lock->vrf = p->cf->iface ? NULL : p->p.vrf;
|
||||||
lock->type = OBJLOCK_TCP;
|
lock->type = OBJLOCK_TCP;
|
||||||
lock->hook = bgp_start_locked;
|
lock->hook = bgp_start_locked;
|
||||||
lock->data = p;
|
lock->data = p;
|
||||||
|
@ -121,6 +121,7 @@ ospf_sk_open(struct ospf_iface *ifa)
|
|||||||
sk->dport = OSPF_PROTO;
|
sk->dport = OSPF_PROTO;
|
||||||
sk->saddr = ifa->addr->ip;
|
sk->saddr = ifa->addr->ip;
|
||||||
sk->iface = ifa->iface;
|
sk->iface = ifa->iface;
|
||||||
|
sk->vrf = p->p.vrf;
|
||||||
|
|
||||||
sk->tos = ifa->cf->tx_tos;
|
sk->tos = ifa->cf->tx_tos;
|
||||||
sk->priority = ifa->cf->tx_priority;
|
sk->priority = ifa->cf->tx_priority;
|
||||||
@ -204,6 +205,7 @@ ospf_open_vlink_sk(struct ospf_proto *p)
|
|||||||
sk->type = SK_IP;
|
sk->type = SK_IP;
|
||||||
sk->subtype = ospf_is_v2(p) ? SK_IPV4 : SK_IPV6;
|
sk->subtype = ospf_is_v2(p) ? SK_IPV4 : SK_IPV6;
|
||||||
sk->dport = OSPF_PROTO;
|
sk->dport = OSPF_PROTO;
|
||||||
|
sk->vrf = p->p.vrf;
|
||||||
|
|
||||||
/* FIXME: configurable tos/priority ? */
|
/* FIXME: configurable tos/priority ? */
|
||||||
sk->tos = IP_PREC_INTERNET_CONTROL;
|
sk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
|
@ -387,6 +387,7 @@ radv_sk_open(struct radv_iface *ifa)
|
|||||||
sk->subtype = SK_IPV6;
|
sk->subtype = SK_IPV6;
|
||||||
sk->dport = ICMPV6_PROTO;
|
sk->dport = ICMPV6_PROTO;
|
||||||
sk->saddr = ifa->addr->ip;
|
sk->saddr = ifa->addr->ip;
|
||||||
|
sk->vrf = ifa->ra->p.vrf;
|
||||||
|
|
||||||
sk->ttl = 255; /* Mandatory for Neighbor Discovery packets */
|
sk->ttl = 255; /* Mandatory for Neighbor Discovery packets */
|
||||||
sk->rx_hook = radv_rx_hook;
|
sk->rx_hook = radv_rx_hook;
|
||||||
|
@ -297,7 +297,6 @@ radv_iface_new(struct radv_proto *p, struct iface *iface, struct radv_iface_conf
|
|||||||
ifa->timer = tm_new_init(pool, radv_timer, ifa, 0, 0);
|
ifa->timer = tm_new_init(pool, radv_timer, ifa, 0, 0);
|
||||||
|
|
||||||
struct object_lock *lock = olock_new(pool);
|
struct object_lock *lock = olock_new(pool);
|
||||||
lock->addr = IPA_NONE;
|
|
||||||
lock->type = OBJLOCK_IP;
|
lock->type = OBJLOCK_IP;
|
||||||
lock->port = ICMPV6_PROTO;
|
lock->port = ICMPV6_PROTO;
|
||||||
lock->iface = iface;
|
lock->iface = iface;
|
||||||
|
@ -747,6 +747,7 @@ rip_open_socket(struct rip_iface *ifa)
|
|||||||
sk->dport = ifa->cf->port;
|
sk->dport = ifa->cf->port;
|
||||||
sk->iface = ifa->iface;
|
sk->iface = ifa->iface;
|
||||||
sk->saddr = rip_is_v2(p) ? ifa->iface->addr4->ip : ifa->iface->llv6->ip;
|
sk->saddr = rip_is_v2(p) ? ifa->iface->addr4->ip : ifa->iface->llv6->ip;
|
||||||
|
sk->vrf = p->p.vrf;
|
||||||
|
|
||||||
sk->rx_hook = rip_rx_hook;
|
sk->rx_hook = rip_rx_hook;
|
||||||
sk->tx_hook = rip_tx_hook;
|
sk->tx_hook = rip_tx_hook;
|
||||||
|
@ -324,6 +324,7 @@ struct nl_want_attrs {
|
|||||||
static struct nl_want_attrs ifla_attr_want[BIRD_IFLA_MAX] = {
|
static struct nl_want_attrs ifla_attr_want[BIRD_IFLA_MAX] = {
|
||||||
[IFLA_IFNAME] = { 1, 0, 0 },
|
[IFLA_IFNAME] = { 1, 0, 0 },
|
||||||
[IFLA_MTU] = { 1, 1, sizeof(u32) },
|
[IFLA_MTU] = { 1, 1, sizeof(u32) },
|
||||||
|
[IFLA_MASTER] = { 1, 1, sizeof(u32) },
|
||||||
[IFLA_WIRELESS] = { 1, 0, 0 },
|
[IFLA_WIRELESS] = { 1, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -790,7 +791,7 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
|||||||
struct iface f = {};
|
struct iface f = {};
|
||||||
struct iface *ifi;
|
struct iface *ifi;
|
||||||
char *name;
|
char *name;
|
||||||
u32 mtu;
|
u32 mtu, master = 0;
|
||||||
uint fl;
|
uint fl;
|
||||||
|
|
||||||
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFLA_RTA(i), ifla_attr_want, a, sizeof(a)))
|
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFLA_RTA(i), ifla_attr_want, a, sizeof(a)))
|
||||||
@ -813,6 +814,9 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
|||||||
name = RTA_DATA(a[IFLA_IFNAME]);
|
name = RTA_DATA(a[IFLA_IFNAME]);
|
||||||
mtu = rta_get_u32(a[IFLA_MTU]);
|
mtu = rta_get_u32(a[IFLA_MTU]);
|
||||||
|
|
||||||
|
if (a[IFLA_MASTER])
|
||||||
|
master = rta_get_u32(a[IFLA_MASTER]);
|
||||||
|
|
||||||
ifi = if_find_by_index(i->ifi_index);
|
ifi = if_find_by_index(i->ifi_index);
|
||||||
if (!new)
|
if (!new)
|
||||||
{
|
{
|
||||||
@ -832,6 +836,9 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
|||||||
f.index = i->ifi_index;
|
f.index = i->ifi_index;
|
||||||
f.mtu = mtu;
|
f.mtu = mtu;
|
||||||
|
|
||||||
|
f.master_index = master;
|
||||||
|
f.master = if_find_by_index(master);
|
||||||
|
|
||||||
fl = i->ifi_flags;
|
fl = i->ifi_flags;
|
||||||
if (fl & IFF_UP)
|
if (fl & IFF_UP)
|
||||||
f.flags |= IF_ADMIN_UP;
|
f.flags |= IF_ADMIN_UP;
|
||||||
@ -1091,6 +1098,26 @@ kif_do_scan(struct kif_proto *p UNUSED)
|
|||||||
else
|
else
|
||||||
log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
|
log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
|
||||||
|
|
||||||
|
/* Re-resolve master interface for slaves */
|
||||||
|
struct iface *i;
|
||||||
|
WALK_LIST(i, iface_list)
|
||||||
|
if (i->master_index)
|
||||||
|
{
|
||||||
|
struct iface f = {
|
||||||
|
.flags = i->flags,
|
||||||
|
.mtu = i->mtu,
|
||||||
|
.index = i->index,
|
||||||
|
.master_index = i->master_index,
|
||||||
|
.master = if_find_by_index(i->master_index)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (f.master != i->master)
|
||||||
|
{
|
||||||
|
memcpy(f.name, i->name, sizeof(f.name));
|
||||||
|
if_update(&f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nl_request_dump(AF_INET, RTM_GETADDR);
|
nl_request_dump(AF_INET, RTM_GETADDR);
|
||||||
while (h = nl_get_scan())
|
while (h = nl_get_scan())
|
||||||
if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
|
if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
|
||||||
|
@ -931,6 +931,18 @@ sk_setup(sock *s)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (s->vrf && !s->iface)
|
||||||
|
{
|
||||||
|
/* Bind socket to associated VRF interface.
|
||||||
|
This is Linux-specific, but so is SO_BINDTODEVICE. */
|
||||||
|
#ifdef SO_BINDTODEVICE
|
||||||
|
struct ifreq ifr = {};
|
||||||
|
strcpy(ifr.ifr_name, s->vrf->name);
|
||||||
|
if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0)
|
||||||
|
ERR("SO_BINDTODEVICE");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (s->iface)
|
if (s->iface)
|
||||||
{
|
{
|
||||||
#ifdef SO_BINDTODEVICE
|
#ifdef SO_BINDTODEVICE
|
||||||
|
Loading…
Reference in New Issue
Block a user