diff options
45 files changed, 602 insertions, 655 deletions
diff --git a/.gitignore b/.gitignore index 40f6475a26..fb40ee52fe 100644 --- a/.gitignore +++ b/.gitignore @@ -113,3 +113,5 @@ refix .emacs.desktop* /test-suite.log +pceplib/test/*.log +pceplib/test/*.trs diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index cbd29c146a..6248ad927b 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -6048,10 +6048,12 @@ bool bgp_evpn_is_prefix_nht_supported(const struct prefix *pfx) * type-5 routes. It may be tweaked later on for other routes, or * even removed completely when all routes are handled. */ - if (pfx && pfx->family == AF_EVPN && - (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE || - evp->prefix.route_type == BGP_EVPN_IMET_ROUTE || - evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)) + if (pfx && pfx->family == AF_EVPN + && (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE + || evp->prefix.route_type == BGP_EVPN_AD_ROUTE + || evp->prefix.route_type == BGP_EVPN_ES_ROUTE + || evp->prefix.route_type == BGP_EVPN_IMET_ROUTE + || evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)) return true; return false; diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 867efb6099..aced0177ea 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -358,7 +358,7 @@ static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n"); vty_out(vty, "Origin codes: i - IGP, e - EGP, ? - incomplete\n"); vty_out(vty, - "EVPN type-1 prefix: [1]:[ESI]:[EthTag]:[IPlen]:[VTEP-IP]\n"); + "EVPN type-1 prefix: [1]:[EthTag]:[ESI]:[IPlen]:[VTEP-IP]\n"); vty_out(vty, "EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]\n"); vty_out(vty, "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n"); @@ -2723,7 +2723,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp, /* RD header and legend - once overall. */ if (rd_header && !json) { vty_out(vty, - "EVPN type-1 prefix: [1]:[ESI]:[EthTag]:[IPlen]:[VTEP-IP]\n"); + "EVPN type-1 prefix: [1]:[EthTag]:[ESI]:[IPlen]:[VTEP-IP]\n"); vty_out(vty, "EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]\n"); vty_out(vty, diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index f72f44f8a2..09abb69968 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -46,6 +46,7 @@ #include "bgpd/bgp_errors.h" #include "bgpd/bgp_network.h" #include "bgpd/bgp_zebra.h" +#include "bgpd/bgp_nht.h" extern struct zebra_privs_t bgpd_privs; @@ -603,6 +604,12 @@ static int bgp_accept(struct thread *thread) BGP_EVENT_ADD(peer, TCP_connection_open); } + /* + * If we are doing nht for a peer that is v6 LL based + * massage the event system to make things happy + */ + bgp_nht_interface_events(peer); + return 0; } diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 3b7ee8b0b6..96febcd5df 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -798,6 +798,9 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); + /* make coverity happy */ + assert(attr.aspath); + attr.local_pref = bgp->default_local_pref; if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) { diff --git a/configure.ac b/configure.ac index 917e791182..2897cfef66 100644 --- a/configure.ac +++ b/configure.ac @@ -1926,7 +1926,7 @@ dnl ----- dnl LTTng dnl ----- if test "$enable_lttng" = "yes"; then - PKG_CHECK_MODULES([UST], [lttng-ust >= 2.12.0], [ + PKG_CHECK_MODULES([UST], [lttng-ust >= 2.10.0], [ AC_DEFINE([HAVE_LTTNG], [1], [Enable LTTng support]) LTTNG=true ], [ diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst index b827afd6cc..681fc1173c 100644 --- a/doc/developer/logging.rst +++ b/doc/developer/logging.rst @@ -191,6 +191,10 @@ Networking data types ``%pNHs``: :frrfmtout:`1.2.3.4 if 15` — same as :c:func:`nexthop2str()` + ``%pNHcg``: :frrfmtout:`1.2.3.4` — compact gateway only + + ``%pNHci``: :frrfmtout:`eth0` — compact interface only + .. frrfmt:: %pBD (struct bgp_dest *) :frrfmtout:`fe80::1234/64` diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 2d1dafd7b4..3a9cd11055 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1252,7 +1252,7 @@ with the linux kernel for that. The following link has helpful references to man sysctl values: https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt Expected sysctl settings -^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------ .. option:: net.ipv4.ip_forward = 1 @@ -1286,7 +1286,7 @@ Expected sysctl settings is the default behavior for v4 as well. Optional sysctl settings -^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------ .. option:: net.ipv4.conf.{all,default,<interface>}.bc_forwarding = 0 diff --git a/lib/nexthop.c b/lib/nexthop.c index 757138b5b4..2e09cb4bcc 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -936,6 +936,12 @@ int nexthop_str2backups(const char *str, int *num_backups, * unreachable (blackhole) * %pNHs * nexthop2str() + * %pNHcg + * 1.2.3.4 + * (0-length if no IP address present) + * %pNHci + * eth0 + * (0-length if no interface present) */ printfrr_ext_autoreg_p("NH", printfrr_nh) static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea, @@ -1026,6 +1032,54 @@ static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea, break; } return ret; + case 'c': + ea->fmt++; + if (*ea->fmt == 'g') { + ea->fmt++; + if (!nexthop) + return bputs(buf, "(null)"); + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + ret += bprintfrr(buf, "%pI4", + &nexthop->gate.ipv4); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + ret += bprintfrr(buf, "%pI6", + &nexthop->gate.ipv6); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_BLACKHOLE: + break; + } + } else if (*ea->fmt == 'i') { + ea->fmt++; + if (!nexthop) + return bputs(buf, "(null)"); + switch (nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + ret += bprintfrr( + buf, "%s", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + if (nexthop->ifindex) + ret += bprintfrr( + buf, "%s", + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + break; + } + } + return ret; } return -1; } diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index b74a0e6c23..6676c0b072 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -550,6 +550,13 @@ void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults) LYD_VALIDATE_NO_STATE, NULL); } +static int lyd_node_cmp(struct lyd_node **dnode1, struct lyd_node **dnode2) +{ + struct nb_node *nb_node = (*dnode1)->schema->priv; + + return nb_node->cbs.cli_cmp(*dnode1, *dnode2); +} + static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, bool with_defaults) { @@ -567,6 +574,10 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, * it's time to print the config. */ if (sort_node && nb_node != sort_node) { + list_sort(sort_list, + (int (*)(const void **, + const void **))lyd_node_cmp); + for (ALL_LIST_ELEMENTS_RO(sort_list, listnode, data)) nb_cli_show_dnode_cmds(vty, data, with_defaults); @@ -584,11 +595,9 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, if (!sort_node) { sort_node = nb_node; sort_list = list_new(); - sort_list->cmp = (int (*)(void *, void *)) - nb_node->cbs.cli_cmp; } - listnode_add_sort(sort_list, child); + listnode_add(sort_list, child); continue; } @@ -596,6 +605,9 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, } if (sort_node) { + list_sort(sort_list, + (int (*)(const void **, const void **))lyd_node_cmp); + for (ALL_LIST_ELEMENTS_RO(sort_list, listnode, data)) nb_cli_show_dnode_cmds(vty, data, with_defaults); diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 71d32b409c..7423a1a9e9 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -780,10 +780,6 @@ void ospf6_area_plist_update(struct prefix_list *plist, int add) const char *name = prefix_list_name(plist); struct ospf6 *ospf6 = NULL; - - if (!om6->ospf6) - return; - for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) { if (PREFIX_NAME_IN(oa) @@ -988,7 +984,6 @@ DEFUN(show_ipv6_ospf6_spf_tree, show_ipv6_ospf6_spf_tree_cmd, int idx_vrf = 0; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) { @@ -1048,7 +1043,6 @@ DEFUN(show_ipv6_ospf6_area_spf_tree, show_ipv6_ospf6_area_spf_tree_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_ipv4 += 2; @@ -1132,7 +1126,6 @@ DEFUN(show_ipv6_ospf6_simulate_spf_tree_root, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_ipv4 += 2; @@ -1340,8 +1333,6 @@ void ospf6_area_interface_delete(struct ospf6_interface *oi) struct listnode *node, *nnode; struct ospf6 *ospf6; - if (!om6->ospf6) - return; for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) if (listnode_lookup(oa->if_list, oi)) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 90c9fdf23a..ff651d674b 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -2522,7 +2522,6 @@ DEFUN(show_ipv6_ospf6_redistribute, show_ipv6_ospf6_redistribute_cmd, json_object *json_array_routes = NULL; json_object *json_array_redistribute = NULL; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (uj) { diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index b427a0c9bd..b63a3c02db 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -1330,7 +1330,6 @@ DEFUN(show_ipv6_ospf6_interface, show_ipv6_ospf6_interface_ifname_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_ifname += 2; @@ -1547,7 +1546,6 @@ DEFUN(show_ipv6_ospf6_interface_traffic, show_ipv6_ospf6_interface_traffic_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) { @@ -1590,7 +1588,6 @@ DEFUN(show_ipv6_ospf6_interface_ifname_prefix, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_ifname += 2; @@ -1651,7 +1648,6 @@ DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_prefix += 2; diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 4ea615f32b..05ef40be47 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -1081,7 +1081,6 @@ DEFUN(show_ipv6_ospf6_neighbor, show_ipv6_ospf6_neighbor_cmd, bool detail = false; bool drchoice = false; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (argv_find(argv, argc, "detail", &idx_type)) @@ -1156,7 +1155,6 @@ DEFUN(show_ipv6_ospf6_neighbor_one, show_ipv6_ospf6_neighbor_one_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_ipv4 += 2; diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 5f630828e7..8bfd3b7124 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -1120,11 +1120,6 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route, json_object *json_array_next_hops = NULL; json_object *json_next_hop; - if (om6->ospf6 == NULL) { - vty_out(vty, "OSPFv3 is not running\n"); - return; - } - monotime(&now); timersub(&now, &route->changed, &res); timerstring(&res, duration, sizeof(duration)); @@ -1208,11 +1203,6 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route, json_object *json_array_next_hops = NULL; json_object *json_next_hop; - if (om6->ospf6 == NULL) { - vty_out(vty, "OSPFv3 is not running\n"); - return; - } - monotime(&now); /* destination */ diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 6ff3789a80..d07d36c319 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -1519,7 +1519,6 @@ DEFUN(show_ipv6_ospf6, show_ipv6_ospf6_cmd, bool uj = use_json(argc, argv); json_object *json = NULL; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) { @@ -1560,7 +1559,6 @@ DEFUN(show_ipv6_ospf6_route, show_ipv6_ospf6_route_cmd, int idx_arg_start = 4; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_arg_start += 2; @@ -1594,7 +1592,6 @@ DEFUN(show_ipv6_ospf6_route_match, show_ipv6_ospf6_route_match_cmd, int idx_start_arg = 4; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_start_arg += 2; @@ -1629,7 +1626,6 @@ DEFUN(show_ipv6_ospf6_route_match_detail, int idx_start_arg = 4; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_start_arg += 2; @@ -1665,7 +1661,6 @@ DEFUN(show_ipv6_ospf6_route_type_detail, show_ipv6_ospf6_route_type_detail_cmd, int idx_start_arg = 4; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_start_arg += 2; @@ -2078,7 +2073,6 @@ DEFPY (show_ipv6_ospf6_external_aggregator, if (uj) json = json_object_new_object(); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) { diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index 0e8185cfeb..e85f4c1b61 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -413,7 +413,6 @@ DEFUN(show_ipv6_ospf6_database, show_ipv6_ospf6_database_cmd, int idx_vrf = 0; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_level += 2; @@ -460,7 +459,6 @@ DEFUN(show_ipv6_ospf6_database_type, show_ipv6_ospf6_database_type_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -505,7 +503,6 @@ DEFUN(show_ipv6_ospf6_database_id, show_ipv6_ospf6_database_id_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (argv[idx_ipv4]->type == IPV4_TKN) inet_pton(AF_INET, argv[idx_ipv4]->arg, &id); @@ -548,7 +545,6 @@ DEFUN(show_ipv6_ospf6_database_router, show_ipv6_ospf6_database_router_cmd, int idx_vrf = 0; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_ipv4 += 2; @@ -619,7 +615,6 @@ DEFUN_HIDDEN( bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_ipv4 += 2; @@ -672,7 +667,6 @@ DEFUN(show_ipv6_ospf6_database_type_id, show_ipv6_ospf6_database_type_id_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -731,7 +725,6 @@ DEFUN(show_ipv6_ospf6_database_type_router, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -782,7 +775,6 @@ DEFUN(show_ipv6_ospf6_database_id_router, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_ls_id += 2; @@ -833,7 +825,6 @@ DEFUN(show_ipv6_ospf6_database_adv_router_linkstate_id, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_adv_rtr += 2; @@ -891,7 +882,6 @@ DEFUN(show_ipv6_ospf6_database_type_id_router, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -960,7 +950,6 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -1008,7 +997,6 @@ DEFUN(show_ipv6_ospf6_database_self_originated, uint32_t adv_router = 0; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_level += 2; @@ -1063,7 +1051,6 @@ DEFUN(show_ipv6_ospf6_database_type_self_originated, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -1123,7 +1110,6 @@ DEFUN(show_ipv6_ospf6_database_type_self_originated_linkstate_id, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -1185,7 +1171,6 @@ DEFUN(show_ipv6_ospf6_database_type_id_self_originated, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_lsa += 2; @@ -1268,7 +1253,6 @@ DEFUN(show_ipv6_ospf6_border_routers, show_ipv6_ospf6_border_routers_cmd, int idx_vrf = 0; int idx_argc = 5; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_argc += 2; @@ -1308,7 +1292,6 @@ DEFUN(show_ipv6_ospf6_linkstate, show_ipv6_ospf6_linkstate_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_ipv4 += 2; @@ -1348,8 +1331,6 @@ DEFUN(show_ipv6_ospf6_linkstate_detail, show_ipv6_ospf6_linkstate_detail_cmd, bool all_vrf = false; int idx_vrf = 0; - - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_detail += 2; diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index d5170be7cc..041a9b1df9 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -93,12 +93,6 @@ extern struct thread_master *master; #define OSPF6_ROUTER_ID_STR "Specify Router-ID\n" #define OSPF6_LS_ID_STR "Specify Link State ID\n" -#define OSPF6_CMD_CHECK_RUNNING() \ - if (om6->ospf6 == NULL) { \ - vty_out(vty, "OSPFv3 is not running\n"); \ - return CMD_SUCCESS; \ - } - #define IS_OSPF6_ASBR(O) ((O)->flag & OSPF6_FLAG_ASBR) #define OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \ if (argv_find(argv, argc, "vrf", &idx_vrf)) { \ diff --git a/pimd/pim_assert.h b/pimd/pim_assert.h index 63fda3fe34..c07cbeb013 100644 --- a/pimd/pim_assert.h +++ b/pimd/pim_assert.h @@ -24,8 +24,22 @@ #include "if.h" -#include "pim_neighbor.h" -#include "pim_ifchannel.h" +struct pim_ifchannel; +struct pim_neighbor; + +enum pim_ifassert_state { + PIM_IFASSERT_NOINFO, + PIM_IFASSERT_I_AM_WINNER, + PIM_IFASSERT_I_AM_LOSER +}; + +struct pim_assert_metric { + uint32_t rpt_bit_flag; + uint32_t metric_preference; + uint32_t route_metric; + struct in_addr ip_address; /* neighbor router that sourced the Assert + message */ +}; /* RFC 4601: 4.11. Timer Values diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c index dfe2d5f2fa..c7fcbba71e 100644 --- a/pimd/pim_bfd.c +++ b/pimd/pim_bfd.c @@ -28,6 +28,7 @@ #include "zclient.h" #include "pim_instance.h" +#include "pim_neighbor.h" #include "pim_cmd.h" #include "pim_vty.h" #include "pim_iface.h" diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index f2845ee6e1..a3a3426f39 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -28,6 +28,7 @@ #include "pimd.h" #include "pim_iface.h" #include "pim_instance.h" +#include "pim_neighbor.h" #include "pim_rpf.h" #include "pim_hello.h" #include "pim_pim.h" diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 1238e03a5b..14aa710524 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3430,112 +3430,87 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj) pim->igmp_watermark_limit ? "Set" : "Not Set", pim->igmp_watermark_limit); vty_out(vty, - "Interface Address Group Mode Timer Srcs V Uptime \n"); + "Interface Group Mode Timer Srcs V Uptime \n"); } /* scan interfaces */ FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; - struct listnode *sock_node; - struct igmp_sock *igmp; + struct listnode *grpnode; + struct igmp_group *grp; if (!pim_ifp) continue; - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, - igmp)) { - char ifaddr_str[INET_ADDRSTRLEN]; - struct listnode *grpnode; - struct igmp_group *grp; - - pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, - sizeof(ifaddr_str)); - - /* scan igmp groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, - grpnode, grp)) { - char group_str[INET_ADDRSTRLEN]; - char hhmmss[10]; - char uptime[10]; + /* scan igmp groups */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode, + grp)) { + char group_str[INET_ADDRSTRLEN]; + char hhmmss[10]; + char uptime[10]; - pim_inet4_dump("<group?>", grp->group_addr, - group_str, sizeof(group_str)); - pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), - grp->t_group_timer); - pim_time_uptime(uptime, sizeof(uptime), - now - grp->group_creation); + pim_inet4_dump("<group?>", grp->group_addr, group_str, + sizeof(group_str)); + pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), + grp->t_group_timer); + pim_time_uptime(uptime, sizeof(uptime), + now - grp->group_creation); - if (uj) { - json_object_object_get_ex( - json, ifp->name, &json_iface); - - if (!json_iface) { - json_iface = - json_object_new_object(); - json_object_pim_ifp_add( - json_iface, ifp); - json_object_object_add( - json, ifp->name, - json_iface); - json_groups = - json_object_new_array(); - json_object_object_add( - json_iface, - "groups", - json_groups); - } + if (uj) { + json_object_object_get_ex(json, ifp->name, + &json_iface); - json_group = json_object_new_object(); - json_object_string_add(json_group, - "source", - ifaddr_str); - json_object_string_add(json_group, - "group", - group_str); - - if (grp->igmp_version == 3) - json_object_string_add( - json_group, "mode", - grp->group_filtermode_isexcl + if (!json_iface) { + json_iface = json_object_new_object(); + json_object_pim_ifp_add(json_iface, + ifp); + json_object_object_add(json, ifp->name, + json_iface); + json_groups = json_object_new_array(); + json_object_object_add(json_iface, + "groups", + json_groups); + } + + json_group = json_object_new_object(); + json_object_string_add(json_group, "group", + group_str); + + if (grp->igmp_version == 3) + json_object_string_add( + json_group, "mode", + grp->group_filtermode_isexcl ? "EXCLUDE" : "INCLUDE"); - json_object_string_add(json_group, - "timer", hhmmss); - json_object_int_add( - json_group, "sourcesCount", - grp->group_source_list - ? listcount( - grp->group_source_list) - : 0); - json_object_int_add( - json_group, "version", - grp->igmp_version); - json_object_string_add( - json_group, "uptime", uptime); - json_object_array_add(json_groups, - json_group); - } else { - vty_out(vty, - "%-16s %-15s %-15s %4s %8s %4d %d %8s\n", - ifp->name, ifaddr_str, - group_str, - grp->igmp_version == 3 + json_object_string_add(json_group, "timer", + hhmmss); + json_object_int_add( + json_group, "sourcesCount", + grp->group_source_list ? listcount( + grp->group_source_list) + : 0); + json_object_int_add(json_group, "version", + grp->igmp_version); + json_object_string_add(json_group, "uptime", + uptime); + json_object_array_add(json_groups, json_group); + } else { + vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n", + ifp->name, group_str, + grp->igmp_version == 3 ? (grp->group_filtermode_isexcl - ? "EXCL" - : "INCL") + ? "EXCL" + : "INCL") : "----", - hhmmss, - grp->group_source_list - ? listcount( - grp->group_source_list) - : 0, - grp->igmp_version, uptime); - } - } /* scan igmp groups */ - } /* scan igmp sockets */ - } /* scan interfaces */ + hhmmss, + grp->group_source_list ? listcount( + grp->group_source_list) + : 0, + grp->igmp_version, uptime); + } + } /* scan igmp groups */ + } /* scan interfaces */ if (uj) { vty_out(vty, "%s\n", json_object_to_json_string_ext( @@ -3550,63 +3525,49 @@ static void igmp_show_group_retransmission(struct pim_instance *pim, struct interface *ifp; vty_out(vty, - "Interface Address Group RetTimer Counter RetSrcs\n"); + "Interface Group RetTimer Counter RetSrcs\n"); /* scan interfaces */ FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; - struct listnode *sock_node; - struct igmp_sock *igmp; + struct listnode *grpnode; + struct igmp_group *grp; if (!pim_ifp) continue; - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, - igmp)) { - char ifaddr_str[INET_ADDRSTRLEN]; - struct listnode *grpnode; - struct igmp_group *grp; - - pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, - sizeof(ifaddr_str)); - - /* scan igmp groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, - grpnode, grp)) { - char group_str[INET_ADDRSTRLEN]; - char grp_retr_mmss[10]; - struct listnode *src_node; - struct igmp_source *src; - int grp_retr_sources = 0; - - pim_inet4_dump("<group?>", grp->group_addr, - group_str, sizeof(group_str)); - pim_time_timer_to_mmss( - grp_retr_mmss, sizeof(grp_retr_mmss), - grp->t_group_query_retransmit_timer); - - - /* count group sources with retransmission state - */ - for (ALL_LIST_ELEMENTS_RO( - grp->group_source_list, src_node, - src)) { - if (src->source_query_retransmit_count - > 0) { - ++grp_retr_sources; - } + /* scan igmp groups */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode, + grp)) { + char group_str[INET_ADDRSTRLEN]; + char grp_retr_mmss[10]; + struct listnode *src_node; + struct igmp_source *src; + int grp_retr_sources = 0; + + pim_inet4_dump("<group?>", grp->group_addr, group_str, + sizeof(group_str)); + pim_time_timer_to_mmss( + grp_retr_mmss, sizeof(grp_retr_mmss), + grp->t_group_query_retransmit_timer); + + + /* count group sources with retransmission state + */ + for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, + src_node, src)) { + if (src->source_query_retransmit_count > 0) { + ++grp_retr_sources; } + } - vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n", - ifp->name, ifaddr_str, group_str, - grp_retr_mmss, - grp->group_specific_query_retransmit_count, - grp_retr_sources); + vty_out(vty, "%-16s %-15s %-8s %7d %7d\n", ifp->name, + group_str, grp_retr_mmss, + grp->group_specific_query_retransmit_count, + grp_retr_sources); - } /* scan igmp groups */ - } /* scan igmp sockets */ - } /* scan interfaces */ + } /* scan igmp groups */ + } /* scan interfaces */ } static void igmp_show_sources(struct pim_instance *pim, struct vty *vty) @@ -3617,71 +3578,54 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty) now = pim_time_monotonic_sec(); vty_out(vty, - "Interface Address Group Source Timer Fwd Uptime \n"); + "Interface Group Source Timer Fwd Uptime \n"); /* scan interfaces */ FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; - struct listnode *sock_node; - struct igmp_sock *igmp; + struct listnode *grpnode; + struct igmp_group *grp; if (!pim_ifp) continue; - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, - igmp)) { - char ifaddr_str[INET_ADDRSTRLEN]; - struct listnode *grpnode; - struct igmp_group *grp; + /* scan igmp groups */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode, + grp)) { + char group_str[INET_ADDRSTRLEN]; + struct listnode *srcnode; + struct igmp_source *src; + + pim_inet4_dump("<group?>", grp->group_addr, group_str, + sizeof(group_str)); - pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, - sizeof(ifaddr_str)); + /* scan group sources */ + for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, + srcnode, src)) { + char source_str[INET_ADDRSTRLEN]; + char mmss[10]; + char uptime[10]; - /* scan igmp groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, - grpnode, grp)) { - char group_str[INET_ADDRSTRLEN]; - struct listnode *srcnode; - struct igmp_source *src; + pim_inet4_dump("<source?>", src->source_addr, + source_str, sizeof(source_str)); - pim_inet4_dump("<group?>", grp->group_addr, - group_str, sizeof(group_str)); + pim_time_timer_to_mmss(mmss, sizeof(mmss), + src->t_source_timer); - /* scan group sources */ - for (ALL_LIST_ELEMENTS_RO( - grp->group_source_list, srcnode, - src)) { - char source_str[INET_ADDRSTRLEN]; - char mmss[10]; - char uptime[10]; - - pim_inet4_dump( - "<source?>", src->source_addr, - source_str, sizeof(source_str)); - - pim_time_timer_to_mmss( - mmss, sizeof(mmss), - src->t_source_timer); - - pim_time_uptime( - uptime, sizeof(uptime), + pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation); - vty_out(vty, - "%-16s %-15s %-15s %-15s %5s %3s %8s\n", - ifp->name, ifaddr_str, - group_str, source_str, mmss, - IGMP_SOURCE_TEST_FORWARDING( - src->source_flags) + vty_out(vty, "%-16s %-15s %-15s %5s %3s %8s\n", + ifp->name, group_str, source_str, mmss, + IGMP_SOURCE_TEST_FORWARDING( + src->source_flags) ? "Y" : "N", - uptime); + uptime); - } /* scan group sources */ - } /* scan igmp groups */ - } /* scan igmp sockets */ - } /* scan interfaces */ + } /* scan group sources */ + } /* scan igmp groups */ + } /* scan interfaces */ } static void igmp_show_source_retransmission(struct pim_instance *pim, @@ -3690,57 +3634,42 @@ static void igmp_show_source_retransmission(struct pim_instance *pim, struct interface *ifp; vty_out(vty, - "Interface Address Group Source Counter\n"); + "Interface Group Source Counter\n"); /* scan interfaces */ FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; - struct listnode *sock_node; - struct igmp_sock *igmp; + struct listnode *grpnode; + struct igmp_group *grp; if (!pim_ifp) continue; - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, - igmp)) { - char ifaddr_str[INET_ADDRSTRLEN]; - struct listnode *grpnode; - struct igmp_group *grp; - - pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, - sizeof(ifaddr_str)); + /* scan igmp groups */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode, + grp)) { + char group_str[INET_ADDRSTRLEN]; + struct listnode *srcnode; + struct igmp_source *src; - /* scan igmp groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, - grpnode, grp)) { - char group_str[INET_ADDRSTRLEN]; - struct listnode *srcnode; - struct igmp_source *src; + pim_inet4_dump("<group?>", grp->group_addr, group_str, + sizeof(group_str)); - pim_inet4_dump("<group?>", grp->group_addr, - group_str, sizeof(group_str)); + /* scan group sources */ + for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, + srcnode, src)) { + char source_str[INET_ADDRSTRLEN]; - /* scan group sources */ - for (ALL_LIST_ELEMENTS_RO( - grp->group_source_list, srcnode, - src)) { - char source_str[INET_ADDRSTRLEN]; + pim_inet4_dump("<source?>", src->source_addr, + source_str, sizeof(source_str)); - pim_inet4_dump( - "<source?>", src->source_addr, - source_str, sizeof(source_str)); + vty_out(vty, "%-16s %-15s %-15s %7d\n", + ifp->name, group_str, source_str, + src->source_query_retransmit_count); - vty_out(vty, - "%-16s %-15s %-15s %-15s %7d\n", - ifp->name, ifaddr_str, - group_str, source_str, - src->source_query_retransmit_count); - - } /* scan group sources */ - } /* scan igmp groups */ - } /* scan igmp sockets */ - } /* scan interfaces */ + } /* scan group sources */ + } /* scan igmp groups */ + } /* scan interfaces */ } static void pim_show_bsr(struct pim_instance *pim, @@ -3993,8 +3922,7 @@ static void clear_mroute(struct pim_instance *pim) /* scan interfaces */ FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; - struct listnode *sock_node; - struct igmp_sock *igmp; + struct igmp_group *grp; struct pim_ifchannel *ch; if (!pim_ifp) @@ -4008,20 +3936,12 @@ static void clear_mroute(struct pim_instance *pim) } /* clean up all igmp groups */ - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, - igmp)) { - - struct igmp_group *grp; - if (igmp->igmp_group_list) { - while (igmp->igmp_group_list->count) { - grp = listnode_head( - igmp->igmp_group_list); - igmp_group_delete(grp); - } + if (pim_ifp->igmp_group_list) { + while (pim_ifp->igmp_group_list->count) { + grp = listnode_head(pim_ifp->igmp_group_list); + igmp_group_delete(grp); } - } } diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 0b28a3e84c..eb19cf4ddf 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -156,14 +156,12 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim, PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options); pim_ifp->igmp_join_list = NULL; - pim_ifp->igmp_socket_list = NULL; pim_ifp->pim_neighbor_list = NULL; pim_ifp->upstream_switch_list = NULL; pim_ifp->pim_generation_id = 0; /* list of struct igmp_sock */ - pim_ifp->igmp_socket_list = list_new(); - pim_ifp->igmp_socket_list->del = (void (*)(void *))igmp_sock_free; + pim_igmp_if_init(pim_ifp, ifp); /* list of struct pim_neighbor */ pim_ifp->pim_neighbor_list = list_new(); @@ -214,7 +212,8 @@ void pim_if_delete(struct interface *ifp) pim_if_del_vif(ifp); pim_ifp->pim->mcast_if_count--; - list_delete(&pim_ifp->igmp_socket_list); + pim_igmp_if_fini(pim_ifp); + list_delete(&pim_ifp->pim_neighbor_list); list_delete(&pim_ifp->upstream_switch_list); list_delete(&pim_ifp->sec_addr_list); diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 92784103fe..55c278d6e2 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -30,6 +30,7 @@ #include "pim_igmp.h" #include "pim_upstream.h" +#include "pim_instance.h" #include "bfd.h" #define PIM_IF_MASK_PIM (1 << 0) @@ -102,6 +103,8 @@ struct pim_interface { int igmp_last_member_query_count; /* IGMP last member query count */ struct list *igmp_socket_list; /* list of struct igmp_sock */ struct list *igmp_join_list; /* list of struct igmp_join */ + struct list *igmp_group_list; /* list of struct igmp_group */ + struct hash *igmp_group_hash; int pim_sock_fd; /* PIM socket file descriptor */ struct thread *t_pim_sock_read; /* thread for reading PIM socket */ diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index 7ec8191e56..52f02a660b 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -25,6 +25,8 @@ #include "if.h" #include "prefix.h" +#include "pim_assert.h" + struct pim_ifchannel; #include "pim_upstream.h" @@ -39,20 +41,6 @@ enum pim_ifjoin_state { PIM_IFJOIN_PRUNE_PENDING_TMP, }; -enum pim_ifassert_state { - PIM_IFASSERT_NOINFO, - PIM_IFASSERT_I_AM_WINNER, - PIM_IFASSERT_I_AM_LOSER -}; - -struct pim_assert_metric { - uint32_t rpt_bit_flag; - uint32_t metric_preference; - uint32_t route_metric; - struct in_addr ip_address; /* neighbor router that sourced the Assert - message */ -}; - /* Flag to detect change in CouldAssert(S,G,I) */ diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 71b2d9187a..50de7124d2 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -810,13 +810,8 @@ static void igmp_group_free(struct igmp_group *group) XFREE(MTYPE_PIM_IGMP_GROUP, group); } -static void igmp_group_count_incr(struct igmp_sock *igmp) +static void igmp_group_count_incr(struct pim_interface *pim_ifp) { - struct pim_interface *pim_ifp = igmp->interface->info; - - if (!pim_ifp) - return; - ++pim_ifp->pim->igmp_group_count; if (pim_ifp->pim->igmp_group_count == pim_ifp->pim->igmp_watermark_limit) { @@ -827,13 +822,8 @@ static void igmp_group_count_incr(struct igmp_sock *igmp) } } -static void igmp_group_count_decr(struct igmp_sock *igmp) +static void igmp_group_count_decr(struct pim_interface *pim_ifp) { - struct pim_interface *pim_ifp = igmp->interface->info; - - if (!pim_ifp) - return; - if (pim_ifp->pim->igmp_group_count == 0) { zlog_warn("Cannot decrement igmp group count below 0(vrf: %s)", VRF_LOGNAME(pim_ifp->pim->vrf)); @@ -848,14 +838,14 @@ void igmp_group_delete(struct igmp_group *group) struct listnode *src_node; struct listnode *src_nextnode; struct igmp_source *src; + struct pim_interface *pim_ifp = group->interface->info; if (PIM_DEBUG_IGMP_TRACE) { char group_str[INET_ADDRSTRLEN]; pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str)); - zlog_debug("Deleting IGMP group %s from socket %d interface %s", - group_str, group->group_igmp_sock->fd, - group->group_igmp_sock->interface->name); + zlog_debug("Deleting IGMP group %s from interface %s", + group_str, group->interface->name); } for (ALL_LIST_ELEMENTS(group->group_source_list, src_node, src_nextnode, @@ -866,9 +856,9 @@ void igmp_group_delete(struct igmp_group *group) THREAD_OFF(group->t_group_query_retransmit_timer); group_timer_off(group); - igmp_group_count_decr(group->group_igmp_sock); - listnode_delete(group->group_igmp_sock->igmp_group_list, group); - hash_release(group->group_igmp_sock->igmp_group_hash, group); + igmp_group_count_decr(pim_ifp); + listnode_delete(pim_ifp->igmp_group_list, group); + hash_release(pim_ifp->igmp_group_hash, group); igmp_group_free(group); } @@ -886,11 +876,6 @@ void igmp_sock_free(struct igmp_sock *igmp) assert(!igmp->t_igmp_read); assert(!igmp->t_igmp_query_timer); assert(!igmp->t_other_querier_timer); - assert(igmp->igmp_group_list); - assert(!listcount(igmp->igmp_group_list)); - - list_delete(&igmp->igmp_group_list); - hash_free(igmp->igmp_group_hash); XFREE(MTYPE_PIM_IGMP_SOCKET, igmp); } @@ -898,14 +883,6 @@ void igmp_sock_free(struct igmp_sock *igmp) void igmp_sock_delete(struct igmp_sock *igmp) { struct pim_interface *pim_ifp; - struct listnode *grp_node; - struct listnode *grp_nextnode; - struct igmp_group *grp; - - for (ALL_LIST_ELEMENTS(igmp->igmp_group_list, grp_node, grp_nextnode, - grp)) { - igmp_group_delete(grp); - } sock_close(igmp); @@ -914,6 +891,9 @@ void igmp_sock_delete(struct igmp_sock *igmp) listnode_delete(pim_ifp->igmp_socket_list, igmp); igmp_sock_free(igmp); + + if (!listcount(pim_ifp->igmp_socket_list)) + pim_igmp_if_reset(pim_ifp); } void igmp_sock_delete_all(struct interface *ifp) @@ -948,12 +928,50 @@ static bool igmp_group_hash_equal(const void *arg1, const void *arg2) return false; } +void pim_igmp_if_init(struct pim_interface *pim_ifp, struct interface *ifp) +{ + char hash_name[64]; + + pim_ifp->igmp_socket_list = list_new(); + pim_ifp->igmp_socket_list->del = (void (*)(void *))igmp_sock_free; + + pim_ifp->igmp_group_list = list_new(); + pim_ifp->igmp_group_list->del = (void (*)(void *))igmp_group_free; + + snprintf(hash_name, sizeof(hash_name), "IGMP %s hash", ifp->name); + pim_ifp->igmp_group_hash = hash_create( + igmp_group_hash_key, igmp_group_hash_equal, hash_name); +} + +void pim_igmp_if_reset(struct pim_interface *pim_ifp) +{ + struct listnode *grp_node, *grp_nextnode; + struct igmp_group *grp; + + for (ALL_LIST_ELEMENTS(pim_ifp->igmp_group_list, grp_node, grp_nextnode, + grp)) { + igmp_group_delete(grp); + } +} + +void pim_igmp_if_fini(struct pim_interface *pim_ifp) +{ + pim_igmp_if_reset(pim_ifp); + + assert(pim_ifp->igmp_group_list); + assert(!listcount(pim_ifp->igmp_group_list)); + + list_delete(&pim_ifp->igmp_group_list); + hash_free(pim_ifp->igmp_group_hash); + + list_delete(&pim_ifp->igmp_socket_list); +} + static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, struct interface *ifp, int mtrace_only) { struct pim_interface *pim_ifp; struct igmp_sock *igmp; - char hash_name[64]; pim_ifp = ifp->info; @@ -965,13 +983,6 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp)); - igmp->igmp_group_list = list_new(); - igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free; - - snprintf(hash_name, sizeof(hash_name), "IGMP %s hash", ifp->name); - igmp->igmp_group_hash = hash_create(igmp_group_hash_key, - igmp_group_hash_equal, hash_name); - igmp->fd = fd; igmp->interface = ifp; igmp->ifaddr = ifaddr; @@ -1114,7 +1125,7 @@ static int igmp_group_timer(struct thread *t) pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str)); zlog_debug("%s: Timer for group %s on interface %s", __func__, - group_str, group->group_igmp_sock->interface->name); + group_str, group->interface->name); } assert(group->group_filtermode_isexcl); @@ -1151,7 +1162,7 @@ static void group_timer_off(struct igmp_group *group) pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str)); zlog_debug("Cancelling TIMER event for group %s on %s", - group_str, group->group_igmp_sock->interface->name); + group_str, group->interface->name); } THREAD_OFF(group->t_group_timer); } @@ -1188,16 +1199,18 @@ struct igmp_group *find_group_by_addr(struct igmp_sock *igmp, struct in_addr group_addr) { struct igmp_group lookup; + struct pim_interface *pim_ifp = igmp->interface->info; lookup.group_addr.s_addr = group_addr.s_addr; - return hash_lookup(igmp->igmp_group_hash, &lookup); + return hash_lookup(pim_ifp->igmp_group_hash, &lookup); } struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, struct in_addr group_addr) { struct igmp_group *group; + struct pim_interface *pim_ifp = igmp->interface->info; group = find_group_by_addr(igmp, group_addr); if (group) { @@ -1239,7 +1252,7 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, group->t_group_query_retransmit_timer = NULL; group->group_specific_query_retransmit_count = 0; group->group_addr = group_addr; - group->group_igmp_sock = igmp; + group->interface = igmp->interface; group->last_igmp_v1_report_dsec = -1; group->last_igmp_v2_report_dsec = -1; group->group_creation = pim_time_monotonic_sec(); @@ -1248,8 +1261,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, /* initialize new group as INCLUDE {empty} */ group->group_filtermode_isexcl = 0; /* 0=INCLUDE, 1=EXCLUDE */ - listnode_add(igmp->igmp_group_list, group); - group = hash_get(igmp->igmp_group_hash, group, hash_alloc_intern); + listnode_add(pim_ifp->igmp_group_list, group); + group = hash_get(pim_ifp->igmp_group_hash, group, hash_alloc_intern); if (PIM_DEBUG_IGMP_TRACE) { char group_str[INET_ADDRSTRLEN]; @@ -1260,7 +1273,7 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, group_str, igmp->fd, igmp->interface->name); } - igmp_group_count_incr(igmp); + igmp_group_count_incr(pim_ifp); /* RFC 3376: 6.2.2. Definition of Group Timers diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h index abb8af836b..dfe986e8f5 100644 --- a/pimd/pim_igmp.h +++ b/pimd/pim_igmp.h @@ -99,12 +99,15 @@ struct igmp_sock { bool mtrace_only; - struct list *igmp_group_list; /* list of struct igmp_group */ - struct hash *igmp_group_hash; - struct igmp_stats rx_stats; }; +struct pim_interface; + +void pim_igmp_if_init(struct pim_interface *pim_ifp, struct interface *ifp); +void pim_igmp_if_reset(struct pim_interface *pim_ifp); +void pim_igmp_if_fini(struct pim_interface *pim_ifp); + struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list, struct in_addr ifaddr); struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd); @@ -178,7 +181,7 @@ struct igmp_group { int group_filtermode_isexcl; /* 0=INCLUDE, 1=EXCLUDE */ struct list *group_source_list; /* list of struct igmp_source */ time_t group_creation; - struct igmp_sock *group_igmp_sock; /* back pointer */ + struct interface *interface; int64_t last_igmp_v1_report_dsec; int64_t last_igmp_v2_report_dsec; }; @@ -188,6 +191,10 @@ struct igmp_group *find_group_by_addr(struct igmp_sock *igmp, struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, struct in_addr group_addr); +struct igmp_source *igmp_get_source_by_addr(struct igmp_group *group, + struct in_addr src_addr, + bool *created); + void igmp_group_delete_empty_include(struct igmp_group *group); void igmp_startup_mode_on(struct igmp_sock *igmp); @@ -195,9 +202,6 @@ void igmp_startup_mode_on(struct igmp_sock *igmp); void igmp_group_timer_on(struct igmp_group *group, long interval_msec, const char *ifname); -struct igmp_source *source_new(struct igmp_group *group, - struct in_addr src_addr); - void igmp_send_query(int igmp_version, struct igmp_group *group, int fd, const char *ifname, char *query_buf, int query_buf_size, int num_sources, struct in_addr dst_addr, diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index bc67a1dd1d..13db11fa80 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -57,16 +57,28 @@ static void on_trace(const char *label, struct interface *ifp, } } +static inline long igmp_gmi_msec(struct igmp_group *group) +{ + struct pim_interface *pim_ifp = group->interface->info; + struct igmp_sock *igmp; + struct listnode *sock_node; + + long qrv = 0, qqi = 0; + + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) { + qrv = MAX(qrv, igmp->querier_robustness_variable); + qqi = MAX(qqi, igmp->querier_query_interval); + } + return PIM_IGMP_GMI_MSEC(qrv, qqi, + pim_ifp->igmp_query_max_response_time_dsec); +} + void igmp_group_reset_gmi(struct igmp_group *group) { long group_membership_interval_msec; - struct pim_interface *pim_ifp; - struct igmp_sock *igmp; struct interface *ifp; - igmp = group->group_igmp_sock; - ifp = igmp->interface; - pim_ifp = ifp->info; + ifp = group->interface; /* RFC 3376: 8.4. Group Membership Interval @@ -82,9 +94,7 @@ void igmp_group_reset_gmi(struct igmp_group *group) (1000 * querier_query_interval) + 100 * query_response_interval_dsec; */ - group_membership_interval_msec = PIM_IGMP_GMI_MSEC( - igmp->querier_robustness_variable, igmp->querier_query_interval, - pim_ifp->igmp_query_max_response_time_dsec); + group_membership_interval_msec = igmp_gmi_msec(group); if (PIM_DEBUG_IGMP_TRACE) { char group_str[INET_ADDRSTRLEN]; @@ -127,7 +137,7 @@ static int igmp_source_timer(struct thread *t) zlog_debug( "%s: Source timer expired for group %s source %s on %s", __func__, group_str, source_str, - group->group_igmp_sock->interface->name); + group->interface->name); } /* @@ -188,8 +198,7 @@ static void source_timer_off(struct igmp_group *group, sizeof(source_str)); zlog_debug( "Cancelling TIMER event for group %s source %s on %s", - group_str, source_str, - group->group_igmp_sock->interface->name); + group_str, source_str, group->interface->name); } THREAD_OFF(source->t_source_timer); @@ -199,7 +208,7 @@ static void igmp_source_timer_on(struct igmp_group *group, struct igmp_source *source, long interval_msec) { source_timer_off(group, source); - struct pim_interface *pim_ifp = group->group_igmp_sock->interface->info; + struct pim_interface *pim_ifp = group->interface->info; if (PIM_DEBUG_IGMP_EVENTS) { char group_str[INET_ADDRSTRLEN]; @@ -211,7 +220,7 @@ static void igmp_source_timer_on(struct igmp_group *group, zlog_debug( "Scheduling %ld.%03ld sec TIMER event for group %s source %s on %s", interval_msec / 1000, interval_msec % 1000, group_str, - source_str, group->group_igmp_sock->interface->name); + source_str, group->interface->name); } thread_add_timer_msec(router->master, igmp_source_timer, source, @@ -225,19 +234,14 @@ static void igmp_source_timer_on(struct igmp_group *group, igmp_source_forward_start(pim_ifp->pim, source); } -void igmp_source_reset_gmi(struct igmp_sock *igmp, struct igmp_group *group, - struct igmp_source *source) +void igmp_source_reset_gmi(struct igmp_group *group, struct igmp_source *source) { long group_membership_interval_msec; - struct pim_interface *pim_ifp; struct interface *ifp; - ifp = igmp->interface; - pim_ifp = ifp->info; + ifp = group->interface; - group_membership_interval_msec = PIM_IGMP_GMI_MSEC( - igmp->querier_robustness_variable, igmp->querier_query_interval, - pim_ifp->igmp_query_max_response_time_dsec); + group_membership_interval_msec = igmp_gmi_msec(group); if (PIM_DEBUG_IGMP_TRACE) { char group_str[INET_ADDRSTRLEN]; @@ -312,7 +316,7 @@ static void source_clear_send_flag(struct list *source_list) */ static void group_exclude_fwd_anysrc_ifempty(struct igmp_group *group) { - struct pim_interface *pim_ifp = group->group_igmp_sock->interface->info; + struct pim_interface *pim_ifp = group->interface->info; assert(group->group_filtermode_isexcl); @@ -356,9 +360,8 @@ void igmp_source_delete(struct igmp_source *source) pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str)); zlog_debug( - "Deleting IGMP source %s for group %s from socket %d interface %s c_oil ref_count %d", - source_str, group_str, group->group_igmp_sock->fd, - group->group_igmp_sock->interface->name, + "Deleting IGMP source %s for group %s from interface %s c_oil ref_count %d", + source_str, group_str, group->interface->name, source->source_channel_oil ? source->source_channel_oil->oil_ref_count : 0); @@ -376,10 +379,9 @@ void igmp_source_delete(struct igmp_source *source) pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str)); zlog_warn( - "%s: forwarding=ON(!) IGMP source %s for group %s from socket %d interface %s", + "%s: forwarding=ON(!) IGMP source %s for group %s from interface %s", __func__, source_str, group_str, - group->group_igmp_sock->fd, - group->group_igmp_sock->interface->name); + group->interface->name); /* warning only */ } @@ -439,11 +441,18 @@ struct igmp_source *igmp_find_source_by_addr(struct igmp_group *group, return 0; } -struct igmp_source *source_new(struct igmp_group *group, - struct in_addr src_addr) +struct igmp_source *igmp_get_source_by_addr(struct igmp_group *group, + struct in_addr src_addr, bool *new) { struct igmp_source *src; + if (new) + *new = false; + + src = igmp_find_source_by_addr(group, src_addr); + if (src) + return src; + if (PIM_DEBUG_IGMP_TRACE) { char group_str[INET_ADDRSTRLEN]; char source_str[INET_ADDRSTRLEN]; @@ -452,9 +461,8 @@ struct igmp_source *source_new(struct igmp_group *group, pim_inet4_dump("<source?>", src_addr, source_str, sizeof(source_str)); zlog_debug( - "Creating new IGMP source %s for group %s on socket %d interface %s", - source_str, group_str, group->group_igmp_sock->fd, - group->group_igmp_sock->interface->name); + "Creating new IGMP source %s for group %s on interface %s", + source_str, group_str, group->interface->name); } src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src)); @@ -471,23 +479,6 @@ struct igmp_source *source_new(struct igmp_group *group, /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */ igmp_anysource_forward_stop(group); - - return src; -} - -static struct igmp_source *add_source_by_addr(struct igmp_sock *igmp, - struct igmp_group *group, - struct in_addr src_addr) -{ - struct igmp_source *src; - - src = igmp_find_source_by_addr(group, src_addr); - if (src) { - return src; - } - - src = source_new(group, src_addr); - return src; } @@ -518,8 +509,7 @@ static void allow(struct igmp_sock *igmp, struct in_addr from, source = igmp_find_source_by_addr(group, star); if (source) - igmp_source_reset_gmi(igmp, group, - source); + igmp_source_reset_gmi(group, source); } } else { igmp_group_delete(group); @@ -540,10 +530,9 @@ static void allow(struct igmp_sock *igmp, struct in_addr from, src_addr = sources + i; - source = add_source_by_addr(igmp, group, *src_addr); - if (!source) { + source = igmp_get_source_by_addr(group, *src_addr, NULL); + if (!source) continue; - } /* RFC 3376: 6.4.1. Reception of Current-State Records @@ -555,7 +544,7 @@ static void allow(struct igmp_sock *igmp, struct in_addr from, igmp_source_reset_gmi() below, resetting the source timers to GMI, accomplishes this. */ - igmp_source_reset_gmi(igmp, group, source); + igmp_source_reset_gmi(group, source); } /* scan received sources */ } @@ -585,21 +574,23 @@ static void isex_excl(struct igmp_group *group, int num_sources, /* scan received sources (A) */ for (i = 0; i < num_sources; ++i) { struct in_addr *src_addr; + bool new; src_addr = sources + i; /* E.2: lookup reported source from (A) in (X,Y) */ - source = igmp_find_source_by_addr(group, *src_addr); - if (source) { + source = igmp_get_source_by_addr(group, *src_addr, &new); + if (!source) + continue; + + if (!new) { /* E.3: if found, clear deletion flag: (X*A) or (Y*A) */ IGMP_SOURCE_DONT_DELETE(source->source_flags); } else { /* E.4: if not found, create source with timer=GMI: * (A-X-Y) */ - source = source_new(group, *src_addr); assert(!source->t_source_timer); /* timer == 0 */ - igmp_source_reset_gmi(group->group_igmp_sock, group, - source); + igmp_source_reset_gmi(group, source); assert(source->t_source_timer); /* (A-X-Y) timer > 0 */ } @@ -615,8 +606,7 @@ static void isex_excl(struct igmp_group *group, int num_sources, source = igmp_find_source_by_addr(group, star); if (source) { IGMP_SOURCE_DONT_DELETE(source->source_flags); - igmp_source_reset_gmi(group->group_igmp_sock, group, - source); + igmp_source_reset_gmi(group, source); } } @@ -639,18 +629,21 @@ static void isex_incl(struct igmp_group *group, int num_sources, for (i = 0; i < num_sources; ++i) { struct igmp_source *source; struct in_addr *src_addr; + bool new; src_addr = sources + i; /* I.2: lookup reported source (B) */ - source = igmp_find_source_by_addr(group, *src_addr); - if (source) { + source = igmp_get_source_by_addr(group, *src_addr, &new); + if (!source) + continue; + + if (!new) { /* I.3: if found, clear deletion flag (A*B) */ IGMP_SOURCE_DONT_DELETE(source->source_flags); } else { /* I.4: if not found, create source with timer=0 (B-A) */ - source = source_new(group, *src_addr); assert(!source->t_source_timer); /* (B-A) timer=0 */ } @@ -706,7 +699,6 @@ void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from, static void toin_incl(struct igmp_group *group, int num_sources, struct in_addr *sources) { - struct igmp_sock *igmp = group->group_igmp_sock; int num_sources_tosend = listcount(group->group_source_list); int i; @@ -717,22 +709,23 @@ static void toin_incl(struct igmp_group *group, int num_sources, for (i = 0; i < num_sources; ++i) { struct igmp_source *source; struct in_addr *src_addr; + bool new; src_addr = sources + i; /* Lookup reported source (B) */ - source = igmp_find_source_by_addr(group, *src_addr); - if (source) { + source = igmp_get_source_by_addr(group, *src_addr, &new); + if (!source) + continue; + + if (!new) { /* If found, clear SEND flag (A*B) */ IGMP_SOURCE_DONT_SEND(source->source_flags); --num_sources_tosend; - } else { - /* If not found, create new source */ - source = source_new(group, *src_addr); } /* (B)=GMI */ - igmp_source_reset_gmi(igmp, group, source); + igmp_source_reset_gmi(group, source); } /* Send sources marked with SEND flag: Q(G,A-B) */ @@ -744,7 +737,6 @@ static void toin_incl(struct igmp_group *group, int num_sources, static void toin_excl(struct igmp_group *group, int num_sources, struct in_addr *sources) { - struct igmp_sock *igmp = group->group_igmp_sock; int num_sources_tosend; int i; @@ -755,25 +747,24 @@ static void toin_excl(struct igmp_group *group, int num_sources, for (i = 0; i < num_sources; ++i) { struct igmp_source *source; struct in_addr *src_addr; + bool new; src_addr = sources + i; /* Lookup reported source (A) */ - source = igmp_find_source_by_addr(group, *src_addr); - if (source) { - if (source->t_source_timer) { - /* If found and timer running, clear SEND flag - * (X*A) */ - IGMP_SOURCE_DONT_SEND(source->source_flags); - --num_sources_tosend; - } - } else { - /* If not found, create new source */ - source = source_new(group, *src_addr); + source = igmp_get_source_by_addr(group, *src_addr, &new); + if (!source) + continue; + + if (source->t_source_timer) { + /* If found and timer running, clear SEND flag + * (X*A) */ + IGMP_SOURCE_DONT_SEND(source->source_flags); + --num_sources_tosend; } /* (A)=GMI */ - igmp_source_reset_gmi(igmp, group, source); + igmp_source_reset_gmi(group, source); } /* Send sources marked with SEND flag: Q(G,X-A) */ @@ -839,22 +830,18 @@ static void toex_incl(struct igmp_group *group, int num_sources, for (i = 0; i < num_sources; ++i) { struct igmp_source *source; struct in_addr *src_addr; + bool new; src_addr = sources + i; /* Lookup reported source (B) */ - source = igmp_find_source_by_addr(group, *src_addr); - if (source) { + source = igmp_get_source_by_addr(group, *src_addr, &new); + if (!new) { /* If found, clear deletion flag: (A*B) */ IGMP_SOURCE_DONT_DELETE(source->source_flags); /* and set SEND flag (A*B) */ IGMP_SOURCE_DO_SEND(source->source_flags); ++num_sources_tosend; - } else { - /* If source not found, create source with timer=0: - * (B-A)=0 */ - source = source_new(group, *src_addr); - assert(!source->t_source_timer); /* (B-A) timer=0 */ } } /* Scan received sources (B) */ @@ -899,12 +886,16 @@ static void toex_excl(struct igmp_group *group, int num_sources, for (i = 0; i < num_sources; ++i) { struct igmp_source *source; struct in_addr *src_addr; + bool new; src_addr = sources + i; /* lookup reported source (A) in known sources (X,Y) */ - source = igmp_find_source_by_addr(group, *src_addr); - if (source) { + source = igmp_get_source_by_addr(group, *src_addr, &new); + if (!source) + continue; + + if (!new) { /* if found, clear off DELETE flag from reported source * (A) */ IGMP_SOURCE_DONT_DELETE(source->source_flags); @@ -912,7 +903,6 @@ static void toex_excl(struct igmp_group *group, int num_sources, /* if not found, create source with Group Timer: * (A-X-Y)=Group Timer */ long group_timer_msec; - source = source_new(group, *src_addr); assert(!source->t_source_timer); /* timer == 0 */ group_timer_msec = igmp_group_timer_remain_msec(group); @@ -986,6 +976,26 @@ void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from, allow(igmp, from, group_addr, num_sources, sources); } +static void igmp_send_query_group(struct igmp_group *group, char *query_buf, + size_t query_buf_size, int num_sources, + int s_flag) +{ + struct interface *ifp = group->interface; + struct pim_interface *pim_ifp = ifp->info; + struct igmp_sock *igmp; + struct listnode *sock_node; + + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) { + igmp_send_query( + pim_ifp->igmp_version, group, igmp->fd, ifp->name, + query_buf, query_buf_size, num_sources, + group->group_addr, group->group_addr, + pim_ifp->igmp_specific_query_max_response_time_dsec, + s_flag, igmp->querier_robustness_variable, + igmp->querier_query_interval); + } +} + /* RFC3376: 6.6.3.1. Building and Sending Group Specific Queries @@ -995,7 +1005,6 @@ void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from, */ static void group_retransmit_group(struct igmp_group *group) { - struct igmp_sock *igmp; struct pim_interface *pim_ifp; long lmqc; /* Last Member Query Count */ long lmqi_msec; /* Last Member Query Interval */ @@ -1003,8 +1012,7 @@ static void group_retransmit_group(struct igmp_group *group) int s_flag; int query_buf_size; - igmp = group->group_igmp_sock; - pim_ifp = igmp->interface->info; + pim_ifp = group->interface->info; if (pim_ifp->igmp_version == 3) { query_buf_size = PIM_IGMP_BUFSIZE_WRITE; @@ -1033,7 +1041,7 @@ static void group_retransmit_group(struct igmp_group *group) sizeof(group_str)); zlog_debug( "retransmit_group_specific_query: group %s on %s: s_flag=%d count=%d", - group_str, igmp->interface->name, s_flag, + group_str, group->interface->name, s_flag, group->group_specific_query_retransmit_count); } @@ -1045,14 +1053,7 @@ static void group_retransmit_group(struct igmp_group *group) interest. */ - igmp_send_query(pim_ifp->igmp_version, group, igmp->fd, - igmp->interface->name, query_buf, sizeof(query_buf), - 0 /* num_sources_tosend */, - group->group_addr /* dst_addr */, - group->group_addr /* group_addr */, - pim_ifp->igmp_specific_query_max_response_time_dsec, - s_flag, igmp->querier_robustness_variable, - igmp->querier_query_interval); + igmp_send_query_group(group, query_buf, sizeof(query_buf), 0, s_flag); } /* @@ -1070,7 +1071,6 @@ static void group_retransmit_group(struct igmp_group *group) static int group_retransmit_sources(struct igmp_group *group, int send_with_sflag_set) { - struct igmp_sock *igmp; struct pim_interface *pim_ifp; long lmqc; /* Last Member Query Count */ long lmqi_msec; /* Last Member Query Interval */ @@ -1090,8 +1090,7 @@ static int group_retransmit_sources(struct igmp_group *group, source_addr1 = (struct in_addr *)(query_buf1 + IGMP_V3_SOURCES_OFFSET); source_addr2 = (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET); - igmp = group->group_igmp_sock; - pim_ifp = igmp->interface->info; + pim_ifp = group->interface->info; lmqc = pim_ifp->igmp_last_member_query_count; lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec; @@ -1131,7 +1130,7 @@ static int group_retransmit_sources(struct igmp_group *group, sizeof(group_str)); zlog_debug( "retransmit_grp&src_specific_query: group %s on %s: srcs_with_sflag=%d srcs_wo_sflag=%d will_send_sflag=%d retransmit_src_left=%d", - group_str, igmp->interface->name, num_sources_tosend1, + group_str, group->interface->name, num_sources_tosend1, num_sources_tosend2, send_with_sflag_set, num_retransmit_sources_left); } @@ -1154,7 +1153,7 @@ static int group_retransmit_sources(struct igmp_group *group, zlog_warn( "%s: group %s on %s: s_flag=1 unable to fit %d sources into buf_size=%zu (max_sources=%d)", __func__, group_str, - igmp->interface->name, + group->interface->name, num_sources_tosend1, sizeof(query_buf1), query_buf1_max_sources); } else { @@ -1169,15 +1168,9 @@ static int group_retransmit_sources(struct igmp_group *group, interest. */ - igmp_send_query( - pim_ifp->igmp_version, group, igmp->fd, - igmp->interface->name, query_buf1, - sizeof(query_buf1), num_sources_tosend1, - group->group_addr, group->group_addr, - pim_ifp->igmp_specific_query_max_response_time_dsec, - 1 /* s_flag */, - igmp->querier_robustness_variable, - igmp->querier_query_interval); + igmp_send_query_group( + group, query_buf1, sizeof(query_buf1), + num_sources_tosend1, 1 /* s_flag */); } } /* send_with_sflag_set */ @@ -1197,7 +1190,7 @@ static int group_retransmit_sources(struct igmp_group *group, sizeof(group_str)); zlog_warn( "%s: group %s on %s: s_flag=0 unable to fit %d sources into buf_size=%zu (max_sources=%d)", - __func__, group_str, igmp->interface->name, + __func__, group_str, group->interface->name, num_sources_tosend2, sizeof(query_buf2), query_buf2_max_sources); } else { @@ -1211,15 +1204,9 @@ static int group_retransmit_sources(struct igmp_group *group, interest. */ - igmp_send_query( - pim_ifp->igmp_version, group, igmp->fd, - igmp->interface->name, query_buf2, - sizeof(query_buf2), num_sources_tosend2, - group->group_addr, group->group_addr, - pim_ifp->igmp_specific_query_max_response_time_dsec, - 0 /* s_flag */, - igmp->querier_robustness_variable, - igmp->querier_query_interval); + igmp_send_query_group( + group, query_buf2, sizeof(query_buf2), + num_sources_tosend2, 0 /* s_flag */); } } @@ -1239,7 +1226,7 @@ static int igmp_group_retransmit(struct thread *t) pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str)); zlog_debug("group_retransmit_timer: group %s on %s", group_str, - group->group_igmp_sock->interface->name); + group->interface->name); } /* Retransmit group-specific queries? (RFC3376: 6.6.3.1) */ @@ -1287,7 +1274,6 @@ static int igmp_group_retransmit(struct thread *t) */ static void group_retransmit_timer_on(struct igmp_group *group) { - struct igmp_sock *igmp; struct pim_interface *pim_ifp; long lmqi_msec; /* Last Member Query Interval */ @@ -1296,8 +1282,7 @@ static void group_retransmit_timer_on(struct igmp_group *group) return; } - igmp = group->group_igmp_sock; - pim_ifp = igmp->interface->info; + pim_ifp = group->interface->info; lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec; @@ -1308,7 +1293,7 @@ static void group_retransmit_timer_on(struct igmp_group *group) zlog_debug( "Scheduling %ld.%03ld sec retransmit timer for group %s on %s", lmqi_msec / 1000, lmqi_msec % 1000, group_str, - igmp->interface->name); + group->interface->name); } thread_add_timer_msec(router->master, igmp_group_retransmit, group, @@ -1332,11 +1317,9 @@ static long igmp_source_timer_remain_msec(struct igmp_source *source) static void group_query_send(struct igmp_group *group) { struct pim_interface *pim_ifp; - struct igmp_sock *igmp; long lmqc; /* Last Member Query Count */ - igmp = group->group_igmp_sock; - pim_ifp = igmp->interface->info; + pim_ifp = group->interface->info; lmqc = pim_ifp->igmp_last_member_query_count; /* lower group timer to lmqt */ @@ -1359,7 +1342,6 @@ static void group_query_send(struct igmp_group *group) static void source_query_send_by_flag(struct igmp_group *group, int num_sources_tosend) { - struct igmp_sock *igmp; struct pim_interface *pim_ifp; struct listnode *src_node; struct igmp_source *src; @@ -1369,8 +1351,7 @@ static void source_query_send_by_flag(struct igmp_group *group, assert(num_sources_tosend > 0); - igmp = group->group_igmp_sock; - pim_ifp = igmp->interface->info; + pim_ifp = group->interface->info; lmqc = pim_ifp->igmp_last_member_query_count; lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec; @@ -1417,16 +1398,19 @@ static void block_excl(struct igmp_group *group, int num_sources, for (i = 0; i < num_sources; ++i) { struct igmp_source *source; struct in_addr *src_addr; + bool new; src_addr = sources + i; /* lookup reported source (A) in known sources (X,Y) */ - source = igmp_find_source_by_addr(group, *src_addr); - if (!source) { + source = igmp_get_source_by_addr(group, *src_addr, &new); + if (!source) + continue; + + if (new) { /* 3: if not found, create source with Group Timer: * (A-X-Y)=Group Timer */ long group_timer_msec; - source = source_new(group, *src_addr); assert(!source->t_source_timer); /* timer == 0 */ group_timer_msec = igmp_group_timer_remain_msec(group); @@ -1504,7 +1488,6 @@ void igmpv3_report_block(struct igmp_sock *igmp, struct in_addr from, void igmp_group_timer_lower_to_lmqt(struct igmp_group *group) { - struct igmp_sock *igmp; struct interface *ifp; struct pim_interface *pim_ifp; char *ifname; @@ -1523,8 +1506,7 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group) return; } - igmp = group->group_igmp_sock; - ifp = igmp->interface; + ifp = group->interface; pim_ifp = ifp->info; ifname = ifp->name; @@ -1551,7 +1533,6 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group) void igmp_source_timer_lower_to_lmqt(struct igmp_source *source) { struct igmp_group *group; - struct igmp_sock *igmp; struct interface *ifp; struct pim_interface *pim_ifp; char *ifname; @@ -1560,8 +1541,7 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source) int lmqt_msec; /* Last Member Query Time */ group = source->source_group; - igmp = group->group_igmp_sock; - ifp = igmp->interface; + ifp = group->interface; pim_ifp = ifp->info; ifname = ifp->name; diff --git a/pimd/pim_igmpv3.h b/pimd/pim_igmpv3.h index 6abaef6e26..273f944b3c 100644 --- a/pimd/pim_igmpv3.h +++ b/pimd/pim_igmpv3.h @@ -23,6 +23,8 @@ #include <zebra.h> #include "if.h" +#include "pim_igmp.h" + #define IGMP_V3_CHECKSUM_OFFSET (2) #define IGMP_V3_REPORT_NUMGROUPS_OFFSET (6) #define IGMP_V3_REPORT_GROUPPRECORD_OFFSET (8) @@ -52,7 +54,7 @@ #define PIM_IGMP_OHPI_DSEC(qrv,qqi,qri_dsec) ((qrv) * (10 * (qqi)) + (qri_dsec)) void igmp_group_reset_gmi(struct igmp_group *group); -void igmp_source_reset_gmi(struct igmp_sock *igmp, struct igmp_group *group, +void igmp_source_reset_gmi(struct igmp_group *group, struct igmp_source *source); void igmp_source_free(struct igmp_source *source); diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index 52ded08ae3..68c5b9167b 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -210,6 +210,8 @@ struct pim_instance { void pim_vrf_init(void); void pim_vrf_terminate(void); +extern struct pim_router *router; + struct pim_instance *pim_get_pim_instance(vrf_id_t vrf_id); #endif diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h index 2d8e1b01fb..4cd6b9f0ac 100644 --- a/pimd/pim_mroute.h +++ b/pimd/pim_mroute.h @@ -167,6 +167,8 @@ struct igmpmsg { Above: from <linux/mroute.h> */ +struct channel_oil; + int pim_mroute_socket_enable(struct pim_instance *pim); int pim_mroute_socket_disable(struct pim_instance *pim); diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index 4b4c1ec7db..f4627cbcc2 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -23,6 +23,7 @@ #include "pim_nb.h" #include "lib/northbound_cli.h" #include "pim_igmpv3.h" +#include "pim_neighbor.h" #include "pim_pim.h" #include "pim_mlag.h" #include "pim_bfd.h" @@ -60,8 +61,9 @@ static void pim_if_membership_clear(struct interface *ifp) static void pim_if_membership_refresh(struct interface *ifp) { struct pim_interface *pim_ifp; - struct listnode *sock_node; - struct igmp_sock *igmp; + struct listnode *grpnode; + struct igmp_group *grp; + pim_ifp = ifp->info; assert(pim_ifp); @@ -83,36 +85,27 @@ static void pim_if_membership_refresh(struct interface *ifp) * the interface */ - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) { - struct listnode *grpnode; - struct igmp_group *grp; - - /* scan igmp groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, - grp)) { - struct listnode *srcnode; - struct igmp_source *src; - - /* scan group sources */ - for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, - srcnode, src)) { - - if (IGMP_SOURCE_TEST_FORWARDING( - src->source_flags)) { - struct prefix_sg sg; - - memset(&sg, 0, - sizeof(struct prefix_sg)); - sg.src = src->source_addr; - sg.grp = grp->group_addr; - pim_ifchannel_local_membership_add( - ifp, &sg, false /*is_vxlan*/); - } - - } /* scan group sources */ - } /* scan igmp groups */ - } /* scan igmp sockets */ + /* scan igmp groups */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode, grp)) { + struct listnode *srcnode; + struct igmp_source *src; + + /* scan group sources */ + for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, + src)) { + + if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) { + struct prefix_sg sg; + + memset(&sg, 0, sizeof(struct prefix_sg)); + sg.src = src->source_addr; + sg.grp = grp->group_addr; + pim_ifchannel_local_membership_add( + ifp, &sg, false /*is_vxlan*/); + } + + } /* scan group sources */ + } /* scan igmp groups */ /* * Finally delete every PIM (S,G) entry lacking all state info @@ -458,6 +451,8 @@ static void change_query_max_response_time(struct pim_interface *pim_ifp, { struct listnode *sock_node; struct igmp_sock *igmp; + struct listnode *grp_node; + struct igmp_group *grp; if (pim_ifp->igmp_query_max_response_time_dsec == query_max_response_time_dsec) @@ -474,32 +469,28 @@ static void change_query_max_response_time(struct pim_interface *pim_ifp, /* scan all sockets */ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) { - struct listnode *grp_node; - struct igmp_group *grp; - /* reschedule socket general query */ igmp_sock_query_reschedule(igmp); + } - /* scan socket groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, - grp)) { - struct listnode *src_node; - struct igmp_source *src; - - /* reset group timers for groups in EXCLUDE mode */ - if (grp->group_filtermode_isexcl) - igmp_group_reset_gmi(grp); - - /* scan group sources */ - for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, - src_node, src)) { - - /* reset source timers for sources with running - * timers - */ - if (src->t_source_timer) - igmp_source_reset_gmi(igmp, grp, src); - } + /* scan socket groups */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grp_node, grp)) { + struct listnode *src_node; + struct igmp_source *src; + + /* reset group timers for groups in EXCLUDE mode */ + if (grp->group_filtermode_isexcl) + igmp_group_reset_gmi(grp); + + /* scan group sources */ + for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, + src)) { + + /* reset source timers for sources with running + * timers + */ + if (src->t_source_timer) + igmp_source_reset_gmi(grp, src); } } } diff --git a/pimd/pim_neighbor.h b/pimd/pim_neighbor.h index b461098a60..d71b2b87c3 100644 --- a/pimd/pim_neighbor.h +++ b/pimd/pim_neighbor.h @@ -27,6 +27,7 @@ #include "prefix.h" #include "pim_tlv.h" +#include "pim_iface.h" struct pim_neighbor { int64_t creation; /* timestamp of creation */ diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index b0aa2b17c5..af8ac84594 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -20,8 +20,9 @@ #ifndef PIM_OIL_H #define PIM_OIL_H +struct pim_interface; + #include "pim_mroute.h" -#include "pim_iface.h" /* * Where did we get this (S,G) from? diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 3e3b6dddb5..f2a969e04a 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -42,7 +42,7 @@ #include "pim_rpf.h" #include "pim_sock.h" #include "pim_memory.h" -#include "pim_iface.h" +#include "pim_neighbor.h" #include "pim_msdp.h" #include "pim_nht.h" #include "pim_mroute.h" diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index dd7cd5d75e..595025e5c9 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -24,9 +24,10 @@ #include "prefix.h" #include "vty.h" #include "plist.h" -#include "pim_iface.h" #include "pim_rpf.h" +struct pim_interface; + enum rp_source { RP_SRC_NONE = 0, RP_SRC_STATIC, diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 66c6df65ad..b93f85e48c 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -31,6 +31,7 @@ #include "pim_pim.h" #include "pim_str.h" #include "pim_iface.h" +#include "pim_neighbor.h" #include "pim_zlookup.h" #include "pim_ifchannel.h" #include "pim_time.h" diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h index f006519b71..006aa1b636 100644 --- a/pimd/pim_rpf.h +++ b/pimd/pim_rpf.h @@ -22,9 +22,6 @@ #include <zebra.h> -#include "pim_upstream.h" -#include "pim_neighbor.h" - /* RFC 4601: diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 56039d5605..ea3b564f8a 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -24,7 +24,7 @@ #include <prefix.h> #include "plist.h" -#include <pimd/pim_rpf.h> +#include "pim_rpf.h" #include "pim_str.h" #include "pim_ifchannel.h" diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 6f933e9e72..aa041df857 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -474,7 +474,7 @@ void igmp_anysource_forward_start(struct pim_instance *pim, assert(group->group_filtermode_isexcl); assert(listcount(group->group_source_list) < 1); - source = source_new(group, src_addr); + source = igmp_get_source_by_addr(group, src_addr, NULL); if (!source) { zlog_warn("%s: Failure to create * source", __func__); return; @@ -508,7 +508,7 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim, sg.src = source->source_addr; sg.grp = group->group_addr; - ch = pim_ifchannel_find(group->group_igmp_sock->interface, &sg); + ch = pim_ifchannel_find(group->interface, &sg); if (pim_is_grp_ssm(pim, group->group_addr)) { /* If SSM group withdraw local membership */ if (ch @@ -517,8 +517,8 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim, zlog_debug( "local membership del for %s as G is now SSM", pim_str_sg_dump(&sg)); - pim_ifchannel_local_membership_del( - group->group_igmp_sock->interface, &sg); + pim_ifchannel_local_membership_del(group->interface, + &sg); } } else { /* If ASM group add local membership */ @@ -529,8 +529,7 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim, "local membership add for %s as G is now ASM", pim_str_sg_dump(&sg)); pim_ifchannel_local_membership_add( - group->group_igmp_sock->interface, &sg, - false /*is_vxlan*/); + group->interface, &sg, false /*is_vxlan*/); } } } @@ -541,33 +540,24 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim) FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; - struct listnode *sock_node; - struct igmp_sock *igmp; + struct listnode *grpnode; + struct igmp_group *grp; if (!pim_ifp) continue; - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, - igmp)) { - struct listnode *grpnode; - struct igmp_group *grp; - - /* scan igmp groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, - grpnode, grp)) { - struct listnode *srcnode; - struct igmp_source *src; - - /* scan group sources */ - for (ALL_LIST_ELEMENTS_RO( - grp->group_source_list, srcnode, - src)) { - igmp_source_forward_reevaluate_one(pim, - src); - } /* scan group sources */ - } /* scan igmp groups */ - } /* scan igmp sockets */ + /* scan igmp groups */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode, + grp)) { + struct listnode *srcnode; + struct igmp_source *src; + + /* scan group sources */ + for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, + srcnode, src)) { + igmp_source_forward_reevaluate_one(pim, src); + } /* scan group sources */ + } /* scan igmp groups */ } /* scan interfaces */ } @@ -585,12 +575,10 @@ void igmp_source_forward_start(struct pim_instance *pim, sg.grp = source->source_group->group_addr; if (PIM_DEBUG_IGMP_TRACE) { - zlog_debug( - "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__, - pim_str_sg_dump(&sg), - source->source_group->group_igmp_sock->fd, - source->source_group->group_igmp_sock->interface->name, - IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); + zlog_debug("%s: (S,G)=%s oif=%s fwd=%d", __func__, + pim_str_sg_dump(&sg), + source->source_group->interface->name, + IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); } /* Prevent IGMP interface from installing multicast route multiple @@ -600,13 +588,12 @@ void igmp_source_forward_start(struct pim_instance *pim, } group = source->source_group; - pim_oif = group->group_igmp_sock->interface->info; + pim_oif = group->interface->info; if (!pim_oif) { if (PIM_DEBUG_IGMP_TRACE) { zlog_debug("%s: multicast not enabled on oif=%s ?", __func__, - source->source_group->group_igmp_sock - ->interface->name); + source->source_group->interface->name); } return; } @@ -688,14 +675,10 @@ void igmp_source_forward_start(struct pim_instance *pim, */ if (PIM_DEBUG_IGMP_TRACE) { zlog_debug( - "%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d", + "%s: ignoring request for looped MFC entry (S,G)=%s: oif=%s vif_index=%d", __func__, pim_str_sg_dump(&sg), source->source_group - ->group_igmp_sock - ->fd, - source->source_group - ->group_igmp_sock ->interface->name, input_iface_vif_index); } @@ -719,7 +702,7 @@ void igmp_source_forward_start(struct pim_instance *pim, if (PIM_I_am_DR(pim_oif) || PIM_I_am_DualActive(pim_oif)) { result = pim_channel_add_oif(source->source_channel_oil, - group->group_igmp_sock->interface, + group->interface, PIM_OIF_FLAG_PROTO_IGMP, __func__); if (result) { if (PIM_DEBUG_MROUTE) { @@ -733,7 +716,7 @@ void igmp_source_forward_start(struct pim_instance *pim, zlog_debug( "%s: %s was received on %s interface but we are not DR for that interface", __func__, pim_str_sg_dump(&sg), - group->group_igmp_sock->interface->name); + group->interface->name); return; } @@ -741,16 +724,15 @@ void igmp_source_forward_start(struct pim_instance *pim, Feed IGMPv3-gathered local membership information into PIM per-interface (S,G) state. */ - if (!pim_ifchannel_local_membership_add( - group->group_igmp_sock->interface, &sg, + if (!pim_ifchannel_local_membership_add(group->interface, &sg, false /*is_vxlan*/)) { if (PIM_DEBUG_MROUTE) zlog_warn("%s: Failure to add local membership for %s", __func__, pim_str_sg_dump(&sg)); pim_channel_del_oif(source->source_channel_oil, - group->group_igmp_sock->interface, - PIM_OIF_FLAG_PROTO_IGMP, __func__); + group->interface, PIM_OIF_FLAG_PROTO_IGMP, + __func__); return; } @@ -772,12 +754,10 @@ void igmp_source_forward_stop(struct igmp_source *source) sg.grp = source->source_group->group_addr; if (PIM_DEBUG_IGMP_TRACE) { - zlog_debug( - "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__, - pim_str_sg_dump(&sg), - source->source_group->group_igmp_sock->fd, - source->source_group->group_igmp_sock->interface->name, - IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); + zlog_debug("%s: (S,G)=%s oif=%s fwd=%d", __func__, + pim_str_sg_dump(&sg), + source->source_group->interface->name, + IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); } /* Prevent IGMP interface from removing multicast route multiple @@ -800,9 +780,8 @@ void igmp_source_forward_stop(struct igmp_source *source) pim_forward_stop below. */ result = pim_channel_del_oif(source->source_channel_oil, - group->group_igmp_sock->interface, - PIM_OIF_FLAG_PROTO_IGMP, - __func__); + group->interface, PIM_OIF_FLAG_PROTO_IGMP, + __func__); if (result) { if (PIM_DEBUG_IGMP_TRACE) zlog_debug( @@ -815,8 +794,7 @@ void igmp_source_forward_stop(struct igmp_source *source) Feed IGMPv3-gathered local membership information into PIM per-interface (S,G) state. */ - pim_ifchannel_local_membership_del(group->group_igmp_sock->interface, - &sg); + pim_ifchannel_local_membership_del(group->interface, &sg); IGMP_SOURCE_DONT_FORWARDING(source->source_flags); } diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index dce936b8a9..abf9577bd5 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -31,6 +31,7 @@ #include "pimd.h" #include "pim_iface.h" +#include "pim_neighbor.h" #include "pim_pim.h" #include "pim_str.h" #include "pim_oil.h" diff --git a/pimd/pimd.h b/pimd/pimd.h index 88e692b50d..4cb860a6b7 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -136,7 +136,6 @@ extern const char *const PIM_ALL_ROUTERS; extern const char *const PIM_ALL_PIM_ROUTERS; extern const char *const PIM_ALL_IGMP_ROUTERS; -extern struct pim_router *router; extern struct zebra_privs_t pimd_privs; extern struct in_addr qpim_all_pim_routers_addr; extern uint8_t qpim_ecmp_enable; diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c index 92efd4c3d6..77fd876594 100644 --- a/tests/bgpd/test_mpath.c +++ b/tests/bgpd/test_mpath.c @@ -310,7 +310,7 @@ static int setup_bgp_path_info_mpath_update(testcase_t *t) str2prefix("42.1.1.0/24", &test_rn.p); rt_node = bgp_dest_to_rnode(&test_rn); memcpy((struct route_table *)&rt_node->table, &rt->route_table, - sizeof(struct route_table *)); + sizeof(struct route_table)); setup_bgp_mp_list(t); for (i = 0; i < test_mp_list_info_count; i++) bgp_path_info_add(&test_rn, &test_mp_list_info[i]); diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c index 21b3a916b8..06996a2f13 100644 --- a/tests/lib/test_printfrr.c +++ b/tests/lib/test_printfrr.c @@ -24,6 +24,7 @@ #include "lib/printfrr.h" #include "lib/memory.h" #include "lib/prefix.h" +#include "lib/nexthop.h" static int errors; @@ -253,5 +254,25 @@ int main(int argc, char **argv) printchk("\"\"", "%pSQqn", (char *)NULL); printchk("(null)", "%pSQq", (char *)NULL); + /* + * %pNH<foo> tests + * + * gateway addresses only for now: interfaces require more setup + */ + printchk("(null)", "%pNHcg", NULL); + printchk("(null)", "%pNHci", NULL); + + struct nexthop nh; + + memset(&nh, 0, sizeof(nh)); + + nh.type = NEXTHOP_TYPE_IPV4; + inet_aton("3.2.1.0", &nh.gate.ipv4); + printchk("3.2.1.0", "%pNHcg", &nh); + + nh.type = NEXTHOP_TYPE_IPV6; + inet_pton(AF_INET6, "fe2c::34", &nh.gate.ipv6); + printchk("fe2c::34", "%pNHcg", &nh); + return !!errors; } diff --git a/tests/subdir.am b/tests/subdir.am index b0be63c695..1edfda9bc2 100644 --- a/tests/subdir.am +++ b/tests/subdir.am @@ -183,7 +183,7 @@ TESTS_CXXFLAGS = \ # note no -Werror ALL_TESTS_LDADD = lib/libfrr.la $(LIBCAP) -BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) $(LIBYANG_LIBS) -lm +BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) $(LIBYANG_LIBS) $(UST_LIBS) -lm ISISD_TEST_LDADD = isisd/libisis.a $(ALL_TESTS_LDADD) if GRPC GRPC_TESTS_LDADD = staticd/libstatic.a grpc/libfrrgrpc_pb.la -lgrpc++ -lprotobuf $(ALL_TESTS_LDADD) $(LIBYANG_LIBS) -lm |
