0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Nest: Ethernet net type - preliminary support

This commit is contained in:
Ondrej Zajicek 2023-10-25 19:16:40 +02:00
parent 2f4f790a16
commit b5c040d0cf
5 changed files with 91 additions and 12 deletions

View File

@ -121,7 +121,7 @@ CF_DECLS
%type <time> expr_us time
%type <a> ipa
%type <net> net_ip4_ net_ip4 net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
%type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ net_ip6_sadr_ net_mpls_
%type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ net_ip6_sadr_ net_eth_ net_mpls_
%type <net_ptr> net_evpn_ net_evpn_ead_ net_evpn_mac_ net_evpn_mac_ip_ net_evpn_imet_ net_evpn_es_
%type <mls> label_stack_start label_stack
%type <esi> evpn_esi
@ -143,7 +143,7 @@ CF_DECLS
%start config
CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, MPLS, FROM, MAX, AS)
CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, ETH, VLAN, MPLS, FROM, MAX, AS)
CF_KEYWORDS(EVPN, EAD, MAC, IMET, ES)
CF_GRAMMAR
@ -299,6 +299,18 @@ net_roa6_: net_ip6_ MAX NUM AS NUM
cf_error("Invalid max prefix length %u", $3);
};
net_eth_: ETH MAC_
{
$$ = cfg_alloc(sizeof(net_addr_eth));
net_fill_eth($$, $2, 0);
}
net_eth_: ETH MAC_ VLAN NUM
{
$$ = cfg_alloc(sizeof(net_addr_eth));
net_fill_eth($$, $2, $4);
}
net_mpls_: MPLS NUM
{
$$ = cfg_alloc(sizeof(net_addr_mpls));
@ -355,6 +367,7 @@ net_:
| net_roa_
| net_flow_
| net_ip6_sadr_
| net_eth_
| net_mpls_
| net_evpn_
;

View File

@ -15,6 +15,7 @@ const char * const net_label[] = {
[NET_FLOW4] = "flow4",
[NET_FLOW6] = "flow6",
[NET_IP6_SADR]= "ipv6-sadr",
[NET_ETH] = "eth",
[NET_MPLS] = "mpls",
[NET_EVPN] = "evpn",
};
@ -29,6 +30,7 @@ const u16 net_addr_length[] = {
[NET_FLOW4] = 0,
[NET_FLOW6] = 0,
[NET_IP6_SADR]= sizeof(net_addr_ip6_sadr),
[NET_ETH] = sizeof(net_addr_eth),
[NET_MPLS] = sizeof(net_addr_mpls),
[NET_EVPN] = 0,
};
@ -43,6 +45,7 @@ const u8 net_max_prefix_length[] = {
[NET_FLOW4] = IP4_MAX_PREFIX_LENGTH,
[NET_FLOW6] = IP6_MAX_PREFIX_LENGTH,
[NET_IP6_SADR]= IP6_MAX_PREFIX_LENGTH,
[NET_ETH] = 0,
[NET_MPLS] = 0,
[NET_EVPN] = 0,
};
@ -57,6 +60,7 @@ const u16 net_max_text_length[] = {
[NET_FLOW4] = 0, /* "flow4 { ... }" */
[NET_FLOW6] = 0, /* "flow6 { ... }" */
[NET_IP6_SADR]= 92, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128 from ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
[NET_ETH] = 28, /* "11:22:33:44:55:66 vlan 65535" */
[NET_MPLS] = 7, /* "1048575" */
[NET_EVPN] = 0,
};
@ -72,6 +76,7 @@ STATIC_ASSERT(sizeof(net_addr_roa6) == 28);
STATIC_ASSERT(sizeof(net_addr_flow4) == 8);
STATIC_ASSERT(sizeof(net_addr_flow6) == 20);
STATIC_ASSERT(sizeof(net_addr_ip6_sadr) == 40);
STATIC_ASSERT(sizeof(net_addr_eth) == 12);
STATIC_ASSERT(sizeof(net_addr_mpls) == 8);
STATIC_ASSERT(sizeof(net_addr_evpn_ead) == 32);
@ -132,6 +137,16 @@ net_format(const net_addr *N, char *buf, int buflen)
return flow6_net_format(buf, buflen, &n->flow6);
case NET_IP6_SADR:
return bsnprintf(buf, buflen, "%I6/%d from %I6/%d", n->ip6_sadr.dst_prefix, n->ip6_sadr.dst_pxlen, n->ip6_sadr.src_prefix, n->ip6_sadr.src_pxlen);
case NET_ETH:
{
int c = bsnprintf(buf, buflen, "%6b", &n->eth.mac);
ADVANCE(buf, buflen, c);
if (n->eth.vid)
c += bsnprintf(buf, buflen, " vlan %d", (int) n->eth.vid);
return c;
}
case NET_MPLS:
return bsnprintf(buf, buflen, "%u", n->mpls.label);
case NET_EVPN:
@ -159,6 +174,7 @@ net_pxmask(const net_addr *a)
case NET_IP6_SADR:
return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
case NET_ETH:
case NET_MPLS:
case NET_EVPN:
default:
@ -192,6 +208,8 @@ net_compare(const net_addr *a, const net_addr *b)
return net_compare_flow6((const net_addr_flow6 *) a, (const net_addr_flow6 *) b);
case NET_IP6_SADR:
return net_compare_ip6_sadr((const net_addr_ip6_sadr *) a, (const net_addr_ip6_sadr *) b);
case NET_ETH:
return net_compare_eth((const net_addr_eth *) a, (const net_addr_eth *) b);
case NET_MPLS:
return net_compare_mpls((const net_addr_mpls *) a, (const net_addr_mpls *) b);
case NET_EVPN:
@ -216,6 +234,7 @@ net_hash(const net_addr *n)
case NET_FLOW4: return NET_HASH(n, flow4);
case NET_FLOW6: return NET_HASH(n, flow6);
case NET_IP6_SADR: return NET_HASH(n, ip6_sadr);
case NET_ETH: return NET_HASH(n, eth);
case NET_MPLS: return NET_HASH(n, mpls);
case NET_EVPN: return NET_HASH(n, evpn);
default: bug("invalid type");
@ -239,6 +258,7 @@ net_validate(const net_addr *n)
case NET_FLOW4: return NET_VALIDATE(n, flow4);
case NET_FLOW6: return NET_VALIDATE(n, flow6);
case NET_IP6_SADR: return NET_VALIDATE(n, ip6_sadr);
case NET_ETH: return NET_VALIDATE(n, eth);
case NET_MPLS: return NET_VALIDATE(n, mpls);
case NET_EVPN: return NET_VALIDATE(n, evpn);
default: return 0;
@ -267,6 +287,7 @@ net_normalize(net_addr *N)
case NET_IP6_SADR:
return net_normalize_ip6_sadr(&n->ip6_sadr);
case NET_ETH:
case NET_MPLS:
case NET_EVPN:
return;
@ -295,6 +316,7 @@ net_classify(const net_addr *N)
case NET_IP6_SADR:
return ip6_zero(n->ip6_sadr.dst_prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6_sadr.dst_prefix);
case NET_ETH:
case NET_MPLS:
case NET_EVPN: /* ?? */
return IADDR_HOST | SCOPE_UNIVERSE;
@ -329,6 +351,7 @@ ipa_in_netX(const ip_addr a, const net_addr *n)
return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)),
ip6_mkmask(net6_pxlen(n))));
case NET_ETH:
case NET_MPLS:
case NET_EVPN:
default:

