/* Utility function of convert between struct prefix <=> union sockunion. * FIXME This function isn't used anywhere. */ struct prefix * sockunion2prefix (const union sockunion *dest, const union sockunion *mask) { if (dest->sa.sa_family == AF_INET) { struct prefix_ipv4 *p; p = prefix_ipv4_new (); p->family = AF_INET; p->prefix = dest->sin.sin_addr; p->prefixlen = ip_masklen (mask->sin.sin_addr); return (struct prefix *) p; } #ifdef HAVE_IPV6 if (dest->sa.sa_family == AF_INET6) { struct prefix_ipv6 *p; p = prefix_ipv6_new (); p->family = AF_INET6; p->prefixlen = ip6_masklen (mask->sin6.sin6_addr); memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr)); return (struct prefix *) p; } #endif /* HAVE_IPV6 */ return NULL; }
/* Utility function of convert between struct prefix <=> union sockunion. */ struct prefix * sockunion2hostprefix (const union sockunion *su) { if (su->sa.sa_family == AF_INET) { struct prefix_ipv4 *p; p = prefix_ipv4_new (); p->family = AF_INET; p->prefix = su->sin.sin_addr; p->prefixlen = IPV4_MAX_BITLEN; return (struct prefix *) p; } #ifdef HAVE_IPV6 if (su->sa.sa_family == AF_INET6) { struct prefix_ipv6 *p; p = prefix_ipv6_new (); p->family = AF_INET6; p->prefixlen = IPV6_MAX_BITLEN; memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr)); return (struct prefix *) p; } #endif /* HAVE_IPV6 */ return NULL; }
int recv_routes_reply(struct ctrl_client * ctrl_client, struct rfpbuf * buffer) { const struct rfp_ipv4_route * rir = buffer->data; struct route_ipv4 * route = new_route(); route->p = prefix_ipv4_new(); route->p->family = AF_INET; memcpy(&route->p->prefix, &rir->p, 4); route->p->prefixlen = ntohs(rir->prefixlen); // print route if(IS_OSPF6_SIBLING_DEBUG_MSG) { char prefix_str[INET_ADDRSTRLEN]; if (inet_ntop(AF_INET, &(route->p->prefix.s_addr), prefix_str, INET_ADDRSTRLEN) != 1) zlog_debug("%s/%d", prefix_str, route->p->prefixlen); } return 0; }
void isis_circuit_add_addr (struct isis_circuit *circuit, struct connected *connected) { struct listnode *node; struct prefix_ipv4 *ipv4; u_char buf[BUFSIZ]; #ifdef HAVE_IPV6 struct prefix_ipv6 *ipv6; #endif /* HAVE_IPV6 */ memset (&buf, 0, BUFSIZ); if (connected->address->family == AF_INET) { u_int32_t addr = connected->address->u.prefix4.s_addr; addr = ntohl (addr); if (IPV4_NET0(addr) || IPV4_NET127(addr) || IN_CLASSD(addr) || IPV4_LINKLOCAL(addr)) return; for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ipv4)) if (prefix_same ((struct prefix *) ipv4, connected->address)) return; ipv4 = prefix_ipv4_new (); ipv4->prefixlen = connected->address->prefixlen; ipv4->prefix = connected->address->u.prefix4; listnode_add (circuit->ip_addrs, ipv4); /* Update MPLS TE Local IP address parameter */ set_circuitparams_local_ipaddr (circuit->mtc, ipv4->prefix); if (circuit->area) lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); #ifdef EXTREME_DEBUG prefix2str (connected->address, buf, BUFSIZ); zlog_debug ("Added IP address %s to circuit %d", buf, circuit->circuit_id); #endif /* EXTREME_DEBUG */ }
/* * EIGRP UPDATE read function */ void eigrp_update_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph, struct stream * s, struct eigrp_interface *ei, int size) { struct eigrp_neighbor *nbr; struct TLV_IPv4_Internal_type *tlv; struct eigrp_prefix_entry *pe; struct eigrp_neighbor_entry *ne; u_int32_t flags; u_int16_t type; uint16_t length; u_char same; struct access_list *alist; struct prefix_list *plist; struct eigrp *e; u_char graceful_restart; u_char graceful_restart_final; struct list *nbr_prefixes; int ret; /* increment statistics. */ ei->update_in++; /* get neighbor struct */ nbr = eigrp_nbr_get(ei, eigrph, iph); /* neighbor must be valid, eigrp_nbr_get creates if none existed */ assert(nbr); flags = ntohl(eigrph->flags); if (flags & EIGRP_CR_FLAG) { return; } same = 0; graceful_restart = 0; graceful_restart_final = 0; if((nbr->recv_sequence_number) == (ntohl(eigrph->sequence))) same = 1; nbr->recv_sequence_number = ntohl(eigrph->sequence); if (IS_DEBUG_EIGRP_PACKET(0, RECV)) zlog_debug("Processing Update size[%u] int(%s) nbr(%s) seq [%u] flags [%0x]", size, ifindex2ifname(nbr->ei->ifp->ifindex), inet_ntoa(nbr->src), nbr->recv_sequence_number, flags); if((flags == (EIGRP_INIT_FLAG+EIGRP_RS_FLAG+EIGRP_EOT_FLAG)) && (!same)) { /* Graceful restart Update received with all routes */ zlog_info("Neighbor %s (%s) is resync: peer graceful-restart", inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex)); /* get all prefixes from neighbor from topology table */ nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr); graceful_restart = 1; graceful_restart_final = 1; } else if((flags == (EIGRP_INIT_FLAG+EIGRP_RS_FLAG)) && (!same)) { /* Graceful restart Update received, routes also in next packet */ zlog_info("Neighbor %s (%s) is resync: peer graceful-restart", inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex)); /* get all prefixes from neighbor from topology table */ nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr); /* save prefixes to neighbor for later use */ nbr->nbr_gr_prefixes = nbr_prefixes; graceful_restart = 1; graceful_restart_final = 0; } else if((flags == (EIGRP_EOT_FLAG)) && (!same)) { /* If there was INIT+RS Update packet before, * consider this as GR EOT */ if(nbr->nbr_gr_prefixes != NULL) { /* this is final packet of GR */ nbr_prefixes = nbr->nbr_gr_prefixes; nbr->nbr_gr_prefixes = NULL; graceful_restart = 1; graceful_restart_final = 1; } } else if((flags == (0)) && (!same)) { /* If there was INIT+RS Update packet before, * consider this as GR not final packet */ if(nbr->nbr_gr_prefixes != NULL) { /* this is GR not final route packet */ nbr_prefixes = nbr->nbr_gr_prefixes; graceful_restart = 1; graceful_restart_final = 0; } } else if((flags & EIGRP_INIT_FLAG) && (!same)) { /* When in pending state, send INIT update only if it wasn't already sent before (only if init_sequence is 0) */ if((nbr->state == EIGRP_NEIGHBOR_PENDING) && (nbr->init_sequence_number == 0)) eigrp_update_send_init(nbr); if (nbr->state == EIGRP_NEIGHBOR_UP) { eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN); eigrp_topology_neighbor_down(nbr->ei->eigrp,nbr); nbr->recv_sequence_number = ntohl(eigrph->sequence); zlog_info("Neighbor %s (%s) is down: peer restarted", inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex)); eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING); zlog_info("Neighbor %s (%s) is pending: new adjacency", inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex)); eigrp_update_send_init(nbr); } } /*If there is topology information*/ while (s->endp > s->getp) { type = stream_getw(s); if (type == EIGRP_TLV_IPv4_INT) { stream_set_getp(s, s->getp - sizeof(u_int16_t)); tlv = eigrp_read_ipv4_tlv(s); /*searching if destination exists */ struct prefix_ipv4 *dest_addr; dest_addr = prefix_ipv4_new(); dest_addr->prefix = tlv->destination; dest_addr->prefixlen = tlv->prefix_length; struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4( eigrp->topology_table, dest_addr); /*if exists it comes to DUAL*/ if (dest != NULL) { /* remove received prefix from neighbor prefix list if in GR */ if(graceful_restart) remove_received_prefix_gr(nbr_prefixes, dest); struct eigrp_fsm_action_message *msg; msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, sizeof(struct eigrp_fsm_action_message)); struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(dest->entries, nbr); msg->packet_type = EIGRP_OPC_UPDATE; msg->eigrp = eigrp; msg->data_type = EIGRP_TLV_IPv4_INT; msg->adv_router = nbr; msg->data.ipv4_int_type = tlv; msg->entry = entry; msg->prefix = dest; int event = eigrp_get_fsm_event(msg); eigrp_fsm_event(msg, event); } else { /*Here comes topology information save*/ pe = eigrp_prefix_entry_new(); pe->serno = eigrp->serno; pe->destination_ipv4 = dest_addr; pe->af = AF_INET; pe->state = EIGRP_FSM_STATE_PASSIVE; pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE; ne = eigrp_neighbor_entry_new(); ne->ei = ei; ne->adv_router = nbr; ne->reported_metric = tlv->metric; ne->reported_distance = eigrp_calculate_metrics(eigrp, &tlv->metric); //TODO: Work in progress /* * Filtering */ e = eigrp_lookup(); /* get access-list from eigrp process */ alist = e->list[EIGRP_FILTER_IN]; zlog_info("PROC IN Prefix: %s", inet_ntoa(dest_addr->prefix)); if (alist) { zlog_info ("ALIST PROC IN: %s", alist->name); } else { zlog_info("ALIST PROC IN je prazdny"); } /* Check if access-list fits */ if (alist && access_list_apply (alist, (struct prefix *) dest_addr) == FILTER_DENY) { /* If yes, set reported metric to Max */ zlog_info("PROC alist IN: Skipping"); //ne->reported_metric.delay = EIGRP_MAX_METRIC; zlog_info("PROC IN Prefix: %s", inet_ntoa(dest_addr->prefix)); eigrp_IPv4_InternalTLV_free (tlv); continue; } else { zlog_info("PROC alist IN: NENastavujem metriku "); } plist = e->prefix[EIGRP_FILTER_IN]; if (plist) { zlog_info ("PLIST PROC IN: %s", plist->name); } else { zlog_info("PLIST PROC IN je prazdny"); } /* Check if prefix-list fits */ if (plist && prefix_list_apply (plist, (struct prefix *) dest_addr) == FILTER_DENY) { /* If yes, set reported metric to Max */ zlog_info("PLIST PROC IN: Skipping"); //ne->reported_metric.delay = EIGRP_MAX_METRIC; zlog_info("PLIST PROC IN Prefix: %s", inet_ntoa(dest_addr->prefix)); eigrp_IPv4_InternalTLV_free (tlv); continue; } else { zlog_info("PLIST PROC IN: NENastavujem metriku "); } //Check route-map /*if (e->routemap[EIGRP_FILTER_IN]) { ret = route_map_apply (e->routemap[EIGRP_FILTER_IN], (struct prefix *)dest_addr, RMAP_EIGRP, NULL); if (ret == RMAP_DENYMATCH) { zlog_debug ("%s is filtered by route-map",inet_ntoa (dest_addr->prefix)); continue; } }*/ /*Get access-list from current interface */ zlog_info("Checking access_list on interface: %s",ei->ifp->name); alist = ei->list[EIGRP_FILTER_IN]; if (alist) { zlog_info ("ALIST INT IN: %s", alist->name); } else { zlog_info("ALIST INT IN je prazdny"); } /* Check if access-list fits */ if (alist && access_list_apply (alist, (struct prefix *) dest_addr) == FILTER_DENY) { /* If yes, set reported metric to Max */ zlog_info("INT alist IN: Skipping"); //ne->reported_metric.delay = EIGRP_MAX_METRIC; zlog_info("INT IN Prefix: %s", inet_ntoa(dest_addr->prefix)); eigrp_IPv4_InternalTLV_free (tlv); continue; } else { zlog_info("INT IN: NENastavujem metriku "); } plist = ei->prefix[EIGRP_FILTER_IN]; if (plist) { zlog_info ("PLIST INT IN: %s", plist->name); } else { zlog_info("PLIST INT IN je prazdny"); } /* Check if prefix-list fits */ if (plist && prefix_list_apply (plist, (struct prefix *) dest_addr) == FILTER_DENY) { /* If yes, set reported metric to Max */ zlog_info("PLIST INT IN: Skipping"); //ne->reported_metric.delay = EIGRP_MAX_METRIC; zlog_info("PLIST INT IN Prefix: %s", inet_ntoa(dest_addr->prefix)); eigrp_IPv4_InternalTLV_free (tlv); continue; } else { zlog_info("PLIST INT IN: NENastavujem metriku "); } //Check route-map /*if (ei->routemap[EIGRP_FILTER_IN]) { ret = route_map_apply (ei->routemap[EIGRP_FILTER_IN], (struct prefix *)dest_addr, RMAP_EIGRP, NULL); if (ret == RMAP_DENYMATCH) { zlog_debug ("%s is filtered by route-map",inet_ntoa (dest_addr->prefix)); continue; } }*/ /* * End of filtering */ ne->distance = eigrp_calculate_total_metrics(eigrp, ne); zlog_info("<DEBUG PROC IN Distance: %x", ne->distance); zlog_info("<DEBUG PROC IN Delay: %x", ne->total_metric.delay); pe->fdistance = pe->distance = pe->rdistance = ne->distance; ne->prefix = pe; ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; eigrp_prefix_entry_add(eigrp->topology_table, pe); eigrp_neighbor_entry_add(pe, ne); pe->distance = pe->fdistance = pe->rdistance = ne->distance; pe->reported_metric = ne->total_metric; eigrp_topology_update_node_flags(pe); pe->req_action |= EIGRP_FSM_NEED_UPDATE; listnode_add(eigrp->topology_changes_internalIPV4, pe); } eigrp_IPv4_InternalTLV_free (tlv); } } /* ask about prefixes not present in GR update, * if this is final GR packet */ if(graceful_restart_final) { eigrp_update_receive_GR_ask(eigrp, nbr, nbr_prefixes); } /* * We don't need to send separate Ack for INIT Update. INIT will be acked in EOT Update. */ if ((nbr->state == EIGRP_NEIGHBOR_UP) && !(flags == EIGRP_INIT_FLAG)) { eigrp_hello_send_ack(nbr); } eigrp_query_send_all(eigrp); eigrp_update_send_all(eigrp, ei); }
/* Add connected IPv4 route to the interface. */ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, u_char prefixlen, struct in_addr *broad, const char *label) { struct prefix_ipv4 *p; struct connected *ifc; /* Make connected structure. */ ifc = connected_new(); ifc->ifp = ifp; ifc->flags = flags; /* If we get a notification from the kernel, * we can safely assume the address is known to the kernel */ SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); /* Allocate new connected address. */ p = prefix_ipv4_new(); p->family = AF_INET; p->prefix = *addr; p->prefixlen = prefixlen; ifc->address = (struct prefix *)p; /* If there is broadcast or peer address. */ if (broad) { p = prefix_ipv4_new(); p->family = AF_INET; p->prefix = *broad; p->prefixlen = prefixlen; ifc->destination = (struct prefix *)p; /* validate the destination address */ if (CONNECTED_PEER(ifc)) { if (IPV4_ADDR_SAME(addr, broad)) zlog_warn ("warning: interface %s has same local and peer " "address %s, routing protocols may malfunction", ifp->name, inet_ntoa(*addr)); } else { if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr, prefixlen)) { char buf[2][INET_ADDRSTRLEN]; struct in_addr bcalc; bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr, prefixlen); zlog_warn ("warning: interface %s broadcast addr %s/%d != " "calculated %s, routing protocols may malfunction", ifp->name, inet_ntop(AF_INET, broad, buf[0], sizeof(buf[0])), prefixlen, inet_ntop(AF_INET, &bcalc, buf[1], sizeof(buf[1]))); } } } else { if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) { zlog_warn("warning: %s called for interface %s " "with peer flag set, but no peer address supplied", __func__, ifp->name); UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } /* no broadcast or destination address was supplied */ if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) zlog_warn ("warning: PtP interface %s with addr %s/%d needs a " "peer address", ifp->name, inet_ntoa(*addr), prefixlen); } /* Label of this address. */ if (label) ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); /* For all that I know an IPv4 address is always ready when we receive * the notification. So it should be safe to set the REAL flag here. */ SET_FLAG(ifc->conf, ZEBRA_IFC_REAL); connected_update(ifp, ifc); }
struct ospf_interface * ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data) { struct ospf_interface * voi; struct interface * vi; char ifname[INTERFACE_NAMSIZ + 1]; struct ospf_area *area; struct in_addr area_id; struct connected *co; struct prefix_ipv4 *p; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): Start"); if (vlink_count == OSPF_VL_MAX_COUNT) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): Alarm: " "cannot create more than OSPF_MAX_VL_COUNT virtual links"); return NULL; } if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): creating pseudo zebra interface"); snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count); vi = if_create (ifname, strnlen(ifname, sizeof(ifname))); co = connected_new (); co->ifp = vi; listnode_add (vi->connected, co); p = prefix_ipv4_new (); p->family = AF_INET; p->prefix.s_addr = 0; p->prefixlen = 0; co->address = (struct prefix *)p; voi = ospf_if_new (ospf, vi, co->address); if (voi == NULL) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created"); return NULL; } voi->connected = co; voi->vl_data = vl_data; voi->ifp->mtu = OSPF_VL_MTU; voi->type = OSPF_IFTYPE_VIRTUALLINK; vlink_count++; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): Created name: %s", ifname); if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name); area_id.s_addr = 0; area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS); voi->area = area; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): set associated area to the backbone"); ospf_nbr_add_self (voi); ospf_area_add_if (voi->area, voi); ospf_if_stream_set (voi); if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_vl_new(): Stop"); return voi; }
/*EIGRP QUERY read function*/ void eigrp_query_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph, struct stream * s, struct eigrp_interface *ei, int size) { struct eigrp_neighbor *nbr; struct TLV_IPv4_Internal_type *tlv; struct eigrp_prefix_entry *temp_tn; struct eigrp_neighbor_entry *temp_te; u_int16_t type; /* increment statistics. */ ei->query_in++; /* get neighbor struct */ nbr = eigrp_nbr_get(ei, eigrph, iph); /* neighbor must be valid, eigrp_nbr_get creates if none existed */ assert(nbr); nbr->recv_sequence_number = ntohl(eigrph->sequence); while (s->endp > s->getp) { type = stream_getw(s); if (type == EIGRP_TLV_IPv4_INT) { stream_set_getp(s, s->getp - sizeof(u_int16_t)); tlv = eigrp_read_ipv4_tlv(s); struct prefix_ipv4 *dest_addr; dest_addr = prefix_ipv4_new(); dest_addr->prefix = tlv->destination; dest_addr->prefixlen = tlv->prefix_length; struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4( eigrp->topology_table, dest_addr); /* If the destination exists (it should, but one never know)*/ if (dest != NULL) { struct eigrp_fsm_action_message *msg; msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, sizeof(struct eigrp_fsm_action_message)); struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup( dest->entries, nbr); msg->packet_type = EIGRP_OPC_QUERY; msg->eigrp = eigrp; msg->data_type = EIGRP_TLV_IPv4_INT; msg->adv_router = nbr; msg->data.ipv4_int_type = tlv; msg->entry = entry; msg->prefix = dest; int event = eigrp_get_fsm_event(msg); eigrp_fsm_event(msg, event); } eigrp_IPv4_InternalTLV_free (tlv); } } eigrp_hello_send_ack(nbr); eigrp_query_send_all(eigrp); eigrp_update_send_all(eigrp,nbr->ei); }
/* Add connected IPv4 route to the interface. */ void connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, u_char prefixlen, struct in_addr *broad, const char *label) { struct prefix_ipv4 *p; struct connected *ifc; /* Make connected structure. */ ifc = connected_new (); ifc->ifp = ifp; ifc->flags = flags; /* Allocate new connected address. */ p = prefix_ipv4_new (); p->family = AF_INET; p->prefix = *addr; p->prefixlen = prefixlen; ifc->address = (struct prefix *) p; /* If there is broadcast or peer address. */ if (broad) { p = prefix_ipv4_new (); p->family = AF_INET; p->prefix = *broad; p->prefixlen = prefixlen; ifc->destination = (struct prefix *) p; /* validate the destination address */ if (CONNECTED_PEER(ifc)) { if (IPV4_ADDR_SAME(addr,broad)) zlog_warn("warning: interface %s has same local and peer " "address %s, routing protocols may malfunction", ifp->name,inet_ntoa(*addr)); } else { if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen)) { char buf[2][INET_ADDRSTRLEN]; struct in_addr bcalc; bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen); zlog_warn("warning: interface %s broadcast addr %s/%d != " "calculated %s, routing protocols may malfunction", ifp->name, inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])), prefixlen, inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1]))); } } } else { if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) { zlog_warn("warning: %s called for interface %s " "with peer flag set, but no peer address supplied", __func__, ifp->name); UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } /* no broadcast or destination address was supplied */ if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) zlog_warn("warning: PtP interface %s with addr %s/%d needs a " "peer address",ifp->name,inet_ntoa(*addr),prefixlen); } /* Label of this address. */ if (label) ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); /* nothing to do? */ if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL) return; connected_announce (ifp, ifc); }
/* Add connected IPv4 route to the interface. */ void connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, u_char prefixlen, struct in_addr *broad, const char *label) { struct prefix_ipv4 *p; struct connected *ifc; /* Make connected structure. */ ifc = connected_new (); ifc->ifp = ifp; ifc->flags = flags; /* Allocate new connected address. */ p = prefix_ipv4_new (); p->family = AF_INET; p->prefix = *addr; p->prefixlen = prefixlen; ifc->address = (struct prefix *) p; /* If there is broadcast or pointopoint address. */ if (broad) { p = prefix_ipv4_new (); p->family = AF_INET; p->prefix = *broad; ifc->destination = (struct prefix *) p; /* validate the destination address */ if (ifp->flags & IFF_POINTOPOINT) { if (IPV4_ADDR_SAME(addr,broad)) zlog_warn("warning: PtP interface %s has same local and peer " "address %s, routing protocols may malfunction", ifp->name,inet_ntoa(*addr)); else if ((prefixlen != IPV4_MAX_PREFIXLEN) && (ipv4_network_addr(addr->s_addr,prefixlen) != ipv4_network_addr(broad->s_addr,prefixlen))) { char buf[2][INET_ADDRSTRLEN]; zlog_warn("warning: PtP interface %s network mismatch: local " "%s/%d vs. peer %s, routing protocols may malfunction", ifp->name, inet_ntop (AF_INET, addr, buf[0], sizeof(buf[0])), prefixlen, inet_ntop (AF_INET, broad, buf[1], sizeof(buf[1]))); } } else { if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen)) { char buf[2][INET_ADDRSTRLEN]; struct in_addr bcalc; bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen); zlog_warn("warning: interface %s broadcast addr %s/%d != " "calculated %s, routing protocols may malfunction", ifp->name, inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])), prefixlen, inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1]))); } /*gjd : for Rtsuit restart , ip address write show running.*/ if(!CHECK_FLAG(ifc->ip_config,RTMD_RESTART_IP_CONFIG)&&(keep_kernel_mode == 1)) { SET_FLAG(ifc->ip_config,RTMD_RESTART_IP_CONFIG); /*zlog_err("%s : line %d ifc->conf(%u), ifc->ipconfig(%u).\n", __func__,__LINE__,ifc->conf,ifc->ip_config);*/ } } } else /* no broadcast or destination address was supplied */ if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) zlog_warn("warning: PtP interface %s with addr %s/%d needs a " "peer address",ifp->name,inet_ntoa(*addr),prefixlen); /* Label of this address. */ if (label) ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); /* nothing to do? */ if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL) return; connected_announce (ifp, ifc); }