for (afi = AFI_IP; afi < AFI_MAX; afi++) \
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+#define FOREACH_SAFI(safi) \
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+
/* BGP master for system wide configurations and variables. */
struct bgp_master {
/* BGP instance list. */
#define BGP_CONFIG_VRF_TO_VRF_EXPORT (1 << 8)
#define BGP_DEFAULT_NAME "default"
+ /* BGP per AF peer count */
+ uint32_t af_peer_count[AFI_MAX][SAFI_MAX];
+
/* Route table for next-hop lookup cache. */
struct bgp_table *nexthop_cache_table[AFI_MAX];
#define BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE 1
-/* BGP router distinguisher value. */
-#define BGP_RD_SIZE 8
-
-struct bgp_rd {
- uint8_t val[BGP_RD_SIZE];
-};
-
+/* Route map direction */
#define RMAP_IN 0
#define RMAP_OUT 1
#define RMAP_MAX 2
#define PEER_CAP_ENHE_AF_NEGO (1 << 14) /* Extended nexthop afi/safi negotiated */
/* Global configuration flags. */
+ /*
+ * Parallel array to flags that indicates whether each flag originates
+ * from a peer-group or if it is config that is specific to this
+ * individual peer. If a flag is set independent of the peer-group, the
+ * same bit should be set here. If this peer is a peer-group, this
+ * memory region should be all zeros.
+ *
+ * The assumption is that the default state for all flags is unset,
+ * so if a flag is unset, the corresponding override flag is unset too.
+ * However if a flag is set, the corresponding override flag is set.
+ */
+ uint32_t flags_override;
+ /*
+ * Parallel array to flags that indicates whether the default behavior
+ * of *flags_override* should be inverted. If a flag is unset and the
+ * corresponding invert flag is set, the corresponding override flag
+ * would be set. However if a flag is set and the corresponding invert
+ * flag is unset, the corresponding override flag would be unset.
+ *
+ * This can be used for attributes like *send-community*, which are
+ * implicitely enabled and have to be disabled explicitely, compared to
+ * 'normal' attributes like *next-hop-self* which are implicitely set.
+ *
+ * All operations dealing with flags should apply the following boolean
+ * logic to keep the internal flag system in a sane state:
+ *
+ * value=0 invert=0 Inherit flag if member, otherwise unset flag
+ * value=0 invert=1 Unset flag unconditionally
+ * value=1 invert=0 Set flag unconditionally
+ * value=1 invert=1 Inherit flag if member, otherwise set flag
+ *
+ * Contrary to the implementation of *flags_override*, the flag
+ * inversion state can be set either on the peer OR the peer *and* the
+ * peer-group. This was done on purpose, as the inversion state of a
+ * flag can be determined on either the peer or the peer-group.
+ *
+ * Example: Enabling the cisco configuration mode inverts all flags
+ * related to *send-community* unconditionally for both peer-groups and
+ * peers.
+ *
+ * This behavior is different for interface peers though, which enable
+ * the *extended-nexthop* flag by default, which regular peers do not.
+ * As the peer-group can contain both regular and interface peers, the
+ * flag inversion state must be set on the peer only.
+ *
+ * When a peer inherits the configuration from a peer-group and the
+ * inversion state of the flag differs between peer and peer-group, the
+ * newly set value must equal to the inverted state of the peer-group.
+ */
+ uint32_t flags_invert;
+ /*
+ * Effective array for storing the peer/peer-group flags. In case of a
+ * peer-group, the peer-specific overrides (see flags_override and
+ * flags_invert) must be respected.
+ */
uint32_t flags;
#define PEER_FLAG_PASSIVE (1 << 0) /* passive mode */
#define PEER_FLAG_SHUTDOWN (1 << 1) /* shutdown */
#define PEER_FLAG_IFPEER_V6ONLY (1 << 14) /* if-based peer is v6 only */
#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */
#define PEER_FLAG_ENFORCE_FIRST_AS (1 << 16) /* enforce-first-as */
+#define PEER_FLAG_ROUTEADV (1 << 17) /* route advertise */
+#define PEER_FLAG_TIMER (1 << 18) /* keepalive & holdtime */
+#define PEER_FLAG_TIMER_CONNECT (1 << 19) /* connect timer */
+#define PEER_FLAG_PASSWORD (1 << 20) /* password */
+#define PEER_FLAG_LOCAL_AS (1 << 21) /* local-as */
+#define PEER_FLAG_UPDATE_SOURCE (1 << 22) /* update-source */
/* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */
char *tx_shutdown_message;
/* Peer Per AF flags */
/*
- * Parallel array to af_flags that indicates whether each flag
- * originates from a peer-group or if it is config that is specific to
- * this individual peer. If a flag is set independent of the
- * peer-group the same bit should be set here. If this peer is a
- * peer-group, this memory region should be all zeros. The assumption
- * is that the default state for all flags is unset.
- *
- * Notes:
- * - if a flag for an individual peer is unset, the corresponding
- * override flag is unset and the peer is considered to be back in
- * sync with the peer-group.
- * - This does *not* contain the flag values, rather it contains
- * whether the flag at the same position in af_flags is
- * *peer-specific*.
+ * Please consult the comments for *flags_override*, *flags_invert* and
+ * *flags* to understand what these three arrays do. The address-family
+ * specific attributes are being treated the exact same way as global
+ * peer attributes.
*/
uint32_t af_flags_override[AFI_MAX][SAFI_MAX];
- /*
- * Parallel array to af_flags that indicates whether each flag should
- * be treated as regular (defaults to 0) or inverted (defaults to 1).
- * If a flag is set to 1 by default, the same bit should be set here.
- *
- * Notes:
- * - This does *not* contain the flag values, rather it contains
- * whether the flag at the same position in af_flags is *regular* or
- * *inverted*.
- */
uint32_t af_flags_invert[AFI_MAX][SAFI_MAX];
- /*
- * Effective flags, computed by applying peer-group flags and then
- * overriding with individual flags
- */
uint32_t af_flags[AFI_MAX][SAFI_MAX];
#define PEER_FLAG_SEND_COMMUNITY (1 << 0) /* send-community */
#define PEER_FLAG_SEND_EXT_COMMUNITY (1 << 1) /* send-community ext. */
#define PEER_STATUS_EOR_SEND (1 << 4) /* end-of-rib send to peer */
#define PEER_STATUS_EOR_RECEIVED (1 << 5) /* end-of-rib received from peer */
- /* Default attribute value for the peer. */
- uint32_t config;
-#define PEER_CONFIG_TIMER (1 << 0) /* keepalive & holdtime */
-#define PEER_CONFIG_CONNECT (1 << 1) /* connect */
-#define PEER_CONFIG_ROUTEADV (1 << 2) /* route advertise */
-#define PEER_GROUP_CONFIG_TIMER (1 << 3) /* timers from peer-group */
-
-#define PEER_OR_GROUP_TIMER_SET(peer) \
- (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER) \
- || CHECK_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER))
-
+ /* Configured timer values. */
_Atomic uint32_t holdtime;
_Atomic uint32_t keepalive;
_Atomic uint32_t connect;
DECLARE_QOBJ_TYPE(peer)
/* Inherit peer attribute from peer-group. */
-#define PEER_ATTR_INHERIT(peer, attr) ((peer)->attr = (peer)->group->conf->attr)
-#define PEER_STR_ATTR_INHERIT(mt, peer, attr) \
+#define PEER_ATTR_INHERIT(peer, group, attr) \
+ ((peer)->attr = (group)->conf->attr)
+#define PEER_STR_ATTR_INHERIT(peer, group, attr, mt) \
do { \
if ((peer)->attr) \
XFREE(mt, (peer)->attr); \
- if ((peer)->group->conf->attr) \
- (peer)->attr = XSTRDUP(mt, (peer)->group->conf->attr); \
+ if ((group)->conf->attr) \
+ (peer)->attr = XSTRDUP(mt, (group)->conf->attr); \
+ else \
+ (peer)->attr = NULL; \
+ } while (0)
+#define PEER_SU_ATTR_INHERIT(peer, group, attr) \
+ do { \
+ if ((peer)->attr) \
+ sockunion_free((peer)->attr); \
+ if ((group)->conf->attr) \
+ (peer)->attr = sockunion_dup((group)->conf->attr); \
else \
(peer)->attr = NULL; \
} while (0)
#define BGP_ATTR_ENCAP 23
#define BGP_ATTR_LARGE_COMMUNITIES 32
#define BGP_ATTR_PREFIX_SID 40
-#if ENABLE_BGP_VNC
+#if ENABLE_BGP_VNC_ATTR
#define BGP_ATTR_VNC 255
#endif
extern void bgp_reset(void);
extern time_t bgp_clock(void);
extern void bgp_zclient_reset(void);
-extern int bgp_nexthop_set(union sockunion *, union sockunion *,
- struct bgp_nexthop *, struct peer *);
extern struct bgp *bgp_get_default(void);
extern struct bgp *bgp_lookup(as_t, const char *);
extern struct bgp *bgp_lookup_by_name(const char *);
extern void bgp_master_init(struct thread_master *master);
-extern void bgp_init(void);
+extern void bgp_init(unsigned short instance);
extern void bgp_pthreads_run(void);
extern void bgp_pthreads_finish(void);
extern void bgp_route_map_init(void);
extern int peer_group_bind(struct bgp *, union sockunion *, struct peer *,
struct peer_group *, as_t *);
-extern int peer_group_unbind(struct bgp *, struct peer *, struct peer_group *);
extern int peer_flag_set(struct peer *, uint32_t);
extern int peer_flag_unset(struct peer *, uint32_t);
+extern void peer_flag_inherit(struct peer *peer, uint32_t flag);
extern int peer_af_flag_set(struct peer *, afi_t, safi_t, uint32_t);
extern int peer_af_flag_unset(struct peer *, afi_t, safi_t, uint32_t);