/* *=========================================================================== * ipnet_rtnetlink_route_delroute_family *=========================================================================== * Description: Delete a route via NETLINK. * Parameters: data - Message payload * len - Length of message. * nlh - NETLINK message header * arg - Reference to route attributes. * * Returns: 0 - Success * <0 - Failure * */ IP_GLOBAL int ipnet_rtnetlink_route_delroute_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlh, struct Ip_rtattr **rta, int family) { int ret = -1; Ip_u16 vr; Ip_u32 table; Ip_u32 ifindex = 0; Ip_bool is_multipath_route = IP_FALSE; Ip_size_t mpa_size = 0; struct Ip_rtnexthop *nh = IP_NULL; struct Ip_sockaddr *gw = IP_NULL; void *mask = IP_NULL; struct Ip_rtmsg *rtm = IP_NLMSG_DATA(nlh); union Ip_sockaddr_union ugw; Ipnet_rtnetlink_key_t ukey; #ifdef IPMPLS struct Ip_sockaddr_mpls gw_mpls; #endif /* IPMPLS */ table = IPCOM_ROUTE_TABLE_GET(rtm->rtm_table); #ifdef IPNET_USE_ROUTE_TABLE_NAMES if (rta[IP_RTA_TABLE_NAME -1]) { if (ipnet_route_vr_and_table_from_name(IP_RTA_DATA(rta[IP_RTA_TABLE_NAME - 1]), &vr, &table) < 0) return -IP_ERRNO_ESRCH; } else #endif { if (mem->vr == IPCOM_VR_ANY) return -IP_ERRNO_EINVAL; vr = ipnet_rtnetlink_vr(rta[IP_RTA_VR - 1], mem->vr); if (rta[IP_RTA_TABLE - 1]) table = IP_GET_32ON8(IP_RTA_DATA(rta[IP_RTA_TABLE - 1])); } if (rta[IP_RTA_OIF -1]) { if (rta[IP_RTA_OIF-1]->rta_len != IP_RTA_LENGTH(sizeof(Ip_u32))) return -IP_ERRNO_EINVAL; ifindex = IP_GET_32ON8(IP_RTA_DATA(rta[IP_RTA_OIF-1])); } if (rta[IP_RTA_MULTIPATH -1]) { is_multipath_route = IP_TRUE; nh = IP_RTA_DATA(rta[IP_RTA_MULTIPATH-1]); mpa_size = IP_RTA_PAYLOAD(rta[IP_RTA_MULTIPATH-1]); if ((nh == IP_NULL) || (mpa_size == 0)) return -IP_ERRNO_EINVAL; } if ((ret = ipnet_rtnetlink_route_key_setup(family, &ukey, ifindex, &mask, rtm->rtm_dst_len, rta[IP_RTA_DST-1])) < 0) return ret; if ((ret = ipnet_rtnetlink_route_gw_setup(family, ifindex, &ugw, &gw, rta[IP_RTA_GATEWAY-1])) < 0) return ret; if (rta[IP_RTA_GATEWAY-1]) gw = &ugw.sa; #ifdef IPMPLS if (rta[IP_RTA_NH_PROTO-1]) { Ip_u32 nh_type; /* IPNET MPLS pseudo-wire route */ if (rta[IP_RTA_NH_PROTO-1]->rta_len != IP_RTA_LENGTH(sizeof(Ip_u32))) return -IP_ERRNO_EINVAL; if (rta[IP_RTA_NH_PROTO_DATA-1]->rta_len != IP_RTA_LENGTH(sizeof(Ip_u32))) return -IP_ERRNO_EINVAL; ipcom_memcpy(&nh_type, IP_RTA_DATA(rta[IP_RTA_NH_PROTO-1]), sizeof(Ip_u32)); if (nh_type != IPNET_ETH_P_MPLS_UNICAST) return -IP_ERRNO_EINVAL; ipcom_memset(&gw_mpls, 0, sizeof(gw_mpls)); gw_mpls.smpls_family = IP_AF_MPLS; IPCOM_SA_LEN_SET(&gw_mpls, sizeof (struct Ip_sockaddr_mpls)); ipcom_memcpy(&gw_mpls.smpls_key, IP_RTA_DATA(rta[IP_RTA_NH_PROTO_DATA-1]), sizeof(Ip_u32)); gw = (struct Ip_sockaddr *)&gw_mpls; } #endif while(1) { if (is_multipath_route) { ifindex = nh->rtnh_ifindex; if (nh->rtnh_len > sizeof(struct Ip_rtnexthop)) { /* Multihop route has gateway */ if ((ret = ipnet_rtnetlink_route_gw_setup(family, ifindex, &ugw, &gw, IP_RTNH_DATA(nh))) < 0) return ret; } } /* Delete the route */ ret = ipnet_route_delete2(family, vr, table, &ukey, mask, gw, ifindex, 0, 0, 0); if (is_multipath_route) { mpa_size -= IP_RTNH_ALIGN(nh->rtnh_len); gw = IP_NULL; if (mpa_size > 0) nh = IP_RTNH_NEXT(nh); else break; } else break; } return is_multipath_route ? 0 : ret; }
/* *=========================================================================== * ipnet_rtnetlink_neigh_delneigh_family *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL int ipnet_rtnetlink_neigh_delneigh_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlmsg, struct Ip_rtattr **rta, int family) { /**/ Ip_u16 vr; Ip_u32 table = IPCOM_ROUTE_TABLE_DEFAULT; Ipnet_netif *netif; int ret = -IP_ERRNO_EAFNOSUPPORT; struct Ip_ndmsg *ndm = IP_NLMSG_DATA(nlmsg); Ipnet_rtnetlink_key_t ukey; /* Destination address required */ if (rta[IP_NDA_DST-1] == IP_NULL) return -IP_ERRNO_EINVAL; #ifdef IPNET_USE_ROUTE_TABLE_NAMES if (rta[IP_NDA_TABLE_NAME -1]) { /* Extract router and table from name */ if (ipnet_route_vr_and_table_from_name(IP_RTA_DATA(rta[IP_NDA_TABLE_NAME - 1]), &vr, &table) < 0) return -IP_ERRNO_ESRCH; } else #endif { if (mem->vr == IPCOM_VR_ANY) return -IP_ERRNO_EINVAL; vr = ipnet_rtnetlink_vr(rta[IP_NDA_VR - 1], mem->vr); if (rta[IP_NDA_TABLE - 1]) table = IP_GET_32ON8(IP_RTA_DATA(rta[IP_NDA_TABLE - 1])); } netif = ipnet_if_indextonetif(vr, ndm->ndm_ifindex); if (netif && (netif->vr_index != vr)) return -IP_ERRNO_EINVAL; /* */ if ((ret = ipnet_rtnetlink_route_key_setup(family, &ukey, netif? netif->ipcom.ifindex : 0, IP_NULL, -1, rta[IP_NDA_DST-1])) < 0) return ret; /* Delete neighbor */ ret = ipnet_route_delete2(family, vr, table, &ukey, IP_NULL, IP_NULL, netif ? netif->ipcom.ifindex : 0, 0, 0, 0); return ret; }