summaryrefslogtreecommitdiff
path: root/pimd/pim_iface.c
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2019-09-30 07:46:19 -0400
committerGitHub <noreply@github.com>2019-09-30 07:46:19 -0400
commit9898a2fb3441e7382dba4190233f466b8271deae (patch)
tree9629a5ce665db95addf0d0bc0f46864ef71b5a49 /pimd/pim_iface.c
parent5c256b572ca09b5d15b67ba0236c8a2678dda19c (diff)
parent26f8f6fe7fb90208d4a5eb285fdf0dca83bde508 (diff)
Merge pull request #5009 from donaldsharp/interface_deletion
lib, zebra: Allow for interface deletion when kernel event happens
Diffstat (limited to 'pimd/pim_iface.c')
-rw-r--r--pimd/pim_iface.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index bdeda2d76b..bc8dedc4f6 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1526,3 +1526,169 @@ int pim_if_ifchannel_count(struct pim_interface *pim_ifp)
return count;
}
+
+int pim_ifp_create(struct interface *ifp)
+{
+ struct pim_instance *pim;
+
+ pim = pim_get_pim_instance(ifp->vrf_id);
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (if_is_operative(ifp)) {
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ /*
+ * If we have a pim_ifp already and this is an if_add
+ * that means that we probably have a vrf move event
+ * If that is the case, set the proper vrfness.
+ */
+ if (pim_ifp)
+ pim_ifp->pim = pim;
+ pim_if_addr_add_all(ifp);
+ }
+
+ /*
+ * If we are a vrf device that is up, open up the pim_socket for
+ * listening
+ * to incoming pim messages irrelevant if the user has configured us
+ * for pim or not.
+ */
+ if (pim_if_is_vrf_device(ifp)) {
+ struct pim_interface *pim_ifp;
+
+ if (!ifp->info) {
+ pim_ifp = pim_if_new(ifp, false, false, false,
+ false /*vxlan_term*/);
+ ifp->info = pim_ifp;
+ }
+
+ pim_sock_add(ifp);
+ }
+
+ if (!strncmp(ifp->name, PIM_VXLAN_TERM_DEV_NAME,
+ sizeof(PIM_VXLAN_TERM_DEV_NAME)))
+ pim_vxlan_add_term_dev(pim, ifp);
+
+ return 0;
+}
+
+int pim_ifp_up(struct interface *ifp)
+{
+ struct pim_instance *pim;
+ uint32_t table_id;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ pim = pim_get_pim_instance(ifp->vrf_id);
+ if (if_is_operative(ifp)) {
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ /*
+ * If we have a pim_ifp already and this is an if_add
+ * that means that we probably have a vrf move event
+ * If that is the case, set the proper vrfness.
+ */
+ if (pim_ifp)
+ pim_ifp->pim = pim;
+
+ /*
+ pim_if_addr_add_all() suffices for bringing up both IGMP and
+ PIM
+ */
+ pim_if_addr_add_all(ifp);
+ }
+
+ /*
+ * If we have a pimreg device callback and it's for a specific
+ * table set the master appropriately
+ */
+ if (sscanf(ifp->name, "pimreg%" SCNu32, &table_id) == 1) {
+ struct vrf *vrf;
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if ((table_id == vrf->data.l.table_id)
+ && (ifp->vrf_id != vrf->vrf_id)) {
+ struct interface *master = if_lookup_by_name(
+ vrf->name, vrf->vrf_id);
+
+ if (!master) {
+ zlog_debug(
+ "%s: Unable to find Master interface for %s",
+ __PRETTY_FUNCTION__, vrf->name);
+ return 0;
+ }
+ pim_zebra_interface_set_master(master, ifp);
+ }
+ }
+ }
+ return 0;
+}
+
+int pim_ifp_down(struct interface *ifp)
+{
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (!if_is_operative(ifp)) {
+ pim_ifchannel_delete_all(ifp);
+ /*
+ pim_if_addr_del_all() suffices for shutting down IGMP,
+ but not for shutting down PIM
+ */
+ pim_if_addr_del_all(ifp);
+
+ /*
+ pim_sock_delete() closes the socket, stops read and timer
+ threads,
+ and kills all neighbors.
+ */
+ if (ifp->info) {
+ pim_sock_delete(ifp, "link down");
+ }
+ }
+
+ if (ifp->info)
+ pim_if_del_vif(ifp);
+
+ return 0;
+}
+
+int pim_ifp_destroy(struct interface *ifp)
+{
+ struct pim_instance *pim;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (!if_is_operative(ifp))
+ pim_if_addr_del_all(ifp);
+
+ pim = pim_get_pim_instance(ifp->vrf_id);
+ if (pim && pim->vxlan.term_if == ifp)
+ pim_vxlan_del_term_dev(pim);
+
+ return 0;
+}