mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 15:41:54 +00:00
Merge commit '76baa8b38ad411e871793ab30bb94e17e1cd2397' into pim
This commit is contained in:
commit
ea8a8c5d3b
6
lib/ip.h
6
lib/ip.h
@ -238,6 +238,12 @@ static inline int ip6_is_link_local(ip6_addr a)
|
||||
static inline int ip6_is_v4mapped(ip6_addr a)
|
||||
{ return _I0(a) == 0 && _I1(a) == 0 && _I2(a) == 0xffff; }
|
||||
|
||||
static inline int ip4_is_multicast(ip4_addr a)
|
||||
{ return (_I(a) & 0xf0000000) == 0xe0000000; }
|
||||
|
||||
static inline int ip6_is_multicast(ip6_addr a)
|
||||
{ return (_I0(a) & 0xff000000) == 0xff000000; }
|
||||
|
||||
#define ipa_classify(x) ip6_classify(&(x))
|
||||
#define ipa_is_link_local(x) ip6_is_link_local(x)
|
||||
|
||||
|
66
lib/net.c
66
lib/net.c
@ -14,6 +14,10 @@ const char * const net_label[] = {
|
||||
[NET_ROA6] = "roa6",
|
||||
[NET_FLOW4] = "flow4",
|
||||
[NET_FLOW6] = "flow6",
|
||||
[NET_MREQ4] = "mreq4",
|
||||
[NET_MREQ6] = "mreq6",
|
||||
[NET_MGRP4] = "mgrp4",
|
||||
[NET_MGRP6] = "mgrp6",
|
||||
[NET_MPLS] = "mpls",
|
||||
};
|
||||
|
||||
@ -26,6 +30,10 @@ const u16 net_addr_length[] = {
|
||||
[NET_ROA6] = sizeof(net_addr_roa6),
|
||||
[NET_FLOW4] = 0,
|
||||
[NET_FLOW6] = 0,
|
||||
[NET_MREQ4] = sizeof(net_addr_mreq4),
|
||||
[NET_MREQ6] = sizeof(net_addr_mreq6),
|
||||
[NET_MGRP4] = sizeof(net_addr_mgrp4),
|
||||
[NET_MGRP6] = sizeof(net_addr_mgrp6),
|
||||
[NET_MPLS] = sizeof(net_addr_mpls),
|
||||
};
|
||||
|
||||
@ -38,6 +46,10 @@ const u8 net_max_prefix_length[] = {
|
||||
[NET_ROA6] = IP6_MAX_PREFIX_LENGTH,
|
||||
[NET_FLOW4] = IP4_MAX_PREFIX_LENGTH,
|
||||
[NET_FLOW6] = IP6_MAX_PREFIX_LENGTH,
|
||||
[NET_MREQ4] = IP4_MAX_PREFIX_LENGTH,
|
||||
[NET_MREQ6] = IP6_MAX_PREFIX_LENGTH,
|
||||
[NET_MGRP4] = IP4_MAX_PREFIX_LENGTH,
|
||||
[NET_MGRP6] = IP6_MAX_PREFIX_LENGTH,
|
||||
[NET_MPLS] = 0,
|
||||
};
|
||||
|
||||
@ -50,6 +62,10 @@ const u16 net_max_text_length[] = {
|
||||
[NET_ROA6] = 60, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128-128 AS4294967295" */
|
||||
[NET_FLOW4] = 0, /* "flow4 { ... }" */
|
||||
[NET_FLOW6] = 0, /* "flow6 { ... }" */
|
||||
[NET_MREQ4] = 15, /* "255.255.255.255" */
|
||||
[NET_MREQ6] = 39, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" */
|
||||
[NET_MGRP4] = 15, /* "255.255.255.255" */
|
||||
[NET_MGRP6] = 39, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" */
|
||||
[NET_MPLS] = 7, /* "1048575" */
|
||||
};
|
||||
|
||||
@ -102,6 +118,14 @@ net_format(const net_addr *N, char *buf, int buflen)
|
||||
return flow4_net_format(buf, buflen, &n->flow4);
|
||||
case NET_FLOW6:
|
||||
return flow6_net_format(buf, buflen, &n->flow6);
|
||||
case NET_MREQ4:
|
||||
return bsnprintf(buf, buflen, "%I4", n->mreq4.grp);
|
||||
case NET_MREQ6:
|
||||
return bsnprintf(buf, buflen, "%I6", n->mreq6.grp);
|
||||
case NET_MGRP4:
|
||||
return bsnprintf(buf, buflen, "%I4", n->mgrp4.grp);
|
||||
case NET_MGRP6:
|
||||
return bsnprintf(buf, buflen, "%I6", n->mgrp6.grp);
|
||||
case NET_MPLS:
|
||||
return bsnprintf(buf, buflen, "%u", n->mpls.label);
|
||||
}
|
||||
@ -118,12 +142,16 @@ net_pxmask(const net_addr *a)
|
||||
case NET_VPN4:
|
||||
case NET_ROA4:
|
||||
case NET_FLOW4:
|
||||
case NET_MREQ4:
|
||||
case NET_MGRP4:
|
||||
return ipa_from_ip4(ip4_mkmask(net4_pxlen(a)));
|
||||
|
||||
case NET_IP6:
|
||||
case NET_VPN6:
|
||||
case NET_ROA6:
|
||||
case NET_FLOW6:
|
||||
case NET_MREQ6:
|
||||
case NET_MGRP6:
|
||||
return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
|
||||
|
||||
case NET_MPLS:
|
||||
@ -156,6 +184,14 @@ net_compare(const net_addr *a, const net_addr *b)
|
||||
return net_compare_flow4((const net_addr_flow4 *) a, (const net_addr_flow4 *) b);
|
||||
case NET_FLOW6:
|
||||
return net_compare_flow6((const net_addr_flow6 *) a, (const net_addr_flow6 *) b);
|
||||
case NET_MREQ4:
|
||||
return net_compare_mreq4((const net_addr_mreq4 *) a, (const net_addr_mreq4 *) b);
|
||||
case NET_MREQ6:
|
||||
return net_compare_mreq6((const net_addr_mreq6 *) a, (const net_addr_mreq6 *) b);
|
||||
case NET_MGRP4:
|
||||
return net_compare_mgrp4((const net_addr_mgrp4 *) a, (const net_addr_mgrp4 *) b);
|
||||
case NET_MGRP6:
|
||||
return net_compare_mgrp6((const net_addr_mgrp6 *) a, (const net_addr_mgrp6 *) b);
|
||||
case NET_MPLS:
|
||||
return net_compare_mpls((const net_addr_mpls *) a, (const net_addr_mpls *) b);
|
||||
}
|
||||
@ -177,6 +213,10 @@ net_hash(const net_addr *n)
|
||||
case NET_ROA6: return NET_HASH(n, roa6);
|
||||
case NET_FLOW4: return NET_HASH(n, flow4);
|
||||
case NET_FLOW6: return NET_HASH(n, flow6);
|
||||
case NET_MREQ4: return NET_HASH(n, mreq4);
|
||||
case NET_MREQ6: return NET_HASH(n, mreq6);
|
||||
case NET_MGRP4: return NET_HASH(n, mgrp4);
|
||||
case NET_MGRP6: return NET_HASH(n, mgrp6);
|
||||
case NET_MPLS: return NET_HASH(n, mpls);
|
||||
default: bug("invalid type");
|
||||
}
|
||||
@ -198,6 +238,10 @@ net_validate(const net_addr *n)
|
||||
case NET_ROA6: return NET_VALIDATE(n, roa6);
|
||||
case NET_FLOW4: return NET_VALIDATE(n, flow4);
|
||||
case NET_FLOW6: return NET_VALIDATE(n, flow6);
|
||||
case NET_MREQ4: return NET_VALIDATE(n, mreq4);
|
||||
case NET_MREQ6: return NET_VALIDATE(n, mreq6);
|
||||
case NET_MGRP4: return NET_VALIDATE(n, mgrp4);
|
||||
case NET_MGRP6: return NET_VALIDATE(n, mgrp6);
|
||||
case NET_MPLS: return NET_VALIDATE(n, mpls);
|
||||
default: return 0;
|
||||
}
|
||||
@ -222,6 +266,10 @@ net_normalize(net_addr *N)
|
||||
case NET_FLOW6:
|
||||
return net_normalize_ip6(&n->ip6);
|
||||
|
||||
case NET_MREQ4:
|
||||
case NET_MREQ6:
|
||||
case NET_MGRP4:
|
||||
case NET_MGRP6:
|
||||
case NET_MPLS:
|
||||
return;
|
||||
}
|
||||
@ -238,12 +286,16 @@ net_classify(const net_addr *N)
|
||||
case NET_VPN4:
|
||||
case NET_ROA4:
|
||||
case NET_FLOW4:
|
||||
case NET_MREQ4:
|
||||
case NET_MGRP4:
|
||||
return ip4_zero(n->ip4.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip4_classify(n->ip4.prefix);
|
||||
|
||||
case NET_IP6:
|
||||
case NET_VPN6:
|
||||
case NET_ROA6:
|
||||
case NET_FLOW6:
|
||||
case NET_MREQ6:
|
||||
case NET_MGRP6:
|
||||
return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
|
||||
|
||||
case NET_MPLS:
|
||||
@ -274,6 +326,16 @@ 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_MREQ4:
|
||||
case NET_MGRP4:
|
||||
if (!ipa_is_ip4(a)) return 0;
|
||||
return ip4_equal(ipa_to_ip4(a), net4_prefix(n));
|
||||
|
||||
case NET_MREQ6:
|
||||
case NET_MGRP6:
|
||||
if (ipa_is_ip4(a)) return 0;
|
||||
return ip6_equal(ipa_to_ip6(a), net6_prefix(n));
|
||||
|
||||
case NET_MPLS:
|
||||
default:
|
||||
return 0;
|
||||
@ -304,5 +366,9 @@ net_init(void)
|
||||
CHECK_NET(net_addr_roa6, 28);
|
||||
CHECK_NET(net_addr_flow4, 8);
|
||||
CHECK_NET(net_addr_flow6, 20);
|
||||
CHECK_NET(net_addr_mreq4, 12);
|
||||
CHECK_NET(net_addr_mreq6, 24);
|
||||
CHECK_NET(net_addr_mgrp4, 8);
|
||||
CHECK_NET(net_addr_mgrp6, 20);
|
||||
CHECK_NET(net_addr_mpls, 8);
|
||||
}
|
||||
|
193
lib/net.h
193
lib/net.h
@ -21,8 +21,12 @@
|
||||
#define NET_ROA6 6
|
||||
#define NET_FLOW4 7
|
||||
#define NET_FLOW6 8
|
||||
#define NET_MPLS 9
|
||||
#define NET_MAX 10
|
||||
#define NET_MREQ4 9
|
||||
#define NET_MREQ6 10
|
||||
#define NET_MGRP4 11
|
||||
#define NET_MGRP6 12
|
||||
#define NET_MPLS 13
|
||||
#define NET_MAX 14
|
||||
|
||||
#define NB_IP4 (1 << NET_IP4)
|
||||
#define NB_IP6 (1 << NET_IP6)
|
||||
@ -32,11 +36,20 @@
|
||||
#define NB_ROA6 (1 << NET_ROA6)
|
||||
#define NB_FLOW4 (1 << NET_FLOW4)
|
||||
#define NB_FLOW6 (1 << NET_FLOW6)
|
||||
#define NB_MREQ4 (1 << NET_MREQ4)
|
||||
#define NB_MREQ6 (1 << NET_MREQ6)
|
||||
#define NB_MGRP4 (1 << NET_MGRP4)
|
||||
#define NB_MGRP6 (1 << NET_MGRP6)
|
||||
#define NB_MPLS (1 << NET_MPLS)
|
||||
|
||||
#define NB_IP (NB_IP4 | NB_IP6)
|
||||
#define NB_VPN (NB_VPN4 | NB_VPN6)
|
||||
#define NB_ROA (NB_ROA4 | NB_ROA6)
|
||||
#define NB_FLOW (NB_FLOW4 | NB_FLOW6)
|
||||
#define NB_MREQ (NB_MREQ4 | NB_MREQ6)
|
||||
#define NB_MGRP (NB_MGRP4 | NB_MGRP6)
|
||||
|
||||
#define NB_HOST (NB_IP | NB_VPN | NB_ROA)
|
||||
#define NB_DEST (NB_IP | NB_VPN | NB_MPLS)
|
||||
#define NB_ANY 0xffffffff
|
||||
|
||||
@ -114,6 +127,36 @@ typedef struct net_addr_flow6 {
|
||||
byte data[0];
|
||||
} net_addr_flow6;
|
||||
|
||||
typedef struct net_addr_mreq4 {
|
||||
u8 type;
|
||||
u8 pxlen;
|
||||
u16 length;
|
||||
ip4_addr grp;
|
||||
uint ifindex;
|
||||
} net_addr_mreq4;
|
||||
|
||||
typedef struct net_addr_mreq6 {
|
||||
u8 type;
|
||||
u8 pxlen;
|
||||
u16 length;
|
||||
ip6_addr grp;
|
||||
uint ifindex;
|
||||
} net_addr_mreq6;
|
||||
|
||||
typedef struct net_addr_mgrp4 {
|
||||
u8 type;
|
||||
u8 pxlen;
|
||||
u16 length;
|
||||
ip4_addr grp;
|
||||
} net_addr_mgrp4;
|
||||
|
||||
typedef struct net_addr_mgrp6 {
|
||||
u8 type;
|
||||
u8 pxlen;
|
||||
u16 length;
|
||||
ip6_addr grp;
|
||||
} net_addr_mgrp6;
|
||||
|
||||
typedef struct net_addr_mpls {
|
||||
u8 type;
|
||||
u8 pxlen;
|
||||
@ -131,6 +174,10 @@ typedef union net_addr_union {
|
||||
net_addr_roa6 roa6;
|
||||
net_addr_flow4 flow4;
|
||||
net_addr_flow6 flow6;
|
||||
net_addr_mreq4 mreq4;
|
||||
net_addr_mreq6 mreq6;
|
||||
net_addr_mgrp4 mgrp4;
|
||||
net_addr_mgrp6 mgrp6;
|
||||
net_addr_mpls mpls;
|
||||
} net_addr_union;
|
||||
|
||||
@ -167,6 +214,18 @@ extern const u16 net_max_text_length[];
|
||||
#define NET_ADDR_FLOW6(prefix,pxlen,dlen) \
|
||||
((net_addr_flow6) { NET_FLOW6, pxlen, sizeof(net_addr_ip6) + dlen, prefix })
|
||||
|
||||
#define NET_ADDR_MREQ4(grp, ifindex) \
|
||||
((net_addr_mreq4) { NET_MREQ4, IP4_MAX_PREFIX_LENGTH, sizeof(net_addr_mreq4), grp, ifindex })
|
||||
|
||||
#define NET_ADDR_MREQ6(grp, ifindex) \
|
||||
((net_addr_mreq6) { NET_MREQ6, IP6_MAX_PREFIX_LENGTH, sizeof(net_addr_mreq6), grp, ifindex })
|
||||
|
||||
#define NET_ADDR_MGRP4(grp) \
|
||||
((net_addr_mgrp4) { NET_MGRP4, IP4_MAX_PREFIX_LENGTH, sizeof(net_addr_mgrp4), grp })
|
||||
|
||||
#define NET_ADDR_MGRP6(grp) \
|
||||
((net_addr_mgrp6) { NET_MGRP6, IP6_MAX_PREFIX_LENGTH, sizeof(net_addr_mgrp6), grp })
|
||||
|
||||
#define NET_ADDR_MPLS(label) \
|
||||
((net_addr_mpls) { NET_MPLS, 20, sizeof(net_addr_mpls), label })
|
||||
|
||||
@ -189,6 +248,18 @@ static inline void net_fill_roa4(net_addr *a, ip4_addr prefix, uint pxlen, uint
|
||||
static inline void net_fill_roa6(net_addr *a, ip6_addr prefix, uint pxlen, uint max_pxlen, u32 asn)
|
||||
{ *(net_addr_roa6 *)a = NET_ADDR_ROA6(prefix, pxlen, max_pxlen, asn); }
|
||||
|
||||
static inline void net_fill_mreq4(net_addr *a, ip4_addr grp, uint ifindex)
|
||||
{ *(net_addr_mreq4 *)a = NET_ADDR_MREQ4(grp, ifindex); }
|
||||
|
||||
static inline void net_fill_mreq6(net_addr *a, ip6_addr grp, uint ifindex)
|
||||
{ *(net_addr_mreq6 *)a = NET_ADDR_MREQ6(grp, ifindex); }
|
||||
|
||||
static inline void net_fill_mgrp4(net_addr *a, ip4_addr grp)
|
||||
{ *(net_addr_mgrp4 *)a = NET_ADDR_MGRP4(grp); }
|
||||
|
||||
static inline void net_fill_mgrp6(net_addr *a, ip6_addr grp)
|
||||
{ *(net_addr_mgrp6 *)a = NET_ADDR_MGRP6(grp); }
|
||||
|
||||
static inline void net_fill_mpls(net_addr *a, u32 label)
|
||||
{ *(net_addr_mpls *)a = NET_ADDR_MPLS(label); }
|
||||
|
||||
@ -208,6 +279,22 @@ static inline void net_fill_ip_host(net_addr *a, ip_addr prefix)
|
||||
net_fill_ip6(a, ipa_to_ip6(prefix), IP6_MAX_PREFIX_LENGTH);
|
||||
}
|
||||
|
||||
static inline void net_fill_mreq(net_addr *a, ip_addr grp, unsigned ifindex)
|
||||
{
|
||||
if (ipa_is_ip4(grp))
|
||||
net_fill_mreq4(a, ipa_to_ip4(grp), ifindex);
|
||||
else
|
||||
net_fill_mreq6(a, ipa_to_ip6(grp), ifindex);
|
||||
}
|
||||
|
||||
static inline void net_fill_mgrp(net_addr *a, ip_addr grp)
|
||||
{
|
||||
if (ipa_is_ip4(grp))
|
||||
net_fill_mgrp4(a, ipa_to_ip4(grp));
|
||||
else
|
||||
net_fill_mgrp6(a, ipa_to_ip6(grp));
|
||||
}
|
||||
|
||||
static inline void net_fill_flow4(net_addr *a, ip4_addr prefix, uint pxlen, byte *data, uint dlen)
|
||||
{
|
||||
net_addr_flow4 *f = (void *) a;
|
||||
@ -240,6 +327,12 @@ static inline int net_is_roa(const net_addr *a)
|
||||
static inline int net_is_flow(const net_addr *a)
|
||||
{ return (a->type == NET_FLOW4) || (a->type == NET_FLOW6); }
|
||||
|
||||
static inline int net_is_mreq(const net_addr *a)
|
||||
{ return (a->type == NET_MREQ4) || (a->type == NET_MREQ6); }
|
||||
|
||||
static inline int net_is_mgrp(const net_addr *a)
|
||||
{ return (a->type == NET_MGRP4) || (a->type == NET_MGRP6); }
|
||||
|
||||
|
||||
static inline ip4_addr net4_prefix(const net_addr *a)
|
||||
{ return ((net_addr_ip4 *) a)->prefix; }
|
||||
@ -255,12 +348,16 @@ static inline ip_addr net_prefix(const net_addr *a)
|
||||
case NET_VPN4:
|
||||
case NET_ROA4:
|
||||
case NET_FLOW4:
|
||||
case NET_MREQ4:
|
||||
case NET_MGRP4:
|
||||
return ipa_from_ip4(net4_prefix(a));
|
||||
|
||||
case NET_IP6:
|
||||
case NET_VPN6:
|
||||
case NET_ROA6:
|
||||
case NET_FLOW6:
|
||||
case NET_MREQ6:
|
||||
case NET_MGRP6:
|
||||
return ipa_from_ip6(net6_prefix(a));
|
||||
|
||||
case NET_MPLS:
|
||||
@ -293,11 +390,25 @@ static inline u64 net_rd(const net_addr *a)
|
||||
switch (a->type)
|
||||
{
|
||||
case NET_VPN4:
|
||||
return ((net_addr_vpn4 *)a)->rd;
|
||||
return ((net_addr_vpn4 *) a)->rd;
|
||||
case NET_VPN6:
|
||||
return ((net_addr_vpn6 *)a)->rd;
|
||||
}
|
||||
return ((net_addr_vpn6 *) a)->rd;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int net_ifindex(net_addr *a)
|
||||
{
|
||||
switch (a->type)
|
||||
{
|
||||
case NET_MREQ4:
|
||||
return ((net_addr_mreq4 *) a)->ifindex;
|
||||
case NET_MREQ6:
|
||||
return ((net_addr_mreq6 *) a)->ifindex;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -338,6 +449,18 @@ static inline int net_equal_prefix_roa4(const net_addr_roa4 *a, const net_addr_r
|
||||
static inline int net_equal_prefix_roa6(const net_addr_roa6 *a, const net_addr_roa6 *b)
|
||||
{ return ip6_equal(a->prefix, b->prefix) && (a->pxlen == b->pxlen); }
|
||||
|
||||
static inline int net_equal_mreq4(const net_addr_mreq4 *a, const net_addr_mreq4 *b)
|
||||
{ return !memcmp(a, b, sizeof(net_addr_mreq4)); }
|
||||
|
||||
static inline int net_equal_mreq6(const net_addr_mreq6 *a, const net_addr_mreq6 *b)
|
||||
{ return !memcmp(a, b, sizeof(net_addr_mreq6)); }
|
||||
|
||||
static inline int net_equal_mgrp4(const net_addr_mgrp4 *a, const net_addr_mgrp4 *b)
|
||||
{ return !memcmp(a, b, sizeof(net_addr_mgrp4)); }
|
||||
|
||||
static inline int net_equal_mgrp6(const net_addr_mgrp6 *a, const net_addr_mgrp6 *b)
|
||||
{ return !memcmp(a, b, sizeof(net_addr_mgrp6)); }
|
||||
|
||||
|
||||
static inline int net_zero_ip4(const net_addr_ip4 *a)
|
||||
{ return !a->pxlen && ip4_zero(a->prefix); }
|
||||
@ -363,6 +486,18 @@ 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_mreq4(const net_addr_mreq4 *a)
|
||||
{ return ip4_zero(a->grp) && !a->ifindex; }
|
||||
|
||||
static inline int net_zero_mreq6(const net_addr_mreq6 *a)
|
||||
{ return ip6_zero(a->grp) && !a->ifindex; }
|
||||
|
||||
static inline int net_zero_mgrp4(const net_addr_mgrp4 *a)
|
||||
{ return ip4_zero(a->grp); }
|
||||
|
||||
static inline int net_zero_mgrp6(const net_addr_mgrp6 *a)
|
||||
{ return ip6_zero(a->grp); }
|
||||
|
||||
static inline int net_zero_mpls(const net_addr_mpls *a)
|
||||
{ return !a->label; }
|
||||
|
||||
@ -391,6 +526,18 @@ static inline int net_compare_flow4(const net_addr_flow4 *a, const net_addr_flow
|
||||
static inline int net_compare_flow6(const net_addr_flow6 *a, const net_addr_flow6 *b)
|
||||
{ return ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen) ?: uint_cmp(a->length, b->length) ?: memcmp(a->data, b->data, a->length - sizeof(net_addr_flow6)); }
|
||||
|
||||
static inline int net_compare_mreq4(const net_addr_mreq4 *a, const net_addr_mreq4 *b)
|
||||
{ return ip4_compare(a->grp, b->grp) ?: uint_cmp(a->ifindex, b->ifindex); }
|
||||
|
||||
static inline int net_compare_mreq6(const net_addr_mreq6 *a, const net_addr_mreq6 *b)
|
||||
{ return ip6_compare(a->grp, b->grp) ?: uint_cmp(a->ifindex, b->ifindex); }
|
||||
|
||||
static inline int net_compare_mgrp4(const net_addr_mgrp4 *a, const net_addr_mgrp4 *b)
|
||||
{ return ip4_compare(a->grp, b->grp); }
|
||||
|
||||
static inline int net_compare_mgrp6(const net_addr_mgrp6 *a, const net_addr_mgrp6 *b)
|
||||
{ return ip6_compare(a->grp, b->grp); }
|
||||
|
||||
static inline int net_compare_mpls(const net_addr_mpls *a, const net_addr_mpls *b)
|
||||
{ return uint_cmp(a->label, b->label); }
|
||||
|
||||
@ -424,6 +571,18 @@ static inline void net_copy_flow4(net_addr_flow4 *dst, const net_addr_flow4 *src
|
||||
static inline void net_copy_flow6(net_addr_flow6 *dst, const net_addr_flow6 *src)
|
||||
{ memcpy(dst, src, src->length); }
|
||||
|
||||
static inline void net_copy_mreq4(net_addr_mreq4 *dst, const net_addr_mreq4 *src)
|
||||
{ memcpy(dst, src, sizeof(net_addr_mreq4)); }
|
||||
|
||||
static inline void net_copy_mreq6(net_addr_mreq6 *dst, const net_addr_mreq6 *src)
|
||||
{ memcpy(dst, src, sizeof(net_addr_mreq6)); }
|
||||
|
||||
static inline void net_copy_mgrp4(net_addr_mgrp4 *dst, const net_addr_mgrp4 *src)
|
||||
{ memcpy(dst, src, sizeof(net_addr_mgrp4)); }
|
||||
|
||||
static inline void net_copy_mgrp6(net_addr_mgrp6 *dst, const net_addr_mgrp6 *src)
|
||||
{ memcpy(dst, src, sizeof(net_addr_mgrp6)); }
|
||||
|
||||
static inline void net_copy_mpls(net_addr_mpls *dst, const net_addr_mpls *src)
|
||||
{ memcpy(dst, src, sizeof(net_addr_mpls)); }
|
||||
|
||||
@ -456,6 +615,18 @@ static inline u32 net_hash_flow4(const net_addr_flow4 *n)
|
||||
static inline u32 net_hash_flow6(const net_addr_flow6 *n)
|
||||
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
|
||||
|
||||
static inline u32 net_hash_mreq4(const net_addr_mreq4 *n)
|
||||
{ return ip4_hash(n->grp) ^ u32_hash(n->ifindex); }
|
||||
|
||||
static inline u32 net_hash_mreq6(const net_addr_mreq6 *n)
|
||||
{ return ip6_hash(n->grp) ^ u32_hash(n->ifindex); }
|
||||
|
||||
static inline u32 net_hash_mgrp4(const net_addr_mgrp4 *n)
|
||||
{ return ip4_hash(n->grp); }
|
||||
|
||||
static inline u32 net_hash_mgrp6(const net_addr_mgrp6 *n)
|
||||
{ return ip6_hash(n->grp); }
|
||||
|
||||
static inline u32 net_hash_mpls(const net_addr_mpls *n)
|
||||
{ return n->label; }
|
||||
|
||||
@ -505,6 +676,18 @@ 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_mreq4(const net_addr_mreq4 *n)
|
||||
{ return ip4_is_multicast(n->grp); }
|
||||
|
||||
static inline int net_validate_mreq6(const net_addr_mreq6 *n)
|
||||
{ return ip6_is_multicast(n->grp); }
|
||||
|
||||
static inline int net_validate_mgrp4(const net_addr_mgrp4 *n)
|
||||
{ return ip4_is_multicast(n->grp); }
|
||||
|
||||
static inline int net_validate_mgrp6(const net_addr_mgrp6 *n)
|
||||
{ return ip6_is_multicast(n->grp); }
|
||||
|
||||
static inline int net_validate_mpls(const net_addr_mpls *n)
|
||||
{ return n->label < (1 << 20); }
|
||||
|
||||
|
@ -410,6 +410,9 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
case 'b':
|
||||
base = 2;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
flags |= LARGE;
|
||||
|
@ -103,6 +103,7 @@ static inline int sk_send_buffer_empty(sock *sk)
|
||||
int sk_setup_multicast(sock *s); /* Prepare UDP or IP socket for multicasting */
|
||||
int sk_join_group(sock *s, ip_addr maddr); /* Join multicast group on sk iface */
|
||||
int sk_leave_group(sock *s, ip_addr maddr); /* Leave multicast group on sk iface */
|
||||
int sk_set_router_alert(sock *s, int ra);
|
||||
int sk_setup_broadcast(sock *s);
|
||||
int sk_set_ttl(sock *s, int ttl); /* Set transmit TTL for given socket */
|
||||
int sk_set_min_ttl(sock *s, int ttl); /* Set minimal accepted TTL for given socket */
|
||||
|
@ -66,7 +66,7 @@ CF_DECLS
|
||||
|
||||
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
|
||||
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS)
|
||||
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6)
|
||||
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, MREQ4, MREQ6, MGRP4, MGRP6)
|
||||
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
|
||||
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
|
||||
CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
|
||||
@ -138,8 +138,12 @@ net_type:
|
||||
| VPN6 { $$ = NET_VPN6; }
|
||||
| ROA4 { $$ = NET_ROA4; }
|
||||
| ROA6 { $$ = NET_ROA6; }
|
||||
| FLOW4{ $$ = NET_FLOW4; }
|
||||
| FLOW6{ $$ = NET_FLOW6; }
|
||||
| FLOW4 { $$ = NET_FLOW4; }
|
||||
| FLOW6 { $$ = NET_FLOW6; }
|
||||
| MREQ4 { $$ = NET_MREQ4; }
|
||||
| MREQ6 { $$ = NET_MREQ6; }
|
||||
| MGRP4 { $$ = NET_MGRP4; }
|
||||
| MGRP6 { $$ = NET_MGRP6; }
|
||||
| MPLS { $$ = NET_MPLS; }
|
||||
;
|
||||
|
||||
|
15
nest/route.h
15
nest/route.h
@ -204,6 +204,8 @@ struct hostentry {
|
||||
u32 igp_metric; /* Chosen route IGP metric */
|
||||
};
|
||||
|
||||
#define RTE_MGRP_MAXVIFS 32
|
||||
|
||||
typedef struct rte {
|
||||
struct rte *next;
|
||||
net *net; /* Network this RTE belongs to */
|
||||
@ -247,6 +249,9 @@ typedef struct rte {
|
||||
u8 best; /* Best route in network, propagated to core */
|
||||
u32 metric; /* Kernel metric */
|
||||
} krt;
|
||||
struct {
|
||||
u32 iifs, oifs; /* Bitmaps for iifs and oifs. Use RTE_MGRP_* macros to manipulate. */
|
||||
} mkrt;
|
||||
} u;
|
||||
} rte;
|
||||
|
||||
@ -275,6 +280,13 @@ static inline int rte_is_filtered(rte *r) { return !!(r->flags & REF_FILTERED);
|
||||
#define RIC_REJECT -1 /* Rejected by protocol */
|
||||
#define RIC_DROP -2 /* Silently dropped by protocol */
|
||||
|
||||
#define RTE_MGRP_SET(iface,m) ((m) |= (1 << if_get_vifi((iface))))
|
||||
#define RTE_MGRP_CLR(iface,m) ((m) &= ~(1 << if_get_vifi((iface))))
|
||||
#define RTE_MGRP_ISSET(iface,m) ((m) & (1 << if_get_vifi((iface))))
|
||||
#define RTE_MGRP_ZERO(m) ((m) = 0)
|
||||
#define RTE_MGRP_COPY(src,dst) ((dst) = (src))
|
||||
#define RTE_MGRP_SAME(m1,m2) ((m1) == (m2))
|
||||
|
||||
struct config;
|
||||
|
||||
void rt_init(void);
|
||||
@ -430,7 +442,8 @@ typedef struct rta {
|
||||
#define RTD_BLACKHOLE 2 /* Silently drop packets */
|
||||
#define RTD_UNREACHABLE 3 /* Reject as unreachable */
|
||||
#define RTD_PROHIBIT 4 /* Administratively prohibited */
|
||||
#define RTD_MAX 5
|
||||
#define RTD_MULTICAST 5 /* Multicast route */
|
||||
#define RTD_MAX 6
|
||||
|
||||
/* Flags for net->n.flags, used by kernel syncer */
|
||||
#define KRF_INSTALLED 0x80 /* This route should be installed in the kernel */
|
||||
|
@ -64,6 +64,7 @@ const char * rta_dest_names[RTD_MAX] = {
|
||||
[RTD_BLACKHOLE] = "blackhole",
|
||||
[RTD_UNREACHABLE] = "unreachable",
|
||||
[RTD_PROHIBIT] = "prohibited",
|
||||
[RTD_MULTICAST] = "multicast",
|
||||
};
|
||||
|
||||
pool *rta_pool;
|
||||
|
@ -213,6 +213,10 @@ fib_hash(struct fib *f, const net_addr *a)
|
||||
case NET_ROA6: return FIB_HASH(f, a, roa6);
|
||||
case NET_FLOW4: return FIB_HASH(f, a, flow4);
|
||||
case NET_FLOW6: return FIB_HASH(f, a, flow6);
|
||||
case NET_MREQ4: return FIB_HASH(f, a, mreq4);
|
||||
case NET_MREQ6: return FIB_HASH(f, a, mreq6);
|
||||
case NET_MGRP4: return FIB_HASH(f, a, mgrp4);
|
||||
case NET_MGRP6: return FIB_HASH(f, a, mgrp6);
|
||||
case NET_MPLS: return FIB_HASH(f, a, mpls);
|
||||
default: bug("invalid type");
|
||||
}
|
||||
@ -250,6 +254,10 @@ fib_find(struct fib *f, const net_addr *a)
|
||||
case NET_ROA6: return FIB_FIND(f, a, roa6);
|
||||
case NET_FLOW4: return FIB_FIND(f, a, flow4);
|
||||
case NET_FLOW6: return FIB_FIND(f, a, flow6);
|
||||
case NET_MREQ4: return FIB_FIND(f, a, mreq4);
|
||||
case NET_MREQ6: return FIB_FIND(f, a, mreq6);
|
||||
case NET_MGRP4: return FIB_FIND(f, a, mgrp4);
|
||||
case NET_MGRP6: return FIB_FIND(f, a, mgrp6);
|
||||
case NET_MPLS: return FIB_FIND(f, a, mpls);
|
||||
default: bug("invalid type");
|
||||
}
|
||||
@ -270,6 +278,10 @@ fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
||||
case NET_ROA6: FIB_INSERT(f, a, e, roa6); return;
|
||||
case NET_FLOW4: FIB_INSERT(f, a, e, flow4); return;
|
||||
case NET_FLOW6: FIB_INSERT(f, a, e, flow6); return;
|
||||
case NET_MREQ4: FIB_INSERT(f, a, e, mreq4); return;
|
||||
case NET_MREQ6: FIB_INSERT(f, a, e, mreq6); return;
|
||||
case NET_MGRP4: FIB_INSERT(f, a, e, mgrp4); return;
|
||||
case NET_MGRP6: FIB_INSERT(f, a, e, mgrp6); return;
|
||||
case NET_MPLS: FIB_INSERT(f, a, e, mpls); return;
|
||||
default: bug("invalid type");
|
||||
}
|
||||
|
@ -898,9 +898,10 @@ rte_validate(rte *e)
|
||||
}
|
||||
|
||||
/* FIXME: better handling different nettypes */
|
||||
c = !net_is_flow(n->n.addr) ?
|
||||
net_classify(n->n.addr): (IADDR_HOST | SCOPE_UNIVERSE);
|
||||
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
||||
/* FIXME: should be check mcast addresses here or in net_validate()? */
|
||||
if (net_type_match(n->n.addr, NB_HOST) &&
|
||||
(c = net_classify(n->n.addr)) &&
|
||||
((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK)))
|
||||
{
|
||||
log(L_WARN "Ignoring bogus route %N received via %s",
|
||||
n->n.addr, e->sender->proto->name);
|
||||
@ -1430,6 +1431,33 @@ rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter)
|
||||
return v > 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Sometimes protocols need to find one route in table without keeping their own copy.
|
||||
* rt_route finds the best route after applying filter.
|
||||
* As the routes may be temporary, successful find is announced by the callback.
|
||||
* Returns 1 if the callback was called.
|
||||
*/
|
||||
int
|
||||
rt_route(struct channel *c, net_addr *n, void (*callback)(struct proto *, void *, rte *), void *data)
|
||||
{
|
||||
net *r;
|
||||
|
||||
net_addr *n0 = alloca(n->length);
|
||||
net_copy(n0, n);
|
||||
|
||||
while (1)
|
||||
{
|
||||
r = net_find(c->table, n0);
|
||||
if (r && rte_is_valid(r->routes) && rt_examine2(r, c->proto, c->out_filter, callback, data))
|
||||
return 1;
|
||||
if (n0->pxlen == 0)
|
||||
return 0;
|
||||
n0->pxlen--;
|
||||
net_normalize(n0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* rt_refresh_begin - start a refresh cycle
|
||||
|
@ -226,6 +226,24 @@ sk_set_min_ttl6(sock *s, int ttl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
sk_set_router_alert4(sock *s, int ra)
|
||||
{
|
||||
if (setsockopt(s->fd, SOL_IP, IP_ROUTER_ALERT, &ra, sizeof(ra)) < 0)
|
||||
ERR("IP_ROUTER_ALER");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
sk_set_router_alert6(sock *s, int ra)
|
||||
{
|
||||
if (setsockopt(s->fd, SOL_IPV6, IPV6_ROUTER_ALERT, &ra, sizeof(ra)) < 0)
|
||||
ERR("IPV6_ROUTER_ALER");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
sk_disable_mtu_disc4(sock *s)
|
||||
{
|
||||
|
@ -630,6 +630,24 @@ sk_set_min_ttl(sock *s, int ttl)
|
||||
return sk_set_min_ttl6(s, ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* sk_set_router_alert - set router alert option
|
||||
* @s: socket
|
||||
* @ra: packets with this router alert option value will be passed to the
|
||||
* socket. Negative integer disables.
|
||||
*
|
||||
* Result: 0 for success, -1 for an error.
|
||||
*/
|
||||
|
||||
int
|
||||
sk_set_router_alert(sock *s, int ra)
|
||||
{
|
||||
if (sk_is_ipv4(s))
|
||||
return sk_set_router_alert4(s, ra);
|
||||
else
|
||||
return sk_set_router_alert6(s, ra);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* sk_set_md5_auth - add / remove MD5 security association for given socket
|
||||
|
Loading…
Reference in New Issue
Block a user