void connected_down_ipv4(struct interface *ifp, struct connected *ifc) { struct prefix_ipv4 p; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) return; PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask_ipv4(&p); /* In case of connected address is 0.0.0.0/0 we treat it tunnel address. */ if (prefix_ipv4_any(&p)) return; /* Same logic as for connected_up_ipv4(): push the changes into the head. */ rib_delete_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST); rib_delete_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_MULTICAST); rib_update(); }
/* Interface goes down. We have to manage different behavior of based OS. */ void if_down (struct interface *ifp) { listnode node; listnode next; struct connected *ifc; struct prefix *p; /* Notify to the protocol daemons. */ zebra_interface_down_update (ifp); /* Delete connected routes from the kernel. */ if (ifp->connected) { for (node = listhead (ifp->connected); node; node = next) { next = node->next; ifc = getdata (node); p = ifc->address; if (p->family == AF_INET) connected_down_ipv4 (ifp, ifc); #ifdef HAVE_IPV6 else if (p->family == AF_INET6) connected_down_ipv6 (ifp, ifc); #endif /* HAVE_IPV6 */ } } /* Examine all static routes which direct to the interface. */ rib_update (); }
/* Called from if_up(). */ void connected_up_ipv4(struct interface *ifp, struct connected *ifc) { struct prefix_ipv4 p; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) return; PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask_ipv4(&p); /* In case of connected address is 0.0.0.0/0 we treat it tunnel address. */ if (prefix_ipv4_any(&p)) return; rib_add_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST); rib_add_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST); rib_update(); }
/* Interface is up. */ void if_up (struct interface *ifp) { struct listnode *node; struct listnode *next; struct connected *ifc; struct prefix *p; /* Notify the protocol daemons. */ zebra_interface_up_update (ifp); /* Install connected routes to the kernel. */ if (ifp->connected) { for (node = listhead (ifp->connected); node; node = next) { next = node->next; ifc = getdata (node); p = ifc->address; if (p->family == AF_INET) connected_up_ipv4 (ifp, ifc); #ifdef HAVE_IPV6 else if (p->family == AF_INET6) connected_up_ipv6 (ifp, ifc); #endif /* HAVE_IPV6 */ } } /* Examine all static routes. */ rib_update (); }
/* Interface goes down. We have to manage different behavior of based OS. */ void if_down (struct interface *ifp) { struct listnode *node; struct listnode *next; struct connected *ifc; struct prefix *p; /* Notify to the protocol daemons. */ zebra_interface_down_update (ifp); /* Delete connected routes from the kernel. */ if (ifp->connected) { for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc)) { p = ifc->address; if (p->family == AF_INET) connected_down_ipv4 (ifp, ifc); #ifdef HAVE_IPV6 else if (p->family == AF_INET6) connected_down_ipv6 (ifp, ifc); #endif /* HAVE_IPV6 */ } } /* Examine all static routes which direct to the interface. */ rib_update (); }
void connected_down_ipv4 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv4 p; struct prefix_ipv4 *addr; struct prefix_ipv4 *dest; if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; addr = (struct prefix_ipv4 *)ifc->address; dest = (struct prefix_ipv4 *)ifc->destination; memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = addr->prefixlen; /* Point-to-point check. */ if (CONNECTED_POINTOPOINT_HOST(ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; /* Apply mask to the network. */ apply_mask_ipv4 (&p); /* In case of connected address is 0.0.0.0/0 we treat it tunnel address. */ if (prefix_ipv4_any (&p)) return; rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); rib_update (); }
void connected_up_ipv6 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; struct prefix_ipv6 *addr; struct prefix_ipv6 *dest; if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER) goto skip; #if 0 /*ipv6 not support interface loacal*/ if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL)) goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/ #endif if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; skip: addr = (struct prefix_ipv6 *) ifc->address; dest = (struct prefix_ipv6 *) ifc->destination; memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; p.prefixlen = addr->prefixlen; if (if_is_pointopoint (ifp) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; else p.prefix = dest->prefix; } else p.prefix = addr->prefix; /* Apply mask to the network. */ apply_mask_ipv6 (&p); #if ! defined (MUSICA) && ! defined (LINUX) /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */ if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) return; #endif rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, ifp->metric, 0); rib_update (); }
/* Called from if_up(). */ void connected_up_ipv4 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv4 p; struct prefix_ipv4 *addr; struct prefix_ipv4 *dest; if (IS_ZEBRA_DEBUG_RIB) zlog_debug ("%s: start", __func__); /* if(product != NULL)*/ if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER)/*gjd : change for active master 在删除ip时,直连路由没删除,因为重复添加,导致refcnt不为0释放不掉*/ goto skip; if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL)) goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/ if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; skip: addr = (struct prefix_ipv4 *) ifc->address; dest = (struct prefix_ipv4 *) ifc->destination; memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = addr->prefixlen; /* Point-to-point check. */ if (CONNECTED_POINTOPOINT_HOST(ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; /* Apply mask to the network. */ apply_mask_ipv4 (&p); /* In case of connected address is 0.0.0.0/0 we treat it tunnel address. */ if (prefix_ipv4_any (&p)) return; rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0); if (IS_ZEBRA_DEBUG_RIB) zlog_debug ("%s: goto rib_update ", __func__); rib_update (); }
void connected_down_ipv6(struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) return; PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); apply_mask_ipv6(&p); if (IN6_IS_ADDR_UNSPECIFIED(&p.prefix)) return; rib_delete_ipv6(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST); rib_update(); }
void connected_down_ipv6 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; struct prefix_ipv6 *addr; struct prefix_ipv6 *dest; if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER) goto skip; if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL)) goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/ if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; skip: addr = (struct prefix_ipv6 *) ifc->address; dest = (struct prefix_ipv6 *) ifc->destination; memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; p.prefixlen = addr->prefixlen; if (if_is_pointopoint (ifp) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; else p.prefix = dest->prefix; } else p.prefix = addr->prefix; apply_mask_ipv6 (&p); if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) return; rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); rib_update (); }
void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, u_char prefixlen, struct in6_addr *broad) { struct prefix_ipv6 p; struct connected *ifc; memset(&p, 0, sizeof(struct prefix_ipv6)); p.family = AF_INET6; memcpy(&p.prefix, address, sizeof(struct in6_addr)); p.prefixlen = prefixlen; ifc = connected_check(ifp, (struct prefix *)&p); if (!ifc) return; connected_withdraw(ifc); rib_update(); }
/* Delete connected IPv4 route to the interface. */ void connected_delete_ipv4(struct interface *ifp, int flags, struct in_addr *addr, u_char prefixlen, struct in_addr *broad) { struct prefix_ipv4 p; struct connected *ifc; memset(&p, 0, sizeof(struct prefix_ipv4)); p.family = AF_INET; p.prefix = *addr; p.prefixlen = prefixlen; ifc = connected_check(ifp, (struct prefix *)&p); if (!ifc) return; connected_withdraw(ifc); rib_update(); }
void connected_up_ipv6 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; struct prefix_ipv6 *addr; struct prefix_ipv6 *dest; if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; addr = (struct prefix_ipv6 *) ifc->address; dest = (struct prefix_ipv6 *) ifc->destination; memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; p.prefixlen = addr->prefixlen; if (if_is_pointopoint (ifp) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; else p.prefix = dest->prefix; } else p.prefix = addr->prefix; /* Apply mask to the network. */ apply_mask_ipv6 (&p); #if ! defined (MUSICA) && ! defined (LINUX) /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */ if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) return; #endif rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, ifp->metric, 0); rib_update (); }
void connected_up_ipv6(struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) return; PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask_ipv6(&p); #ifndef LINUX /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */ if (IN6_IS_ADDR_UNSPECIFIED(&p.prefix)) return; #endif rib_add_ipv6(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST); rib_update(); }
void connected_down_ipv6 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; struct prefix_ipv6 *addr; struct prefix_ipv6 *dest; if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; addr = (struct prefix_ipv6 *) ifc->address; dest = (struct prefix_ipv6 *) ifc->destination; memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; p.prefixlen = addr->prefixlen; if (if_is_pointopoint (ifp) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; else p.prefix = dest->prefix; } else p.prefix = addr->prefix; apply_mask_ipv6 (&p); if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) return; rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); rib_update (); }
void connected_down_ipv4 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv4 p; struct prefix_ipv4 *addr; struct prefix_ipv4 *dest; if (IS_ZEBRA_DEBUG_RIB) zlog_debug ("%s: start ", __func__); /*gujd: 2012-10-19, pm 3:49. When vrrp use virtual IP address , destination is NULL, so can't return.*/ #if 0 if(!ifc || !ifc->address || !ifc->destination|| !ifc->ifp) { zlog_err("ifc(%p), ifc->address(%p), ifc->destination(%p).\n", ifc,ifc->address,ifc->destination); return; } #else if(!ifc || !ifc->address || !ifc->ifp) { /*CID 11026 (#1 of 1): Dereference after null check (FORWARD_NULL) 4. var_deref_op: Dereferencing null pointer "ifc". Make sure , here is bug. So changed.*/ /*zlog_err("ifc(%p), ifc->address(%p), ifc->ifp(%p).\n", ifc,ifc->address,ifc->ifp); return ;*/ if(!ifc) { zlog_err("%s: line %d, ifc is null.\n",__func__,__LINE__); return ; } else { zlog_err("%s: line %d, ifc->address(%p), ifc->ifp(%p).\n", __func__,__LINE__,ifc->address,ifc->ifp); return ; } } #endif /* if(product != NULL)*/ if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER)/*gjd : change for active master 在删除ip时,直连路由没删除,因为重复添加,导致refcnt不为0释放不掉*/ goto skip; if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL)) goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/ if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; skip: addr = (struct prefix_ipv4 *)ifc->address; dest = (struct prefix_ipv4 *)ifc->destination; memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = addr->prefixlen; /* Point-to-point check. */ if (CONNECTED_POINTOPOINT_HOST(ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; /* Apply mask to the network. */ apply_mask_ipv4 (&p); /* In case of connected address is 0.0.0.0/0 we treat it tunnel address. */ if (prefix_ipv4_any (&p)) return; rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); if (IS_ZEBRA_DEBUG_RIB) zlog_debug ("%s: goto rib_update ", __func__); rib_update (); }