int isis_zebra_if_address_add (int command, struct zclient *zclient, zebra_size_t length) { struct connected *c; struct prefix *p; char buf[BUFSIZ]; c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf); if (c == NULL) return 0; p = c->address; prefix2str (p, buf, BUFSIZ); #ifdef EXTREME_DEBUG if (p->family == AF_INET) zlog_debug ("connected IP address %s", buf); #ifdef HAVE_IPV6 if (p->family == AF_INET6) zlog_debug ("connected IPv6 address %s", buf); #endif /* HAVE_IPV6 */ #endif /* EXTREME_DEBUG */ if (if_is_operative (c->ifp)) isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c); return 0; }
static int ospf_interface_address_add (int command, struct zclient *zclient, zebra_size_t length) { struct connected *c; c = zebra_interface_address_read (command, zclient->ibuf); if (c == NULL) return 0; if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) { char buf[128]; prefix2str(c->address, buf, sizeof(buf)); zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf); } ospf_if_update (NULL, c->ifp); #ifdef HAVE_SNMP ospf_snmp_if_update (c->ifp); #endif /* HAVE_SNMP */ return 0; }
int rip_interface_address_add (int command, struct zclient *zclient, zebra_size_t length) { struct connected *ifc; struct prefix *p; ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf); if (ifc == NULL) return 0; p = ifc->address; if (p->family == AF_INET) { if (IS_RIP_DEBUG_ZEBRA) zlog_debug ("connected address %s/%d is added", inet_ntoa (p->u.prefix4), p->prefixlen); rip_enable_apply(ifc->ifp); /* Check if this prefix needs to be redistributed */ rip_apply_address_add(ifc); #ifdef HAVE_SNMP rip_ifaddr_add (ifc->ifp, ifc); #endif /* HAVE_SNMP */ } return 0; }
static int bgp_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length) { struct connected *ifc; ifc = zebra_interface_address_read (command, zclient->ibuf); if (ifc == NULL) return 0; if (BGP_DEBUG(zebra, ZEBRA)) { char buf[128]; prefix2str(ifc->address, buf, sizeof(buf)); zlog_debug("Zebra rcvd: interface %s address delete %s", ifc->ifp->name, buf); } if (if_is_operative (ifc->ifp)) bgp_connected_delete (ifc); connected_free (ifc); return 0; }
int ripng_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length) { struct connected *ifc; struct prefix *p; char buf[INET6_ADDRSTRLEN]; ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf); if (ifc) { p = ifc->address; if (p->family == AF_INET6) { if (IS_RIPNG_DEBUG_ZEBRA) zlog_debug ("RIPng connected address %s/%d delete", inet_ntop (AF_INET6, &p->u.prefix6, buf, INET6_ADDRSTRLEN), p->prefixlen); /* Check wether this prefix needs to be removed. */ ripng_apply_address_del(ifc); } connected_free (ifc); } return 0; }
static int rsvp_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length) { struct connected *c; char buf[128]; c = zebra_interface_address_read (command, zclient->ibuf); if (c == NULL) return 0; prefix2str (c->address, buf, sizeof (buf)); zlog_debug ("Zebra: interface %s address delete %s", c->ifp->name, buf); if (IfIpAddrDel (c->address->u.prefix4.s_addr, c->address->prefixlen) != E_OK) { zlog_err ("Cannot add IP address %s %d", __FILE__, __LINE__); } if (IpAddrSetByIfIndex (c->ifp->ifindex, 0) != E_OK) { zlog_err ("Cannot unset IP address %s %d", __FILE__, __LINE__); } DisableRsvpOnInterface (c->ifp->ifindex); connected_free (c); return 0; }
static int interface_address_add(ZAPI_CALLBACK_ARGS) { zebra_interface_address_read(cmd, zclient->ibuf, vrf_id); return 0; }
int rip_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length) { struct connected *ifc; struct prefix *p; ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf); if (ifc) { p = ifc->address; if (p->family == AF_INET) { if (IS_RIP_DEBUG_ZEBRA) zlog_debug ("connected address %s/%d is deleted", inet_ntoa (p->u.prefix4), p->prefixlen); #ifdef HAVE_SNMP rip_ifaddr_delete (ifc->ifp, ifc); #endif /* HAVE_SNMP */ /* Chech wether this prefix needs to be removed */ rip_apply_address_del(ifc); } connected_free (ifc); } return 0; }
static int interface_address_delete(ZAPI_CALLBACK_ARGS) { struct connected *c; c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id); if (!c) return 0; connected_free(c); return 0; }
static int ospf_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length) { struct ospf *ospf; struct connected *c; struct interface *ifp; struct ospf_interface *oi; struct route_node *rn; struct prefix p; c = zebra_interface_address_read (command, zclient->ibuf); if (c == NULL) return 0; if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) { char buf[128]; prefix2str(c->address, buf, sizeof(buf)); zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf); } ifp = c->ifp; p = *c->address; p.prefixlen = IPV4_MAX_PREFIXLEN; rn = route_node_lookup (IF_OIFS (ifp), &p); if (!rn) { connected_free (c); return 0; } assert (rn->info); oi = rn->info; /* Call interface hook functions to clean up */ ospf_if_free (oi); #ifdef HAVE_SNMP ospf_snmp_if_update (c->ifp); #endif /* HAVE_SNMP */ connected_free (c); ospf = ospf_lookup (); if (ospf != NULL) ospf_if_update (ospf); return 0; }
int ripng_interface_address_add (int command, struct zclient *zclient, zebra_size_t length) { struct connected *c; struct prefix *p; c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf); if (c == NULL) return 0; p = c->address; if (p->family == AF_INET6) { if (IS_RIPNG_DEBUG_ZEBRA) zlog_debug ("RIPng connected address %s/%d add", inet6_ntop(&p->u.prefix6), p->prefixlen); /* Check is this prefix needs to be redistributed. */ ripng_apply_address_add(c); /* Let's try once again whether the interface could be activated */ if (c->ifp) { struct ripng_interface *ri = c->ifp->info; if (!ri->running) { /* Check if this interface is RIP enabled or not.*/ ripng_enable_apply (c->ifp); /* Apply distribute list to the interface. */ ripng_distribute_update_interface (c->ifp); /* Check interface routemap. */ ripng_if_rmap_update_interface (c->ifp); } } } return 0; }
int nhrp_interface_address_add(int cmd, struct zclient *client, zebra_size_t length, vrf_id_t vrf_id) { struct connected *ifc; char buf[PREFIX_STRLEN]; ifc = zebra_interface_address_read(cmd, client->ibuf, vrf_id); if (ifc == NULL) return 0; debugf(NHRP_DEBUG_IF, "if-addr-add: %s: %s", ifc->ifp->name, prefix2str(ifc->address, buf, sizeof buf)); nhrp_interface_update_address(ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0); return 0; }
static int pim_zebra_if_address_del(int command, struct zclient *client, zebra_size_t length) { struct connected *c; struct prefix *p; zassert(command == ZEBRA_INTERFACE_ADDRESS_DELETE); /* zebra api notifies address adds/dels events by using the same call interface_add_read below, see comments in lib/zclient.c zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...) will remove address from interface list by calling connected_delete_by_prefix() */ c = zebra_interface_address_read(command, client->ibuf); if (!c) return 0; p = c->address; if (p->family != AF_INET) return 0; if (PIM_DEBUG_ZEBRA) { char buf[BUFSIZ]; prefix2str(p, buf, BUFSIZ); zlog_debug("%s: %s disconnected IP address %s flags %u %s", __PRETTY_FUNCTION__, c->ifp->name, buf, c->flags, CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); #ifdef PIM_DEBUG_IFADDR_DUMP dump_if_address(c->ifp); #endif } pim_if_addr_del(c, 0); return 0; }
static int ospf6_zebra_if_address_update_delete (int command, struct zclient *zclient, zebra_size_t length) { struct connected *c; char buf[128]; c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf); if (c == NULL) return 0; if (IS_OSPF6_DEBUG_ZEBRA (RECV)) zlog_debug ("Zebra Interface address delete: %s %5s %s/%d", c->ifp->name, prefix_family_str (c->address), inet_ntop (c->address->family, &c->address->u.prefix, buf, sizeof (buf)), c->address->prefixlen); if (c->address->family == AF_INET6) ospf6_interface_connected_route_update (c->ifp); return 0; }
static int rsvp_interface_address_add (int command, struct zclient *zclient, zebra_size_t length) { struct connected *c; char buf[128]; c = zebra_interface_address_read (command, zclient->ibuf); if (c == NULL) return 0; prefix2str (c->address, buf, sizeof (buf)); zlog_debug ("Zebra: interface %s address add %s", c->ifp->name, buf); zlog_info ("trying to add IP address %s", buf); if (IfIpAdd (c->address->u.prefix4.s_addr, c->address->prefixlen) != E_OK) { zlog_err ("Cannot add IP address %s %d", __FILE__, __LINE__); } if (IpAddrSetByIfIndex (c->ifp->ifindex, c->address->u.prefix4.s_addr) != E_OK) { zlog_err ("Cannot set IP address %s %d", __FILE__, __LINE__); } if (IsRsvpEnabledOnIf (c->ifp->ifindex) == E_OK) { if (EnableRsvpOnInterface2 (c->ifp->ifindex) != E_OK) { zlog_err ("Cannot enable RSVP on I/F %d %s %d", c->ifp->ifindex, __FILE__, __LINE__); } } return 0; }
static int isis_zebra_if_address_del (int command, struct zclient *client, zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; struct interface *ifp; #ifdef EXTREME_DEBUG struct prefix *p; u_char buf[BUFSIZ]; #endif /* EXTREME_DEBUG */ c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf, vrf_id); if (c == NULL) return 0; ifp = c->ifp; #ifdef EXTREME_DEBUG p = c->address; prefix2str (p, buf, BUFSIZ); if (p->family == AF_INET) zlog_debug ("disconnected IP address %s", buf); #ifdef HAVE_IPV6 if (p->family == AF_INET6) zlog_debug ("disconnected IPv6 address %s", buf); #endif /* HAVE_IPV6 */ #endif /* EXTREME_DEBUG */ if (if_is_operative (ifp)) isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c); connected_free (c); return 0; }
static int pim_zebra_if_address_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; struct prefix *p; /* zebra api notifies address adds/dels events by using the same call interface_add_read below, see comments in lib/zclient.c zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...) will add address to interface list by calling connected_add_by_prefix() */ c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); if (!c) return 0; p = c->address; if (p->family != AF_INET) return 0; if (PIM_DEBUG_ZEBRA) { char buf[BUFSIZ]; prefix2str(p, buf, BUFSIZ); zlog_debug("%s: %s connected IP address %s flags %u %s", __PRETTY_FUNCTION__, c->ifp->name, buf, c->flags, CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); #ifdef PIM_DEBUG_IFADDR_DUMP dump_if_address(c->ifp); #endif } if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) { /* trying to add primary address */ struct in_addr primary_addr = pim_find_primary_addr(c->ifp); if (primary_addr.s_addr != p->u.prefix4.s_addr) { if (PIM_DEBUG_ZEBRA) { /* but we had a primary address already */ char buf[BUFSIZ]; char old[100]; prefix2str(p, buf, BUFSIZ); pim_inet4_dump("<old?>", primary_addr, old, sizeof(old)); zlog_warn("%s: %s primary addr old=%s: forcing secondary flag on new=%s", __PRETTY_FUNCTION__, c->ifp->name, old, buf); } SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY); } } pim_if_addr_add(c); return 0; }
static int ldp_interface_address_delete(int command, struct zclient *zclient, zebra_size_t length) { struct ldp *ldp = ldp_get(); struct connected *c; struct interface *ifp; struct prefix *p; struct ldp_addr addr; struct ldp_if iff; struct ldp_interface *li; c = zebra_interface_address_read(command, zclient->ibuf); if (c == NULL || c->address->family != AF_INET) { return 0; } ifp = c->ifp; p = c->address; zlog_info("address delete %s from interface %s", inet_ntoa(p->u.prefix4), ifp->name); if (ldp) { prefix2mpls_inet_addr(p, &addr.address); iff.handle = ifp; ldp_cfg_if_addr_set(ldp->h, &iff, &addr, LDP_CFG_DEL); li = ifp->info; if (ldp->trans_addr == LDP_TRANS_ADDR_STATIC_INTERFACE && !strncmp(ldp->trans_addr_ifname,ifp->name,IFNAMSIZ + 1)) { ldp_global g; zlog_info("updating global transport address"); g.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp)); g.transport_address.type = (g.transport_address.u.ipv4)?MPLS_FAMILY_IPV4:MPLS_FAMILY_NONE; ldp_admin_state_start(ldp); ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TRANS_ADDR); ldp_admin_state_finish(ldp); } if (ldp->trans_addr == LDP_TRANS_ADDR_INTERFACE) { zlog_info("updating entity transport address"); li->entity.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp)); li->entity.transport_address.type = li->entity.transport_address.u.ipv4 ? MPLS_FAMILY_IPV4 : MPLS_FAMILY_NONE; if (li->entity.index) { ldp_interface_admin_state_start(li); ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_TRANS_ADDR); ldp_interface_admin_state_finish(li); } } } connected_free(c); return 0; }
void eigrp_zebra_init(void) { struct zclient_options opt = {.receive_notify = false}; zclient = zclient_new_notify(master, &opt); zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs); zclient->zebra_connected = eigrp_zebra_connected; zclient->router_id_update = eigrp_router_id_update_zebra; zclient->interface_add = eigrp_interface_add; zclient->interface_delete = eigrp_interface_delete; zclient->interface_up = eigrp_interface_state_up; zclient->interface_down = eigrp_interface_state_down; zclient->interface_address_add = eigrp_interface_address_add; zclient->interface_address_delete = eigrp_interface_address_delete; zclient->redistribute_route_add = eigrp_zebra_read_route; zclient->redistribute_route_del = eigrp_zebra_read_route; zclient->route_notify_owner = eigrp_zebra_route_notify_owner; } /* Zebra route add and delete treatment. */ static int eigrp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct zapi_route api; struct eigrp *eigrp; if (zapi_route_decode(zclient->ibuf, &api) < 0) return -1; if (IPV4_NET127(ntohl(api.prefix.u.prefix4.s_addr))) return 0; eigrp = eigrp_lookup(); if (eigrp == NULL) return 0; if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */ { } return 0; } /* Inteface addition message from zebra. */ static int eigrp_interface_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; struct eigrp_interface *ei; ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); if (!ifp->info) return 0; ei = ifp->info; ei->params.type = eigrp_default_iftype(ifp); eigrp_if_update(ifp); return 0; } static int eigrp_interface_delete(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; struct stream *s; s = zclient->ibuf; /* zebra_interface_state_read () updates interface structure in iflist */ ifp = zebra_interface_state_read(s, vrf_id); if (ifp == NULL) return 0; if (if_is_up(ifp)) zlog_warn("Zebra: got delete of %s, but interface is still up", ifp->name); if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug( "Zebra: interface delete %s index %d flags %llx metric %d mtu %d", ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); if (ifp->info) eigrp_if_free(ifp->info, INTERFACE_DOWN_BY_ZEBRA); if_set_index(ifp, IFINDEX_INTERNAL); return 0; } static int eigrp_interface_address_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); if (c == NULL) return 0; if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) { char buf[128]; prefix2str(c->address, buf, sizeof(buf)); zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf); } eigrp_if_update(c->ifp); return 0; } static int eigrp_interface_address_delete(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; struct interface *ifp; struct eigrp_interface *ei; c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); if (c == NULL) return 0; if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) { char buf[128]; prefix2str(c->address, buf, sizeof(buf)); zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf); } ifp = c->ifp; ei = ifp->info; if (!ei) return 0; /* Call interface hook functions to clean up */ eigrp_if_free(ei, INTERFACE_DOWN_BY_ZEBRA); connected_free(c); return 0; } static int eigrp_interface_state_up(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; ifp = zebra_interface_if_lookup(zclient->ibuf); if (ifp == NULL) return 0; /* Interface is already up. */ if (if_is_operative(ifp)) { /* Temporarily keep ifp values. */ struct interface if_tmp; memcpy(&if_tmp, ifp, sizeof(struct interface)); zebra_interface_if_set_value(zclient->ibuf, ifp); if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug("Zebra: Interface[%s] state update.", ifp->name); if (if_tmp.bandwidth != ifp->bandwidth) { if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug( "Zebra: Interface[%s] bandwidth change %d -> %d.", ifp->name, if_tmp.bandwidth, ifp->bandwidth); // eigrp_if_recalculate_output_cost (ifp); } if (if_tmp.mtu != ifp->mtu) { if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug( "Zebra: Interface[%s] MTU change %u -> %u.", ifp->name, if_tmp.mtu, ifp->mtu); /* Must reset the interface (simulate down/up) when MTU * changes. */ eigrp_if_reset(ifp); } return 0; } zebra_interface_if_set_value(zclient->ibuf, ifp); if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug("Zebra: Interface[%s] state change to up.", ifp->name); if (ifp->info) eigrp_if_up(ifp->info); return 0; } static int eigrp_interface_state_down(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); if (ifp == NULL) return 0; if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug("Zebra: Interface[%s] state change to down.", ifp->name); if (ifp->info) eigrp_if_down(ifp->info); return 0; } static struct interface *zebra_interface_if_lookup(struct stream *s) { char ifname_tmp[INTERFACE_NAMSIZ]; /* Read interface name. */ stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); /* And look it up. */ return if_lookup_by_name(ifname_tmp, VRF_DEFAULT); }