struct update_subgroup;
struct bpacket;
+struct bgp_pbr_config;
/*
* Allow the neighbor XXXX remote-as to take internal or external
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];
struct vpn_policy vpn_policy[AFI_MAX];
+ struct bgp_pbr_config *bgp_pbr_cfg;
+
+ /* local esi hash table */
+ struct hash *esihash;
+
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(bgp)
#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_DISABLE_CONNECTED_CHECK (1 << 6) /* disable-connected-check */
#define PEER_FLAG_LOCAL_AS_NO_PREPEND (1 << 7) /* local-as no-prepend */
#define PEER_FLAG_LOCAL_AS_REPLACE_AS (1 << 8) /* local-as no-prepend replace-as */
-#define PEER_FLAG_DELETE (1 << 9) /* mark the peer for deleting */
-#define PEER_FLAG_CONFIG_NODE (1 << 10) /* the node to update configs on */
+#define PEER_FLAG_DELETE (1 << 9) /* mark the peer for deleting */
+#define PEER_FLAG_CONFIG_NODE (1 << 10) /* the node to update configs on */
#define PEER_FLAG_LONESOUL (1 << 11)
#define PEER_FLAG_DYNAMIC_NEIGHBOR (1 << 12) /* dynamic neighbor */
#define PEER_FLAG_CAPABILITY_ENHE (1 << 13) /* Extended next-hop (rfc 5549)*/
#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_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];
- /*
- * Effective flags, computed by applying peer-group flags and then
- * overriding with individual flags
- */
+ uint32_t af_flags_invert[AFI_MAX][SAFI_MAX];
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;
/* Filter structure. */
struct bgp_filter filter[AFI_MAX][SAFI_MAX];
+ /*
+ * Parallel array to filter that indicates whether each filter
+ * originates from a peer-group or if it is config that is specific to
+ * this individual peer. If a filter is set independent of the
+ * peer-group the appropriate 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. Due to filters
+ * having a direction (e.g. in/out/...), this array has a third
+ * dimension for storing the overrides independently per direction.
+ *
+ * Notes:
+ * - if a filter 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 filter values, rather it contains
+ * whether the filter in filter (struct bgp_filter) is peer-specific.
+ */
+ uint8_t filter_override[AFI_MAX][SAFI_MAX][(FILTER_MAX > RMAP_MAX)
+ ? FILTER_MAX
+ : RMAP_MAX];
+#define PEER_FT_DISTRIBUTE_LIST (1 << 0) /* distribute-list */
+#define PEER_FT_FILTER_LIST (1 << 1) /* filter-list */
+#define PEER_FT_PREFIX_LIST (1 << 2) /* prefix-list */
+#define PEER_FT_ROUTE_MAP (1 << 3) /* route-map */
+#define PEER_FT_UNSUPPRESS_MAP (1 << 4) /* unsuppress-map */
+
/* ORF Prefix-list */
struct prefix_list *orf_plist[AFI_MAX][SAFI_MAX];
};
DECLARE_QOBJ_TYPE(peer)
+/* Inherit peer attribute from peer-group. */
+#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 ((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)
+
/* Check if suppress start/restart of sessions to peer. */
#define BGP_PEER_START_SUPPRESSED(P) \
(CHECK_FLAG((P)->flags, PEER_FLAG_SHUTDOWN) \
#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 *);
struct prefix **);
extern struct peer *peer_lookup_dynamic_neighbor(struct bgp *,
union sockunion *);
-extern void peer_drop_dynamic_neighbor(struct peer *);
/*
* Peers are incredibly easy to memory leak
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);
extern int peer_af_flag_check(struct peer *, afi_t, safi_t, uint32_t);
+extern void peer_af_flag_inherit(struct peer *peer, afi_t afi, safi_t safi,
+ uint32_t flag);
extern int peer_ebgp_multihop_set(struct peer *, int);
extern int peer_ebgp_multihop_unset(struct peer *);