View File

@ -24,9 +24,10 @@
#define NET_FLOW4 7
#define NET_FLOW6 8
#define NET_IP6_SADR 9
#define NET_MPLS 10
#define NET_EVPN 11
#define NET_MAX 12
#define NET_ETH 10
#define NET_MPLS 11
#define NET_EVPN 12
#define NET_MAX 13
#define NB_IP4 (1 << NET_IP4)
#define NB_IP6 (1 << NET_IP6)
@ -37,6 +38,7 @@
#define NB_FLOW4 (1 << NET_FLOW4)
#define NB_FLOW6 (1 << NET_FLOW6)
#define NB_IP6_SADR (1 << NET_IP6_SADR)
#define NB_ETH (1 << NET_ETH)
#define NB_MPLS (1 << NET_MPLS)
#define NB_EVPN (1 << NET_EVPN)
@ -44,7 +46,7 @@
#define NB_VPN (NB_VPN4 | NB_VPN6)
#define NB_ROA (NB_ROA4 | NB_ROA6)
#define NB_FLOW (NB_FLOW4 | NB_FLOW6)
#define NB_DEST (NB_IP | NB_IP6_SADR | NB_VPN | NB_MPLS | NB_EVPN)
#define NB_DEST (NB_IP | NB_IP6_SADR | NB_VPN | NB_ETH | NB_MPLS | NB_EVPN)
#define NB_ANY 0xffffffff
@ -121,6 +123,14 @@ typedef struct net_addr_flow6 {
byte data[0];
} net_addr_flow6;
typedef struct net_addr_eth {
u8 type;
u8 pxlen;
u16 length;
mac_addr mac;
u16 vid;
} net_addr_eth;
typedef struct net_addr_mpls {
u8 type;
u8 pxlen;
@ -220,6 +230,7 @@ typedef union net_addr_union {
net_addr_flow4 flow4;
net_addr_flow6 flow6;
net_addr_ip6_sadr ip6_sadr;
net_addr_eth eth;
net_addr_mpls mpls;
net_addr_evpn evpn;
} net_addr_union;
@ -260,6 +271,9 @@ extern const u16 net_max_text_length[];
#define NET_ADDR_IP6_SADR(dst_prefix,dst_pxlen,src_prefix,src_pxlen) \
((net_addr_ip6_sadr) { NET_IP6_SADR, dst_pxlen, sizeof(net_addr_ip6_sadr), dst_prefix, src_pxlen, src_prefix })
#define NET_ADDR_ETH(mac, vid) \
((net_addr_eth) { NET_ETH, 48, sizeof(net_addr_eth), mac, vid })
#define NET_ADDR_MPLS(label) \
((net_addr_mpls) { NET_MPLS, 20, sizeof(net_addr_mpls), label })
@ -301,6 +315,9 @@ static inline void net_fill_roa6(net_addr *a, ip6_addr prefix, uint pxlen, uint
static inline void net_fill_ip6_sadr(net_addr *a, ip6_addr dst_prefix, uint dst_pxlen, ip6_addr src_prefix, uint src_pxlen)
{ *(net_addr_ip6_sadr *)a = NET_ADDR_IP6_SADR(dst_prefix, dst_pxlen, src_prefix, src_pxlen); }
static inline void net_fill_eth(net_addr *a, mac_addr mac, u16 vid)
{ *(net_addr_eth *)a = NET_ADDR_ETH(mac, vid); }
static inline void net_fill_mpls(net_addr *a, u32 label)
{ *(net_addr_mpls *)a = NET_ADDR_MPLS(label); }
@ -405,6 +422,7 @@ static inline ip_addr net_prefix(const net_addr *a)
case NET_IP6_SADR:
return ipa_from_ip6(net6_prefix(a));
case NET_ETH:
case NET_MPLS:
case NET_EVPN:
default:
@ -412,12 +430,16 @@ static inline ip_addr net_prefix(const net_addr *a)
}
}
static inline mac_addr net_mac_addr(const net_addr *a)
{
ASSERT_DIE(a->type == NET_ETH);
return ((net_addr_eth *) a)->mac;
}
static inline u32 net_mpls(const net_addr *a)
{
if (a->type == NET_MPLS)
return ((net_addr_mpls *) a)->label;
bug("Can't call net_mpls on non-mpls net_addr");
ASSERT_DIE(a->type == NET_MPLS);
return ((net_addr_mpls *) a)->label;
}
static inline uint net4_pxlen(const net_addr *a)
@ -476,6 +498,9 @@ static inline int net_equal_flow6(const net_addr_flow6 *a, const net_addr_flow6
static inline int net_equal_ip6_sadr(const net_addr_ip6_sadr *a, const net_addr_ip6_sadr *b)
{ return !memcmp(a, b, sizeof(net_addr_ip6_sadr)); }
static inline int net_equal_eth(const net_addr_eth *a, const net_addr_eth *b)
{ return !memcmp(a, b, sizeof(net_addr_eth)); }
static inline int net_equal_mpls(const net_addr_mpls *a, const net_addr_mpls *b)
{ return !memcmp(a, b, sizeof(net_addr_mpls)); }
@ -520,6 +545,9 @@ static inline int net_zero_flow4(const net_addr_flow4 *a)
static inline int net_zero_flow6(const net_addr_flow6 *a)
{ return !a->pxlen && ip6_zero(a->prefix) && (a->length == sizeof(net_addr_flow6)); }
static inline int net_zero_eth(const net_addr_eth *a)
{ return mac_zero(a->mac) && !a->vid; }
static inline int net_zero_mpls(const net_addr_mpls *a)
{ return !a->label; }
@ -555,6 +583,9 @@ static inline int net_compare_ip6_sadr(const net_addr_ip6_sadr *a, const net_add
ip6_compare(a->src_prefix, b->src_prefix) ?: uint_cmp(a->src_pxlen, b->src_pxlen);
}
static inline int net_compare_eth(const net_addr_eth *a, const net_addr_eth *b)
{ return uint_cmp(a->vid, b->vid) ?: mac_compare(a->mac, b->mac); }
static inline int net_compare_mpls(const net_addr_mpls *a, const net_addr_mpls *b)
{ return uint_cmp(a->label, b->label); }
@ -598,6 +629,9 @@ static inline void net_copy_flow6(net_addr_flow6 *dst, const net_addr_flow6 *src
static inline void net_copy_ip6_sadr(net_addr_ip6_sadr *dst, const net_addr_ip6_sadr *src)
{ memcpy(dst, src, sizeof(net_addr_ip6_sadr)); }
static inline void net_copy_eth(net_addr_eth *dst, const net_addr_eth *src)
{ memcpy(dst, src, sizeof(net_addr_eth)); }
static inline void net_copy_mpls(net_addr_mpls *dst, const net_addr_mpls *src)
{ memcpy(dst, src, sizeof(net_addr_mpls)); }
@ -644,6 +678,9 @@ static inline u32 net_hash_flow6(const net_addr_flow6 *n)
static inline u32 net_hash_ip6_sadr(const net_addr_ip6_sadr *n)
{ return px6_hash(n->dst_prefix, n->dst_pxlen); }
static inline u32 net_hash_eth(const net_addr_eth *n)
{ u64 x = 0; memcpy(&x, (char *) n + OFFSETOF(net_addr_eth, mac), 8); return u64_hash(x); }
static inline u32 net_hash_mpls(const net_addr_mpls *n)
{ return u32_hash(n->label); }
@ -696,6 +733,9 @@ static inline int net_validate_flow4(const net_addr_flow4 *n)
static inline int net_validate_flow6(const net_addr_flow6 *n)
{ return net_validate_px6(n->prefix, n->pxlen); }
static inline int net_validate_eth(const net_addr_eth *n)
{ return n->vid < (1 << 12); }
static inline int net_validate_mpls(const net_addr_mpls *n)
{ return n->label < (1 << 20); }

View File

@ -115,7 +115,7 @@ CF_DECLS
CF_KEYWORDS(ROUTER, ID, HOSTNAME, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, DEFAULT, TABLE, TABLES, STATES, ROUTES, FILTERS)
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, ETH, MPLS)
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED, RPKI)
CF_KEYWORDS(PASSWORD, KEY, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, CHANNELS, INTERFACES)
CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512, BLAKE2S128, BLAKE2S256, BLAKE2B256, BLAKE2B512)
@ -203,6 +203,7 @@ net_type_base:
| ROA6 { $$ = NET_ROA6; }
| FLOW4{ $$ = NET_FLOW4; }
| FLOW6{ $$ = NET_FLOW6; }
| ETH { $$ = NET_ETH; }
| EVPN { $$ = NET_EVPN; }
;
@ -211,7 +212,7 @@ net_type:
| MPLS { $$ = NET_MPLS; }
;
CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, IP6_SADR, MPLS, EVPN)
CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, IP6_SADR, ETH, MPLS, EVPN)
/* Creation of routing tables */

View File

@ -278,6 +278,7 @@ fib_find(struct fib *f, const net_addr *a)
case NET_FLOW4: return FIB_FIND(f, a, flow4);
case NET_FLOW6: return FIB_FIND(f, a, flow6);
case NET_IP6_SADR: return FIB_FIND(f, a, ip6_sadr);
case NET_ETH: return FIB_FIND(f, a, eth);
case NET_MPLS: return FIB_FIND(f, a, mpls);
case NET_EVPN: return FIB_FIND(f, a, evpn);
default: bug("invalid type");
@ -300,6 +301,7 @@ fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
case NET_FLOW4: FIB_INSERT(f, a, e, flow4); return;
case NET_FLOW6: FIB_INSERT(f, a, e, flow6); return;
case NET_IP6_SADR: FIB_INSERT(f, a, e, ip6_sadr); return;
case NET_ETH: FIB_INSERT(f, a, e, eth); return;
case NET_MPLS: FIB_INSERT(f, a, e, mpls); return;
case NET_EVPN: FIB_INSERT(f, a, e, evpn); return;
default: bug("invalid type");