frr/bgpd/bgp_community.h

125 lines
4.6 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/* Community attribute related functions.
* Copyright (C) 1998 Kunihiro Ishiguro
*/
#ifndef _QUAGGA_BGP_COMMUNITY_H
#define _QUAGGA_BGP_COMMUNITY_H
#include "lib/json.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
/* Communities attribute. */
struct community {
/* Reference count of communities value. */
unsigned long refcnt;
/* Communities value size. */
int size;
/* Communities value. */
uint32_t *val;
/* Communities as a json object */
json_object *json;
/* String of community attribute. This sring is used by vty output
and expanded community-list for regular expression match. */
char *str;
};
/* Well-known communities value. */
#define COMMUNITY_INTERNET 0x0
#define COMMUNITY_GSHUT 0xFFFF0000
#define COMMUNITY_ACCEPT_OWN 0xFFFF0001
#define COMMUNITY_ROUTE_FILTER_TRANSLATED_v4 0xFFFF0002
#define COMMUNITY_ROUTE_FILTER_v4 0xFFFF0003
#define COMMUNITY_ROUTE_FILTER_TRANSLATED_v6 0xFFFF0004
#define COMMUNITY_ROUTE_FILTER_v6 0xFFFF0005
#define COMMUNITY_LLGR_STALE 0xFFFF0006
#define COMMUNITY_NO_LLGR 0xFFFF0007
#define COMMUNITY_ACCEPT_OWN_NEXTHOP 0xFFFF0008
#define COMMUNITY_BLACKHOLE 0xFFFF029A
#define COMMUNITY_NO_EXPORT 0xFFFFFF01
#define COMMUNITY_NO_ADVERTISE 0xFFFFFF02
#define COMMUNITY_NO_EXPORT_SUBCONFED 0xFFFFFF03
#define COMMUNITY_LOCAL_AS 0xFFFFFF03
#define COMMUNITY_NO_PEER 0xFFFFFF04
#define COMMUNITY_SIZE 4
/* Macros of community attribute. */
#define com_length(X) ((X)->size * COMMUNITY_SIZE)
#define com_lastval(X) ((X)->val + (X)->size - 1)
#define com_nthval(X,n) ((X)->val + (n))
/* Prototypes of communities attribute functions. */
extern void community_init(void);
extern void community_finish(void);
extern void community_free(struct community **comm);
extern struct community *community_uniq_sort(struct community *com);
extern struct community *community_parse(uint32_t *pnt, unsigned short length);
extern struct community *community_intern(struct community *com);
extern void community_unintern(struct community **com);
extern char *community_str(struct community *com, bool make_json,
bool translate_alias);
extern unsigned int community_hash_make(const struct community *com);
extern struct community *community_str2com(const char *str);
extern bool community_match(const struct community *com1,
const struct community *com2);
extern bool community_cmp(const struct community *c1,
const struct community *c2);
extern struct community *community_merge(struct community *com1,
struct community *com2);
extern struct community *community_delete(struct community *com1,
struct community *com2);
extern struct community *community_dup(struct community *com);
extern bool community_include(struct community *com, uint32_t val);
extern void community_add_val(struct community *com, uint32_t val);
extern void community_del_val(struct community *com, uint32_t *val);
extern unsigned long community_count(void);
extern struct hash *community_hash(void);
extern uint32_t community_val_get(struct community *com, int i);
extern void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
struct community *community);
extern void bgp_compute_aggregate_community_val(
struct bgp_aggregate *aggregate);
extern void bgp_compute_aggregate_community_hash(
struct bgp_aggregate *aggregate,
struct community *community);
extern void bgp_remove_community_from_aggregate(struct bgp_aggregate *aggregate,
struct community *community);
extern void bgp_remove_comm_from_aggregate_hash(struct bgp_aggregate *aggregate,
struct community *community);
extern void bgp_aggr_community_remove(void *arg);
/* This implies that when propagating routes into a VRF, the ACCEPT_OWN
* community SHOULD NOT be propagated.
*/
static inline void community_strip_accept_own(struct attr *attr)
{
struct community *old_com = bgp_attr_get_community(attr);
struct community *new_com = NULL;
uint32_t val = COMMUNITY_ACCEPT_OWN;
if (old_com && community_include(old_com, val)) {
new_com = community_dup(old_com);
val = htonl(val);
community_del_val(new_com, &val);
if (!old_com->refcnt)
community_free(&old_com);
if (!new_com->size) {
community_free(&new_com);
bgp_attr_set_community(attr, NULL);
} else {
bgp_attr_set_community(attr, new_com);
}
}
}
#endif /* _QUAGGA_BGP_COMMUNITY_H */