From 3c7c91d0bd04d4db0a47db5717d36671ecc96a1b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 24 Apr 2014 17:41:43 +0200 Subject: [PATCH] zebra: receive ZAPI IPv6 source prefix Check and read the IPv6 source prefix on ZAPI messages, and pass it down to the RIB functions (which do nothing with it yet.) Since the RIB functions now all have a new extra argument, this also updates the kernel route read functions to supply NULL. Signed-off-by: David Lamparter --- lib/zclient.h | 1 + zebra/connected.c | 12 ++++++------ zebra/kernel_socket.c | 12 ++++++------ zebra/redistribute.c | 6 +++--- zebra/rib.h | 8 ++++---- zebra/rt_netlink.c | 16 ++++++++-------- zebra/rtread_getmsg.c | 2 +- zebra/zebra_rib.c | 9 +++++---- zebra/zserv.c | 36 ++++++++++++++++++++++++++++++------ 9 files changed, 64 insertions(+), 38 deletions(-) diff --git a/lib/zclient.h b/lib/zclient.h index ccb7b0509d..7808fd804f 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -114,6 +114,7 @@ struct zclient #define ZAPI_MESSAGE_METRIC 0x08 #define ZAPI_MESSAGE_TAG 0x10 #define ZAPI_MESSAGE_MTU 0x20 +#define ZAPI_MESSAGE_SRCPFX 0x40 /* Zserv protocol message header */ struct zserv_header diff --git a/zebra/connected.c b/zebra/connected.c index ebd948252e..0ceaddc8e3 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -201,11 +201,11 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) return; rib_add (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, NULL, ifp->ifindex, + 0, 0, &p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, 0); rib_add (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, NULL, ifp->ifindex, + 0, 0, &p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) @@ -331,10 +331,10 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) /* Same logic as for connected_up_ipv4(): push the changes into the head. */ rib_delete (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, ifp->ifindex, 0); + 0, 0, &p, NULL, NULL, ifp->ifindex, 0); rib_delete (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, ifp->ifindex, 0); + 0, 0, &p, NULL, NULL, ifp->ifindex, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug ("%u: IF %s IPv4 address down, scheduling RIB processing", @@ -407,7 +407,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) #endif rib_add (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, NULL, ifp->ifindex, + 0, 0, &p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) @@ -507,7 +507,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) return; rib_delete (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, ifp->ifindex, 0); + 0, 0, &p, NULL, NULL, ifp->ifindex, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing", diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index fd059dfee7..20a0472195 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -992,17 +992,17 @@ rtm_read (struct rt_msghdr *rtm) */ if (rtm->rtm_type == RTM_CHANGE) rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, - 0, zebra_flags, &p, NULL, 0, 0); + 0, zebra_flags, &p, NULL, NULL, 0, 0); union g_addr ggate = { .ipv4 = gate.sin.sin_addr }; if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, - &p, &ggate, NULL, 0, 0, 0, 0, 0); + &p, NULL, &ggate, NULL, 0, 0, 0, 0, 0); else rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, - 0, zebra_flags, &p, &ggate, 0, 0); + 0, zebra_flags, &p, NULL, &ggate, 0, 0); } if (dest.sa.sa_family == AF_INET6) { @@ -1034,18 +1034,18 @@ rtm_read (struct rt_msghdr *rtm) */ if (rtm->rtm_type == RTM_CHANGE) rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, - 0, zebra_flags, &p, NULL, 0, 0); + 0, zebra_flags, &p, NULL, NULL, 0, 0); union g_addr ggate = { .ipv6 = gate.sin6.sin6_addr }; if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) rib_add (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, - 0, zebra_flags, &p, &ggate, NULL, ifindex, + 0, zebra_flags, &p, NULL, &ggate, NULL, ifindex, 0, 0, 0, 0); else rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, - 0, zebra_flags, &p, &ggate, ifindex, 0); + 0, zebra_flags, &p, NULL, &ggate, ifindex, 0); } } diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 4b2aabd186..435122cfe7 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -519,7 +519,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char gate = (union g_addr *)&nhop->gate.ipv4; rib_add (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE, - rib->table, 0, &p, gate, (union g_addr *)&nhop->src.ipv4, + rib->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4, nhop->ifindex, zebrad.rtm_table_default, rib->metric, rib->mtu, zebra_import_table_distance[AFI_IP][rib->table]); @@ -541,7 +541,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char for (nhop = rib->nexthop; nhop; nhop = nhop->next) rib_copy_nexthops(newrib, nhop); - rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, newrib); + rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, NULL, newrib); } } } @@ -565,7 +565,7 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib) p.u.prefix4 = rn->p.u.prefix4; rib_delete (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE, - rib->table, rib->flags, &p, NULL, + rib->table, rib->flags, &p, NULL, NULL, 0, zebrad.rtm_table_default); } /* DD: Add IPv6 code */ diff --git a/zebra/rib.h b/zebra/rib.h index d80ea6cbd8..fceab93d1a 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -342,17 +342,17 @@ extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib); * 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, u_short instance, int flags, struct prefix *p, - union g_addr *gate, union g_addr *src, + struct prefix_ipv6 *src_p, union g_addr *gate, union g_addr *src, ifindex_t ifindex, u_int32_t table_id, u_int32_t, u_int32_t, u_char); extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *, - struct rib *); + struct prefix_ipv6 *src_p, struct rib *); extern int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, - union g_addr *gate, ifindex_t ifindex, - u_int32_t table_id); + struct prefix_ipv6 *src_p, union g_addr *gate, + ifindex_t ifindex, u_int32_t table_id); extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *, struct route_node **rn_out); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index d2781f4c4e..585b80f979 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -238,7 +238,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, if (!tb[RTA_MULTIPATH]) rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, - 0, flags, &p, gate, src, index, + 0, flags, &p, NULL, gate, src, index, table, metric, mtu, 0); else { @@ -296,7 +296,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, if (rib->nexthop_num == 0) XFREE (MTYPE_RIB, rib); else - rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib); + rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib); } } if (rtm->rtm_family == AF_INET6) @@ -306,7 +306,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, p.prefixlen = rtm->rtm_dst_len; rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, - 0, flags, &p, gate, src, index, + 0, flags, &p, NULL, gate, src, index, table, metric, mtu, 0); } @@ -431,7 +431,7 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, { if (!tb[RTA_MULTIPATH]) rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, - 0, 0, &p, gate, src, index, + 0, 0, &p, NULL, gate, src, index, table, metric, mtu, 0); else { @@ -490,12 +490,12 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, if (rib->nexthop_num == 0) XFREE (MTYPE_RIB, rib); else - rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib); + rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib); } } else rib_delete (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, - &p, gate, index, table); + &p, NULL, gate, index, table); } if (rtm->rtm_family == AF_INET6) @@ -516,11 +516,11 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, if (h->nlmsg_type == RTM_NEWROUTE) rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, - 0, 0, &p, gate, src, index, + 0, 0, &p, NULL, gate, src, index, table, metric, mtu, 0); else rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, - 0, zebra_flags, &p, gate, index, table); + 0, zebra_flags, &p, NULL, gate, index, table); } return 0; diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index c6eee75174..1007d0ac18 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -94,7 +94,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry) ggateway = (union g_addr *)&gateway; rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, - zebra_flags, &prefix, ggateway, NULL, 0, 0, 0, 0, 0); + zebra_flags, &prefix, NULL, ggateway, NULL, 0, 0, 0, 0, 0); } void diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 59893b1a0f..d638ceab7f 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2585,7 +2585,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id) int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, - struct rib *rib) + struct prefix_ipv6 *src_p, struct rib *rib) { struct route_table *table; struct route_node *rn; @@ -2674,8 +2674,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, - int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex, - u_int32_t table_id) + int flags, struct prefix *p, struct prefix_ipv6 *src_p, + union g_addr *gate, ifindex_t ifindex, u_int32_t table_id) { struct route_table *table; struct route_node *rn; @@ -2815,7 +2815,8 @@ rib_delete (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, - union g_addr *gate, union g_addr *src, ifindex_t ifindex, + struct prefix_ipv6 *src_p, union g_addr *gate, + union g_addr *src, ifindex_t ifindex, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, u_char distance) { diff --git a/zebra/zserv.c b/zebra/zserv.c index 6f72ad1758..fd40ed123b 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1149,7 +1149,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) /* Table */ rib->table = zvrf->table_id; - ret = rib_add_multipath (AFI_IP, safi, &p, rib); + ret = rib_add_multipath (AFI_IP, safi, &p, NULL, rib); /* Stats */ if (ret > 0) @@ -1243,7 +1243,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) table_id = zvrf->table_id; rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance, - api.flags, &p, nexthop_p, ifindex, table_id); + api.flags, &p, NULL, nexthop_p, ifindex, table_id); client->v4_route_del_cnt++; return 0; } @@ -1378,7 +1378,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct /* Table */ rib->table = zvrf->table_id; - ret = rib_add_multipath (AFI_IP6, safi, &p, rib); + ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, rib); /* Stats */ if (ret > 0) client->v4_route_add_cnt++; @@ -1399,6 +1399,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) u_char nexthop_num; u_char nexthop_type; struct prefix p; + struct prefix_ipv6 src_p, *src_pp; safi_t safi; static struct in6_addr nexthops[MULTIPATH_NUM]; static unsigned int ifindices[MULTIPATH_NUM]; @@ -1426,6 +1427,17 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) p.prefixlen = stream_getc (s); stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen)); + if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX)) + { + memset (&src_p, 0, sizeof (struct prefix_ipv6)); + src_p.family = AF_INET6; + src_p.prefixlen = stream_getc (s); + stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); + src_pp = &src_p; + } + else + src_pp = NULL; + /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the rib to ensure that IPv6 multipathing works; need to coalesce * these. Clients should send the same number of paired set of @@ -1500,7 +1512,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) rib->vrf_id = zvrf_id (zvrf); rib->table = zvrf->table_id; - ret = rib_add_multipath (AFI_IP6, safi, &p, rib); + ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, rib); /* Stats */ if (ret > 0) client->v6_route_add_cnt++; @@ -1521,6 +1533,7 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) union g_addr *pnexthop = NULL; unsigned long ifindex; struct prefix p; + struct prefix_ipv6 src_p, *src_pp; s = client->ibuf; ifindex = 0; @@ -1539,6 +1552,17 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) p.prefixlen = stream_getc (s); stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen)); + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX)) + { + memset (&src_p, 0, sizeof (struct prefix_ipv6)); + src_p.family = AF_INET6; + src_p.prefixlen = stream_getc (s); + stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); + src_pp = &src_p; + } + else + src_pp = NULL; + /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { @@ -1582,10 +1606,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, - api.flags, &p, NULL, ifindex, client->rtm_table); + api.flags, &p, src_pp, NULL, ifindex, client->rtm_table); else rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, - api.flags, &p, pnexthop, ifindex, client->rtm_table); + api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table); client->v6_route_del_cnt++; return 0; -- 2.39.5