mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Nest: Ethernet net type - preliminary support
This commit is contained in:
parent
2f4f790a16
commit
b5c040d0cf
@ -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_
|
||||
;
|
||||
|
23
lib/net.c
23
lib/net.c
@ -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:
|
||||
|
56
lib/net.h
56
lib/net.h
@ -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); }
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user