mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:13:08 +00:00
zebra: rib: use nexthop ptr in rib_add/delete
This simplifies the API for the following blackhole rework. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
09a484dd1d
commit
fd36be7e15
@ -36,7 +36,8 @@ DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
|
|||||||
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
|
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
|
||||||
|
|
||||||
/* check if nexthops are same, non-recursive */
|
/* check if nexthops are same, non-recursive */
|
||||||
int nexthop_same_no_recurse(struct nexthop *next1, struct nexthop *next2)
|
int nexthop_same_no_recurse(const struct nexthop *next1,
|
||||||
|
const struct nexthop *next2)
|
||||||
{
|
{
|
||||||
if (next1->type != next2->type)
|
if (next1->type != next2->type)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -135,8 +135,8 @@ void nexthop_add_labels(struct nexthop *, enum lsp_types_t, u_int8_t,
|
|||||||
void nexthop_del_labels(struct nexthop *);
|
void nexthop_del_labels(struct nexthop *);
|
||||||
|
|
||||||
extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type);
|
extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type);
|
||||||
extern int nexthop_same_no_recurse(struct nexthop *next1,
|
extern int nexthop_same_no_recurse(const struct nexthop *next1,
|
||||||
struct nexthop *next2);
|
const struct nexthop *next2);
|
||||||
extern int nexthop_labels_match(struct nexthop *nh1, struct nexthop *nh2);
|
extern int nexthop_labels_match(struct nexthop *nh1, struct nexthop *nh2);
|
||||||
|
|
||||||
extern const char *nexthop2str(struct nexthop *nexthop, char *str, int size);
|
extern const char *nexthop2str(struct nexthop *nexthop, char *str, int size);
|
||||||
|
@ -177,6 +177,10 @@ static void connected_update(struct interface *ifp, struct connected *ifc)
|
|||||||
void connected_up_ipv4(struct interface *ifp, struct connected *ifc)
|
void connected_up_ipv4(struct interface *ifp, struct connected *ifc)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
|
struct nexthop nh = {
|
||||||
|
.type = NEXTHOP_TYPE_IFINDEX,
|
||||||
|
.ifindex = ifp->ifindex,
|
||||||
|
};
|
||||||
|
|
||||||
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
||||||
return;
|
return;
|
||||||
@ -192,12 +196,10 @@ void connected_up_ipv4(struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
rib_add(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
rib_add(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
||||||
&p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric,
|
&p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0);
|
||||||
0, 0);
|
|
||||||
|
|
||||||
rib_add(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
rib_add(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
||||||
&p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric,
|
&p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0);
|
||||||
0, 0);
|
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -306,6 +308,10 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
|
|||||||
void connected_down_ipv4(struct interface *ifp, struct connected *ifc)
|
void connected_down_ipv4(struct interface *ifp, struct connected *ifc)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
|
struct nexthop nh = {
|
||||||
|
.type = NEXTHOP_TYPE_IFINDEX,
|
||||||
|
.ifindex = ifp->ifindex,
|
||||||
|
};
|
||||||
|
|
||||||
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
||||||
return;
|
return;
|
||||||
@ -323,10 +329,10 @@ void connected_down_ipv4(struct interface *ifp, struct connected *ifc)
|
|||||||
/* Same logic as for connected_up_ipv4(): push the changes into the
|
/* Same logic as for connected_up_ipv4(): push the changes into the
|
||||||
* head. */
|
* head. */
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
||||||
&p, NULL, NULL, ifp->ifindex, 0, 0);
|
&p, NULL, &nh, 0, 0);
|
||||||
|
|
||||||
rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
|
rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
|
||||||
0, &p, NULL, NULL, ifp->ifindex, 0, 0);
|
0, &p, NULL, &nh, 0, 0);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -384,6 +390,10 @@ void connected_delete_ipv4(struct interface *ifp, int flags,
|
|||||||
void connected_up_ipv6(struct interface *ifp, struct connected *ifc)
|
void connected_up_ipv6(struct interface *ifp, struct connected *ifc)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
|
struct nexthop nh = {
|
||||||
|
.type = NEXTHOP_TYPE_IFINDEX,
|
||||||
|
.ifindex = ifp->ifindex,
|
||||||
|
};
|
||||||
|
|
||||||
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
||||||
return;
|
return;
|
||||||
@ -400,8 +410,7 @@ void connected_up_ipv6(struct interface *ifp, struct connected *ifc)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
rib_add(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
rib_add(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
||||||
&p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric,
|
&p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0);
|
||||||
0, 0);
|
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -489,6 +498,10 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
|
|||||||
void connected_down_ipv6(struct interface *ifp, struct connected *ifc)
|
void connected_down_ipv6(struct interface *ifp, struct connected *ifc)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
|
struct nexthop nh = {
|
||||||
|
.type = NEXTHOP_TYPE_IFINDEX,
|
||||||
|
.ifindex = ifp->ifindex,
|
||||||
|
};
|
||||||
|
|
||||||
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
||||||
return;
|
return;
|
||||||
@ -501,7 +514,7 @@ void connected_down_ipv6(struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
|
rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
|
||||||
0, &p, NULL, NULL, ifp->ifindex, 0, 0);
|
0, &p, NULL, &nh, 0, 0);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
|
@ -849,6 +849,7 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
union sockunion dest, mask, gate;
|
union sockunion dest, mask, gate;
|
||||||
char ifname[INTERFACE_NAMSIZ + 1];
|
char ifname[INTERFACE_NAMSIZ + 1];
|
||||||
short ifnlen = 0;
|
short ifnlen = 0;
|
||||||
|
struct nexthop nh;
|
||||||
|
|
||||||
zebra_flags = 0;
|
zebra_flags = 0;
|
||||||
|
|
||||||
@ -1015,19 +1016,22 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
*/
|
*/
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
||||||
NULL, 0, 0, 0);
|
NULL, 0, 0);
|
||||||
|
|
||||||
|
memset(&nh, 0, sizeof(nh));
|
||||||
|
nh.type = NEXTHOP_TYPE_IPV4;
|
||||||
|
nh.gate.ipv4 = gate.sin;
|
||||||
|
|
||||||
union g_addr ggate = {.ipv4 = gate.sin.sin_addr};
|
|
||||||
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
|| rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
&ggate, NULL, 0, 0, 0, 0, 0);
|
&nh, 0, 0, 0, 0);
|
||||||
else
|
else
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
&ggate, 0, 0, 0);
|
&nh, 0, 0);
|
||||||
}
|
}
|
||||||
if (dest.sa.sa_family == AF_INET6) {
|
if (dest.sa.sa_family == AF_INET6) {
|
||||||
/* One day we might have a debug section here like one in the
|
/* One day we might have a debug section here like one in the
|
||||||
@ -1057,19 +1061,24 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
*/
|
*/
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
||||||
NULL, 0, 0, 0);
|
NULL, NULL, 0, 0);
|
||||||
|
|
||||||
|
memset(&nh, 0, sizeof(nh));
|
||||||
|
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
|
||||||
|
: NEXTHOP_TYPE_IPV6;
|
||||||
|
nh.gate.ipv6 = gate.sin6;
|
||||||
|
nh.ifindex = ifindex;
|
||||||
|
|
||||||
union g_addr ggate = {.ipv6 = gate.sin6.sin6_addr};
|
|
||||||
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
|| rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
&ggate, NULL, ifindex, 0, 0, 0, 0);
|
&nh, 0, 0, 0, 0);
|
||||||
else
|
else
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
&ggate, ifindex, 0, 0);
|
&nh, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,8 +496,6 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
|
|||||||
struct route_entry *newre;
|
struct route_entry *newre;
|
||||||
struct route_entry *same;
|
struct route_entry *same;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct nexthop *nhop;
|
|
||||||
union g_addr *gate;
|
|
||||||
route_map_result_t ret = RMAP_MATCH;
|
route_map_result_t ret = RMAP_MATCH;
|
||||||
|
|
||||||
if (rmap_name)
|
if (rmap_name)
|
||||||
@ -529,17 +527,10 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
|
|||||||
|
|
||||||
|
|
||||||
if (re->nexthop_num == 1) {
|
if (re->nexthop_num == 1) {
|
||||||
nhop = re->nexthop;
|
|
||||||
if (nhop->type == NEXTHOP_TYPE_IFINDEX)
|
|
||||||
gate = NULL;
|
|
||||||
else
|
|
||||||
gate = (union g_addr *)&nhop->gate.ipv4;
|
|
||||||
|
|
||||||
rib_add(AFI_IP, SAFI_UNICAST, re->vrf_id,
|
rib_add(AFI_IP, SAFI_UNICAST, re->vrf_id,
|
||||||
ZEBRA_ROUTE_TABLE, re->table, 0, &p,
|
ZEBRA_ROUTE_TABLE, re->table, 0, &p,
|
||||||
NULL, gate,
|
NULL, re->nexthop,
|
||||||
(union g_addr *)&nhop->src.ipv4,
|
zebrad.rtm_table_default,
|
||||||
nhop->ifindex, zebrad.rtm_table_default,
|
|
||||||
re->metric, re->mtu,
|
re->metric, re->mtu,
|
||||||
zebra_import_table_distance[AFI_IP]
|
zebra_import_table_distance[AFI_IP]
|
||||||
[re->table]);
|
[re->table]);
|
||||||
@ -580,7 +571,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
|
|||||||
p.u.prefix4 = rn->p.u.prefix4;
|
p.u.prefix4 = rn->p.u.prefix4;
|
||||||
|
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
|
rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
|
||||||
re->table, re->flags, &p, NULL, NULL, 0,
|
re->table, re->flags, &p, NULL, NULL,
|
||||||
zebrad.rtm_table_default, re->metric);
|
zebrad.rtm_table_default, re->metric);
|
||||||
}
|
}
|
||||||
/* DD: Add IPv6 code */
|
/* DD: Add IPv6 code */
|
||||||
|
11
zebra/rib.h
11
zebra/rib.h
@ -294,18 +294,17 @@ extern int rib_uninstall_kernel(struct route_node *rn, struct route_entry *re);
|
|||||||
* also implicitly withdraw equal prefix of same type. */
|
* also implicitly withdraw equal prefix of same type. */
|
||||||
extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||||
u_short instance, int flags, struct prefix *p,
|
u_short instance, int flags, struct prefix *p,
|
||||||
struct prefix_ipv6 *src_p, union g_addr *gate,
|
struct prefix_ipv6 *src_p, const struct nexthop *nh,
|
||||||
union g_addr *src, ifindex_t ifindex, u_int32_t table_id,
|
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
|
||||||
u_int32_t metric, u_int32_t mtu, u_char distance);
|
u_char distance);
|
||||||
|
|
||||||
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
|
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
|
||||||
struct prefix_ipv6 *src_p, struct route_entry *);
|
struct prefix_ipv6 *src_p, struct route_entry *);
|
||||||
|
|
||||||
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||||
u_short instance, int flags, struct prefix *p,
|
u_short instance, int flags, struct prefix *p,
|
||||||
struct prefix_ipv6 *src_p, union g_addr *gate,
|
struct prefix_ipv6 *src_p, const struct nexthop *nh,
|
||||||
ifindex_t ifindex, u_int32_t table_id,
|
u_int32_t table_id, u_int32_t metric);
|
||||||
u_int32_t metric);
|
|
||||||
|
|
||||||
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t,
|
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t,
|
||||||
union g_addr *,
|
union g_addr *,
|
||||||
|
@ -365,11 +365,31 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
|
|||||||
afi = AFI_IP6;
|
afi = AFI_IP6;
|
||||||
|
|
||||||
if (h->nlmsg_type == RTM_NEWROUTE) {
|
if (h->nlmsg_type == RTM_NEWROUTE) {
|
||||||
if (!tb[RTA_MULTIPATH])
|
if (!tb[RTA_MULTIPATH]) {
|
||||||
|
struct nexthop nh;
|
||||||
|
size_t sz = (afi == AFI_IP) ? 4 : 16;
|
||||||
|
|
||||||
|
memset(&nh, 0, sizeof(nh));
|
||||||
|
if (index && !gate)
|
||||||
|
nh.type = NEXTHOP_TYPE_IFINDEX;
|
||||||
|
else if (index && gate)
|
||||||
|
nh.type = (afi == AFI_IP)
|
||||||
|
? NEXTHOP_TYPE_IPV4_IFINDEX
|
||||||
|
: NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||||
|
else if (!index && gate)
|
||||||
|
nh.type = (afi == AFI_IP)
|
||||||
|
? NEXTHOP_TYPE_IPV4
|
||||||
|
: NEXTHOP_TYPE_IPV6;
|
||||||
|
else
|
||||||
|
nh.type = NEXTHOP_TYPE_BLACKHOLE;
|
||||||
|
nh.ifindex = index;
|
||||||
|
if (prefsrc)
|
||||||
|
memcpy(&nh.src, prefsrc, sz);
|
||||||
|
if (gate)
|
||||||
|
memcpy(&nh.gate, gate, sz);
|
||||||
rib_add(afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
rib_add(afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||||
0, flags, &p, NULL, gate, prefsrc, index, table,
|
0, flags, &p, NULL, &nh, table, metric, mtu, 0);
|
||||||
metric, mtu, 0);
|
} else {
|
||||||
else {
|
|
||||||
/* This is a multipath route */
|
/* This is a multipath route */
|
||||||
|
|
||||||
struct route_entry *re;
|
struct route_entry *re;
|
||||||
@ -444,41 +464,35 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
|
|||||||
NULL, re);
|
NULL, re);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!tb[RTA_MULTIPATH])
|
if (!tb[RTA_MULTIPATH]) {
|
||||||
rib_delete(afi, SAFI_UNICAST, vrf_id,
|
struct nexthop nh;
|
||||||
ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate,
|
size_t sz = (afi == AFI_IP) ? 4 : 16;
|
||||||
index, table, metric);
|
|
||||||
else {
|
|
||||||
struct rtnexthop *rtnh =
|
|
||||||
(struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]);
|
|
||||||
|
|
||||||
len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (len < (int)sizeof(*rtnh)
|
|
||||||
|| rtnh->rtnh_len > len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
gate = NULL;
|
|
||||||
if (rtnh->rtnh_len > sizeof(*rtnh)) {
|
|
||||||
memset(tb, 0, sizeof(tb));
|
|
||||||
netlink_parse_rtattr(
|
|
||||||
tb, RTA_MAX, RTNH_DATA(rtnh),
|
|
||||||
rtnh->rtnh_len - sizeof(*rtnh));
|
|
||||||
if (tb[RTA_GATEWAY])
|
|
||||||
gate = RTA_DATA(
|
|
||||||
tb[RTA_GATEWAY]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
memset(&nh, 0, sizeof(nh));
|
||||||
|
if (index && !gate)
|
||||||
|
nh.type = NEXTHOP_TYPE_IFINDEX;
|
||||||
|
else if (index && gate)
|
||||||
|
nh.type = (afi == AFI_IP)
|
||||||
|
? NEXTHOP_TYPE_IPV4_IFINDEX
|
||||||
|
: NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||||
|
else if (!index && gate)
|
||||||
|
nh.type = (afi == AFI_IP)
|
||||||
|
? NEXTHOP_TYPE_IPV4
|
||||||
|
: NEXTHOP_TYPE_IPV6;
|
||||||
|
else
|
||||||
|
nh.type = NEXTHOP_TYPE_BLACKHOLE;
|
||||||
|
nh.ifindex = index;
|
||||||
if (gate)
|
if (gate)
|
||||||
|
memcpy(&nh.gate, gate, sz);
|
||||||
rib_delete(afi, SAFI_UNICAST, vrf_id,
|
rib_delete(afi, SAFI_UNICAST, vrf_id,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, flags,
|
ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, &nh,
|
||||||
&p, NULL, gate, index,
|
|
||||||
table, metric);
|
table, metric);
|
||||||
|
} else {
|
||||||
len -= NLMSG_ALIGN(rtnh->rtnh_len);
|
/* XXX: need to compare the entire list of nexthops
|
||||||
rtnh = RTNH_NEXT(rtnh);
|
* here for NLM_F_APPEND stupidity */
|
||||||
}
|
rib_delete(afi, SAFI_UNICAST, vrf_id,
|
||||||
|
ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL,
|
||||||
|
NULL, table, metric);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,8 @@
|
|||||||
static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry)
|
static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry)
|
||||||
{
|
{
|
||||||
struct prefix prefix;
|
struct prefix prefix;
|
||||||
struct in_addr tmpaddr, gateway;
|
struct in_addr tmpaddr;
|
||||||
union g_addr *ggateway;
|
struct nexthop nh;
|
||||||
u_char zebra_flags = 0;
|
u_char zebra_flags = 0;
|
||||||
|
|
||||||
if (routeEntry->ipRouteInfo.re_ire_type & IRE_CACHETABLE)
|
if (routeEntry->ipRouteInfo.re_ire_type & IRE_CACHETABLE)
|
||||||
@ -93,11 +93,12 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry)
|
|||||||
tmpaddr.s_addr = routeEntry->ipRouteMask;
|
tmpaddr.s_addr = routeEntry->ipRouteMask;
|
||||||
prefix.prefixlen = ip_masklen(tmpaddr);
|
prefix.prefixlen = ip_masklen(tmpaddr);
|
||||||
|
|
||||||
gateway.s_addr = routeEntry->ipRouteNextHop;
|
memset(&nh, 0, sizeof(nh));
|
||||||
ggateway = (union g_addr *)&gateway;
|
nh.type = NEXTHOP_TYPE_IPV4;
|
||||||
|
nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop;
|
||||||
|
|
||||||
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
|
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
|
||||||
zebra_flags, &prefix, NULL, ggateway, NULL, 0, 0, 0, 0, 0);
|
zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void route_read(struct zebra_ns *zns)
|
void route_read(struct zebra_ns *zns)
|
||||||
|
@ -2273,16 +2273,15 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
|
|||||||
|
|
||||||
void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||||
u_short instance, int flags, struct prefix *p,
|
u_short instance, int flags, struct prefix *p,
|
||||||
struct prefix_ipv6 *src_p, union g_addr *gate,
|
struct prefix_ipv6 *src_p, const struct nexthop *nh,
|
||||||
ifindex_t ifindex, u_int32_t table_id,
|
u_int32_t table_id, u_int32_t metric)
|
||||||
u_int32_t metric)
|
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *re;
|
struct route_entry *re;
|
||||||
struct route_entry *fib = NULL;
|
struct route_entry *fib = NULL;
|
||||||
struct route_entry *same = NULL;
|
struct route_entry *same = NULL;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *rtnh;
|
||||||
char buf2[INET6_ADDRSTRLEN];
|
char buf2[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
assert(!src_p || afi == AFI_IP6);
|
assert(!src_p || afi == AFI_IP6);
|
||||||
@ -2332,9 +2331,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
if (re->type == ZEBRA_ROUTE_KERNEL &&
|
if (re->type == ZEBRA_ROUTE_KERNEL &&
|
||||||
re->metric != metric)
|
re->metric != metric)
|
||||||
continue;
|
continue;
|
||||||
if (re->type == ZEBRA_ROUTE_CONNECT && (nexthop = re->nexthop)
|
if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->nexthop)
|
||||||
&& nexthop->type == NEXTHOP_TYPE_IFINDEX) {
|
&& rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) {
|
||||||
if (nexthop->ifindex != ifindex)
|
if (rtnh->ifindex != nh->ifindex)
|
||||||
continue;
|
continue;
|
||||||
if (re->refcnt) {
|
if (re->refcnt) {
|
||||||
re->refcnt--;
|
re->refcnt--;
|
||||||
@ -2347,14 +2346,12 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
}
|
}
|
||||||
/* Make sure that the route found has the same gateway. */
|
/* Make sure that the route found has the same gateway. */
|
||||||
else {
|
else {
|
||||||
if (gate == NULL) {
|
if (nh == NULL) {
|
||||||
same = re;
|
same = re;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (ALL_NEXTHOPS(re->nexthop, nexthop))
|
for (ALL_NEXTHOPS(re->nexthop, rtnh))
|
||||||
if (IPV4_ADDR_SAME(&nexthop->gate.ipv4, &gate->ipv4)
|
if (nexthop_same_no_recurse(rtnh, nh)) {
|
||||||
|| IPV6_ADDR_SAME(&nexthop->gate.ipv6,
|
|
||||||
gate)) {
|
|
||||||
same = re;
|
same = re;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2375,9 +2372,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
}
|
}
|
||||||
if (allow_delete) {
|
if (allow_delete) {
|
||||||
/* Unset flags. */
|
/* Unset flags. */
|
||||||
for (nexthop = fib->nexthop; nexthop;
|
for (rtnh = fib->nexthop; rtnh;
|
||||||
nexthop = nexthop->next)
|
rtnh = rtnh->next)
|
||||||
UNSET_FLAG(nexthop->flags,
|
UNSET_FLAG(rtnh->flags,
|
||||||
NEXTHOP_FLAG_FIB);
|
NEXTHOP_FLAG_FIB);
|
||||||
|
|
||||||
UNSET_FLAG(fib->status,
|
UNSET_FLAG(fib->status,
|
||||||
@ -2391,22 +2388,22 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IS_ZEBRA_DEBUG_RIB) {
|
if (IS_ZEBRA_DEBUG_RIB) {
|
||||||
if (gate)
|
if (nh)
|
||||||
rnode_debug(
|
rnode_debug(
|
||||||
rn, vrf_id,
|
rn, vrf_id,
|
||||||
"via %s ifindex %d type %d "
|
"via %s ifindex %d type %d "
|
||||||
"doesn't exist in rib",
|
"doesn't exist in rib",
|
||||||
inet_ntop(
|
inet_ntop(
|
||||||
family2afi(afi), gate,
|
family2afi(afi), &nh->gate,
|
||||||
buf2,
|
buf2,
|
||||||
INET_ADDRSTRLEN), /* FIXME
|
INET_ADDRSTRLEN), /* FIXME
|
||||||
*/
|
*/
|
||||||
ifindex, type);
|
nh->ifindex, type);
|
||||||
else
|
else
|
||||||
rnode_debug(
|
rnode_debug(
|
||||||
rn, vrf_id,
|
rn, vrf_id,
|
||||||
"ifindex %d type %d doesn't exist in rib",
|
"type %d doesn't exist in rib",
|
||||||
ifindex, type);
|
type);
|
||||||
}
|
}
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
return;
|
return;
|
||||||
@ -2423,15 +2420,14 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
|
|
||||||
int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
||||||
int flags, struct prefix *p, struct prefix_ipv6 *src_p,
|
int flags, struct prefix *p, struct prefix_ipv6 *src_p,
|
||||||
union g_addr *gate, union g_addr *src, ifindex_t ifindex,
|
const struct nexthop *nh, u_int32_t table_id, u_int32_t metric,
|
||||||
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
|
u_int32_t mtu, u_char distance)
|
||||||
u_char distance)
|
|
||||||
{
|
{
|
||||||
struct route_entry *re;
|
struct route_entry *re;
|
||||||
struct route_entry *same = NULL;
|
struct route_entry *same = NULL;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *rtnh;
|
||||||
|
|
||||||
assert(!src_p || afi == AFI_IP6);
|
assert(!src_p || afi == AFI_IP6);
|
||||||
|
|
||||||
@ -2480,9 +2476,9 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Duplicate system route comes in. */
|
/* Duplicate system route comes in. */
|
||||||
else if ((nexthop = re->nexthop)
|
else if ((rtnh = re->nexthop)
|
||||||
&& nexthop->type == NEXTHOP_TYPE_IFINDEX
|
&& rtnh->type == NEXTHOP_TYPE_IFINDEX
|
||||||
&& nexthop->ifindex == ifindex
|
&& rtnh->ifindex == nh->ifindex
|
||||||
&& !CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
|
&& !CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
|
||||||
re->refcnt++;
|
re->refcnt++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2503,29 +2499,14 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
|||||||
re->nexthop_num = 0;
|
re->nexthop_num = 0;
|
||||||
re->uptime = time(NULL);
|
re->uptime = time(NULL);
|
||||||
|
|
||||||
/* Nexthop settings. */
|
rtnh = nexthop_new();
|
||||||
if (gate) {
|
*rtnh = *nh;
|
||||||
if (afi == AFI_IP6) {
|
route_entry_nexthop_add(re, rtnh);
|
||||||
if (ifindex)
|
|
||||||
route_entry_nexthop_ipv6_ifindex_add(
|
|
||||||
re, &gate->ipv6, ifindex);
|
|
||||||
else
|
|
||||||
route_entry_nexthop_ipv6_add(re, &gate->ipv6);
|
|
||||||
} else {
|
|
||||||
if (ifindex)
|
|
||||||
route_entry_nexthop_ipv4_ifindex_add(
|
|
||||||
re, &gate->ipv4, &src->ipv4, ifindex);
|
|
||||||
else
|
|
||||||
route_entry_nexthop_ipv4_add(re, &gate->ipv4,
|
|
||||||
&src->ipv4);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
route_entry_nexthop_ifindex_add(re, ifindex);
|
|
||||||
|
|
||||||
/* If this route is kernel route, set FIB flag to the route. */
|
/* If this route is kernel route, set FIB flag to the route. */
|
||||||
if (RIB_SYSTEM_ROUTE(re))
|
if (RIB_SYSTEM_ROUTE(re))
|
||||||
for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
|
for (rtnh = re->nexthop; rtnh; rtnh = rtnh->next)
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
SET_FLAG(rtnh->flags, NEXTHOP_FLAG_FIB);
|
||||||
|
|
||||||
/* Link new rib to node.*/
|
/* Link new rib to node.*/
|
||||||
if (IS_ZEBRA_DEBUG_RIB) {
|
if (IS_ZEBRA_DEBUG_RIB) {
|
||||||
|
Loading…
Reference in New Issue
Block a user