diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2022-08-30 21:25:50 +0300 | 
|---|---|---|
| committer | Donatas Abraitis <donatas@opensourcerouting.org> | 2022-09-04 21:23:59 +0300 | 
| commit | 7b27cf7bbdf24521ddb780298d998a167226c684 (patch) | |
| tree | 19507be6456400894b988e806cfa024d4a57b9a1 /bgpd/bgp_ecommunity.c | |
| parent | 4880f5fa16ac542e07a134bb599e67c32bee9e79 (diff) | |
bgpd: Add Origin Validation State extended community
```
spine1-debian-11# sh ip bgp 100.100.100.101/32
BGP routing table entry for 100.100.100.101/32, version 21
Paths: (1 available, best #1, table default)
  Not advertised to any peer
  Local
    fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
    (fe80::ca5d:fd0d:cd8:1bb7) (used)
      Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
      Extended Community: OVS:invalid
      Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11# sh ip bgp 100.100.100.100/32
BGP routing table entry for 100.100.100.100/32, version 17
Paths: (1 available, best #1, table default)
  Not advertised to any peer
  Local
    fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
    (fe80::ca5d:fd0d:cd8:1bb7) (used)
      Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
      Extended Community: OVS:not-found
      Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11#
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_ecommunity.c')
| -rw-r--r-- | bgpd/bgp_ecommunity.c | 70 | 
1 files changed, 70 insertions, 0 deletions
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 3f627521e7..f57e9ae88b 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -394,6 +394,44 @@ enum ecommunity_token {  	ecommunity_token_val6,  }; +static const char *ecommunity_origin_validation_state2str( +	enum ecommunity_origin_validation_states state) +{ +	switch (state) { +	case ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID: +		return "valid"; +	case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND: +		return "not-found"; +	case ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID: +		return "invalid"; +	case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED: +		return "not-used"; +	} + +	return "ERROR"; +} + +static void ecommunity_origin_validation_state_str(char *buf, size_t bufsz, +						   uint8_t *ptr) +{ +	/* Origin Validation State is encoded in the last octet +	 * +	 * 0                   1                   2                   3 +	 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +	 * |       0x43    |      0x00     |             Reserved          | +	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +	 * |                    Reserved                   |validationstate| +	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +	 */ +	uint8_t state = *(ptr + ECOMMUNITY_SIZE - 3); + +	snprintf(buf, bufsz, "OVS:%s", +		 ecommunity_origin_validation_state2str(state)); + +	(void)ptr; /* consume value */ +} +  static int ecommunity_encode_internal(uint8_t type, uint8_t sub_type,  				      int trans, as_t as,  				      struct in_addr *ip, @@ -1172,6 +1210,13 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)  						  ecom->disable_ieee_floating);  			else  				unk_ecom = 1; +		} else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) { +			sub_type = *pnt++; +			if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE) +				ecommunity_origin_validation_state_str( +					encbuf, sizeof(encbuf), pnt); +			else +				unk_ecom = 1;  		} else {  			sub_type = *pnt++;  			unk_ecom = 1; @@ -1541,6 +1586,31 @@ void bgp_remove_ecomm_from_aggregate_hash(struct bgp_aggregate *aggregate,  	}  } +struct ecommunity * +ecommunity_add_origin_validation_state(enum rpki_states rpki_state, +				       struct ecommunity *old) +{ +	struct ecommunity *new = NULL; +	struct ecommunity ovs_ecomm = {0}; +	struct ecommunity_val ovs_eval; + +	encode_origin_validation_state(rpki_state, &ovs_eval); + +	if (old) { +		new = ecommunity_dup(old); +		ecommunity_add_val(new, &ovs_eval, true, true); +		if (!old->refcnt) +			ecommunity_free(&old); +	} else { +		ovs_ecomm.size = 1; +		ovs_ecomm.unit_size = ECOMMUNITY_SIZE; +		ovs_ecomm.val = (uint8_t *)&ovs_eval.val; +		new = ecommunity_dup(&ovs_ecomm); +	} + +	return new; +} +  /*   * return the BGP link bandwidth extended community, if present;   * the actual bandwidth is returned via param  | 
