0
0
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:
Ondrej Zajicek (work) 2018-01-22 21:09:29 +01:00
commit ea8a8c5d3b
12 changed files with 374 additions and 21 deletions

View File

@ -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)

View File

@ -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
View File

@ -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); }

View File

@ -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;

View File

@ -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 */

View File

@ -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; }
;

View File

@ -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 */

View File

@ -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;

View File

@ -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");
}

View File

@ -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

View File

@ -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)
{

View File

@ -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