From 80cf4e451db10daf78d277f36a97ece1615f0450 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 4 Jan 2019 19:08:10 -0200 Subject: [PATCH] ripngd: make YANG operational-data VRF aware too Move the "state" container into the "instance" list and adapt the code accordingly. Signed-off-by: Renato Westphal --- ripngd/ripng_northbound.c | 189 +++++++++++++++++++++----------------- ripngd/ripngd.h | 1 + yang/frr-ripngd.yang | 134 +++++++++++++-------------- 3 files changed, 173 insertions(+), 151 deletions(-) diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c index 9784d0c20..3a1d52837 100644 --- a/ripngd/ripng_northbound.c +++ b/ripngd/ripng_northbound.c @@ -101,6 +101,39 @@ static int ripngd_instance_delete(enum nb_event event, return NB_OK; } +static const void *ripngd_instance_get_next(const void *parent_list_entry, + const void *list_entry) +{ + const struct ripng *ripng = list_entry; + + if (list_entry == NULL) + ripng = RB_MIN(ripng_instance_head, &ripng_instances); + else + ripng = RB_NEXT(ripng_instance_head, (struct ripng *)ripng); + + return ripng; +} + +static int ripngd_instance_get_keys(const void *list_entry, + struct yang_list_keys *keys) +{ + const struct ripng *ripng = list_entry; + + keys->num = 1; + strlcpy(keys->key[0], ripng->vrf_name, sizeof(keys->key[0])); + + return NB_OK; +} + +static const void * +ripngd_instance_lookup_entry(const void *parent_list_entry, + const struct yang_list_keys *keys) +{ + const char *vrf_name = keys->key[0]; + + return ripng_lookup_by_vrf_name(vrf_name); +} + /* * XPath: /frr-ripngd:ripngd/instance/allow-ecmp */ @@ -655,19 +688,15 @@ ripngd_instance_timers_update_interval_modify(enum nb_event event, } /* - * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor + * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor */ static const void * -ripngd_state_neighbors_neighbor_get_next(const void *parent_list_entry, - const void *list_entry) +ripngd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry, + const void *list_entry) { - struct ripng *ripng; + const struct ripng *ripng = parent_list_entry; struct listnode *node; - ripng = ripng_lookup_by_vrf_id(VRF_DEFAULT); - if (!ripng) - return NULL; - if (list_entry == NULL) node = listhead(ripng->peer_list); else @@ -676,8 +705,9 @@ ripngd_state_neighbors_neighbor_get_next(const void *parent_list_entry, return node; } -static int ripngd_state_neighbors_neighbor_get_keys(const void *list_entry, - struct yang_list_keys *keys) +static int +ripngd_instance_state_neighbors_neighbor_get_keys(const void *list_entry, + struct yang_list_keys *keys) { const struct listnode *node = list_entry; const struct ripng_peer *peer = listgetdata(node); @@ -689,21 +719,16 @@ static int ripngd_state_neighbors_neighbor_get_keys(const void *list_entry, return NB_OK; } -static const void * -ripngd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +static const void *ripngd_instance_state_neighbors_neighbor_lookup_entry( + const void *parent_list_entry, const struct yang_list_keys *keys) { - struct ripng *ripng; + const struct ripng *ripng = parent_list_entry; struct in6_addr address; struct ripng_peer *peer; struct listnode *node; yang_str2ipv6(keys->key[0], &address); - ripng = ripng_lookup_by_vrf_id(VRF_DEFAULT); - if (!ripng) - return NULL; - for (ALL_LIST_ELEMENTS_RO(ripng->peer_list, node, peer)) { if (IPV6_ADDR_SAME(&peer->addr, &address)) return node; @@ -713,11 +738,11 @@ ripngd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry, } /* - * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/address + * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/address */ static struct yang_data * -ripngd_state_neighbors_neighbor_address_get_elem(const char *xpath, - const void *list_entry) +ripngd_instance_state_neighbors_neighbor_address_get_elem( + const char *xpath, const void *list_entry) { const struct listnode *node = list_entry; const struct ripng_peer *peer = listgetdata(node); @@ -726,21 +751,21 @@ ripngd_state_neighbors_neighbor_address_get_elem(const char *xpath, } /* - * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/last-update + * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update */ static struct yang_data * -ripngd_state_neighbors_neighbor_last_update_get_elem(const char *xpath, - const void *list_entry) +ripngd_instance_state_neighbors_neighbor_last_update_get_elem( + const char *xpath, const void *list_entry) { /* TODO: yang:date-and-time is tricky */ return NULL; } /* - * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd + * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-packets-rcvd */ static struct yang_data * -ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem( +ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( const char *xpath, const void *list_entry) { const struct listnode *node = list_entry; @@ -750,11 +775,11 @@ ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem( } /* - * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd + * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-routes-rcvd */ static struct yang_data * -ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath, - const void *list_entry) +ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem( + const char *xpath, const void *list_entry) { const struct listnode *node = list_entry; const struct ripng_peer *peer = listgetdata(node); @@ -763,19 +788,15 @@ ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath, } /* - * XPath: /frr-ripngd:ripngd/state/routes/route + * XPath: /frr-ripngd:ripngd/instance/state/routes/route */ static const void * -ripngd_state_routes_route_get_next(const void *parent_list_entry, - const void *list_entry) +ripngd_instance_state_routes_route_get_next(const void *parent_list_entry, + const void *list_entry) { - struct ripng *ripng; + const struct ripng *ripng = parent_list_entry; struct agg_node *rn; - ripng = ripng_lookup_by_vrf_id(VRF_DEFAULT); - if (ripng == NULL) - return NULL; - if (list_entry == NULL) rn = agg_route_top(ripng->table); else @@ -786,8 +807,9 @@ ripngd_state_routes_route_get_next(const void *parent_list_entry, return rn; } -static int ripngd_state_routes_route_get_keys(const void *list_entry, - struct yang_list_keys *keys) +static int +ripngd_instance_state_routes_route_get_keys(const void *list_entry, + struct yang_list_keys *keys) { const struct agg_node *rn = list_entry; @@ -797,20 +819,15 @@ static int ripngd_state_routes_route_get_keys(const void *list_entry, return NB_OK; } -static const void * -ripngd_state_routes_route_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +static const void *ripngd_instance_state_routes_route_lookup_entry( + const void *parent_list_entry, const struct yang_list_keys *keys) { - struct ripng *ripng; + const struct ripng *ripng = parent_list_entry; struct prefix prefix; struct agg_node *rn; yang_str2ipv6p(keys->key[0], &prefix); - ripng = ripng_lookup_by_vrf_id(VRF_DEFAULT); - if (!ripng) - return NULL; - rn = agg_node_lookup(ripng->table, &prefix); if (!rn || !rn->info) return NULL; @@ -821,11 +838,11 @@ ripngd_state_routes_route_lookup_entry(const void *parent_list_entry, } /* - * XPath: /frr-ripngd:ripngd/state/routes/route/prefix + * XPath: /frr-ripngd:ripngd/instance/state/routes/route/prefix */ static struct yang_data * -ripngd_state_routes_route_prefix_get_elem(const char *xpath, - const void *list_entry) +ripngd_instance_state_routes_route_prefix_get_elem(const char *xpath, + const void *list_entry) { const struct agg_node *rn = list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); @@ -834,11 +851,11 @@ ripngd_state_routes_route_prefix_get_elem(const char *xpath, } /* - * XPath: /frr-ripngd:ripngd/state/routes/route/next-hop + * XPath: /frr-ripngd:ripngd/instance/state/routes/route/next-hop */ static struct yang_data * -ripngd_state_routes_route_next_hop_get_elem(const char *xpath, - const void *list_entry) +ripngd_instance_state_routes_route_next_hop_get_elem(const char *xpath, + const void *list_entry) { const struct agg_node *rn = list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); @@ -847,25 +864,26 @@ ripngd_state_routes_route_next_hop_get_elem(const char *xpath, } /* - * XPath: /frr-ripngd:ripngd/state/routes/route/interface + * XPath: /frr-ripngd:ripngd/instance/state/routes/route/interface */ static struct yang_data * -ripngd_state_routes_route_interface_get_elem(const char *xpath, - const void *list_entry) +ripngd_instance_state_routes_route_interface_get_elem(const char *xpath, + const void *list_entry) { const struct agg_node *rn = list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); + const struct ripng *ripng = ripng_info_get_instance(rinfo); return yang_data_new_string( - xpath, ifindex2ifname(rinfo->ifindex, VRF_DEFAULT)); + xpath, ifindex2ifname(rinfo->ifindex, ripng->vrf->vrf_id)); } /* - * XPath: /frr-ripngd:ripngd/state/routes/route/metric + * XPath: /frr-ripngd:ripngd/instance/state/routes/route/metric */ static struct yang_data * -ripngd_state_routes_route_metric_get_elem(const char *xpath, - const void *list_entry) +ripngd_instance_state_routes_route_metric_get_elem(const char *xpath, + const void *list_entry) { const struct agg_node *rn = list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); @@ -950,6 +968,9 @@ const struct frr_yang_module_info frr_ripngd_info = { .xpath = "/frr-ripngd:ripngd/instance", .cbs.create = ripngd_instance_create, .cbs.delete = ripngd_instance_delete, + .cbs.get_next = ripngd_instance_get_next, + .cbs.get_keys = ripngd_instance_get_keys, + .cbs.lookup_entry = ripngd_instance_lookup_entry, .cbs.cli_show = cli_show_router_ripng, }, { @@ -1046,48 +1067,48 @@ const struct frr_yang_module_info frr_ripngd_info = { .cbs.modify = ripngd_instance_timers_update_interval_modify, }, { - .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor", - .cbs.get_next = ripngd_state_neighbors_neighbor_get_next, - .cbs.get_keys = ripngd_state_neighbors_neighbor_get_keys, - .cbs.lookup_entry = ripngd_state_neighbors_neighbor_lookup_entry, + .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor", + .cbs.get_next = ripngd_instance_state_neighbors_neighbor_get_next, + .cbs.get_keys = ripngd_instance_state_neighbors_neighbor_get_keys, + .cbs.lookup_entry = ripngd_instance_state_neighbors_neighbor_lookup_entry, }, { - .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/address", - .cbs.get_elem = ripngd_state_neighbors_neighbor_address_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/address", + .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_address_get_elem, }, { - .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/last-update", - .cbs.get_elem = ripngd_state_neighbors_neighbor_last_update_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update", + .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_last_update_get_elem, }, { - .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd", - .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-packets-rcvd", + .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem, }, { - .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd", - .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-routes-rcvd", + .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem, }, { - .xpath = "/frr-ripngd:ripngd/state/routes/route", - .cbs.get_next = ripngd_state_routes_route_get_next, - .cbs.get_keys = ripngd_state_routes_route_get_keys, - .cbs.lookup_entry = ripngd_state_routes_route_lookup_entry, + .xpath = "/frr-ripngd:ripngd/instance/state/routes/route", + .cbs.get_next = ripngd_instance_state_routes_route_get_next, + .cbs.get_keys = ripngd_instance_state_routes_route_get_keys, + .cbs.lookup_entry = ripngd_instance_state_routes_route_lookup_entry, }, { - .xpath = "/frr-ripngd:ripngd/state/routes/route/prefix", - .cbs.get_elem = ripngd_state_routes_route_prefix_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/prefix", + .cbs.get_elem = ripngd_instance_state_routes_route_prefix_get_elem, }, { - .xpath = "/frr-ripngd:ripngd/state/routes/route/next-hop", - .cbs.get_elem = ripngd_state_routes_route_next_hop_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/next-hop", + .cbs.get_elem = ripngd_instance_state_routes_route_next_hop_get_elem, }, { - .xpath = "/frr-ripngd:ripngd/state/routes/route/interface", - .cbs.get_elem = ripngd_state_routes_route_interface_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/interface", + .cbs.get_elem = ripngd_instance_state_routes_route_interface_get_elem, }, { - .xpath = "/frr-ripngd:ripngd/state/routes/route/metric", - .cbs.get_elem = ripngd_state_routes_route_metric_get_elem, + .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/metric", + .cbs.get_elem = ripngd_instance_state_routes_route_metric_get_elem, }, { .xpath = "/frr-ripngd:clear-ripng-route", diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index e9894dd4c..d6c4394c6 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -372,6 +372,7 @@ struct ripng_offset_list { /* Extern variables. */ extern struct zebra_privs_t ripngd_privs; extern struct thread_master *master; +extern struct ripng_instance_head ripng_instances; /* Prototypes. */ extern void ripng_init(void); diff --git a/yang/frr-ripngd.yang b/yang/frr-ripngd.yang index 5d6d61564..6f7773f8b 100644 --- a/yang/frr-ripngd.yang +++ b/yang/frr-ripngd.yang @@ -199,82 +199,82 @@ module frr-ripngd { "Interval at which RIPng updates are sent."; } } - } - - /* - * Operational data. - */ - container state { - config false; - description - "Operational data."; - container neighbors { + /* + * Operational data. + */ + container state { + config false; description - "Neighbor information."; - list neighbor { - key "address"; + "Operational data."; + + container neighbors { description - "A RIPng neighbor."; - leaf address { - type inet:ipv6-address; - description - "IPv6 address that a RIPng neighbor is using as its - source address."; - } - leaf last-update { - type yang:date-and-time; - description - "The time when the most recent RIPng update was - received from this neighbor."; - } - leaf bad-packets-rcvd { - type yang:counter32; - description - "The number of RIPng invalid packets received from - this neighbor which were subsequently discarded - for any reason (e.g. a version 0 packet, or an - unknown command type)."; - } - leaf bad-routes-rcvd { - type yang:counter32; + "Neighbor information."; + list neighbor { + key "address"; description - "The number of routes received from this neighbor, - in valid RIPng packets, which were ignored for any - reason (e.g. unknown address family, or invalid - metric)."; + "A RIPng neighbor."; + leaf address { + type inet:ipv6-address; + description + "IPv6 address that a RIPng neighbor is using as its + source address."; + } + leaf last-update { + type yang:date-and-time; + description + "The time when the most recent RIPng update was + received from this neighbor."; + } + leaf bad-packets-rcvd { + type yang:counter32; + description + "The number of RIPng invalid packets received from + this neighbor which were subsequently discarded + for any reason (e.g. a version 0 packet, or an + unknown command type)."; + } + leaf bad-routes-rcvd { + type yang:counter32; + description + "The number of routes received from this neighbor, + in valid RIPng packets, which were ignored for any + reason (e.g. unknown address family, or invalid + metric)."; + } } } - } - container routes { - description - "Route information."; - list route { - key "prefix"; + container routes { description - "A RIPng IPv6 route."; - leaf prefix { - type inet:ipv6-prefix; + "Route information."; + list route { + key "prefix"; description - "IPv6 address and prefix length, in the format - specified in RFC6991."; - } - leaf next-hop { - type inet:ipv6-address; - description - "Next hop IPv6 address."; - } - leaf interface { - type string; - description - "The interface that the route uses."; - } - leaf metric { - type uint8 { - range "0..16"; + "A RIPng IPv6 route."; + leaf prefix { + type inet:ipv6-prefix; + description + "IPv6 address and prefix length, in the format + specified in RFC6991."; + } + leaf next-hop { + type inet:ipv6-address; + description + "Next hop IPv6 address."; + } + leaf interface { + type string; + description + "The interface that the route uses."; + } + leaf metric { + type uint8 { + range "0..16"; + } + description + "Route metric."; } - description - "Route metric."; } } } -- 2.39.2