int vr_send_route_dump(struct nl_client *cl, unsigned int router_id, unsigned int vrf, unsigned int family, uint8_t *marker, unsigned int marker_plen) { vr_route_req req; memset(&req, 0, sizeof(req)); req.h_op = SANDESH_OP_DUMP; req.rtr_rid = router_id; req.rtr_vrf_id = vrf; req.rtr_family = family; if (family == AF_BRIDGE) { if (marker_plen != VR_ETHER_ALEN) return -EINVAL; req.rtr_mac = marker; req.rtr_mac_size = VR_ETHER_ALEN; } else { req.rtr_prefix = marker; req.rtr_prefix_size = RT_IP_ADDR_SIZE(family); req.rtr_marker = marker; req.rtr_marker_size = RT_IP_ADDR_SIZE(family); req.rtr_marker_plen = marker_plen; } return vr_sendmsg(cl, &req, "vr_route_req"); }
int inet_route_add(struct rtable_fspec *fs, struct vr_route_req *req) { int i; struct vr_rtable *rtable; struct vrouter *router; unsigned int pmask, pmask_byte; router = vrouter_get(req->rtr_req.rtr_rid); if (!router) return -EINVAL; /* V4 and V6 only */ if (req->rtr_req.rtr_family != AF_INET && req->rtr_req.rtr_family != AF_INET6) return -EINVAL; /* There has to be some prefix to add */ if (!req->rtr_req.rtr_prefix_size) return -EINVAL; rtable = router->vr_inet_rtable; if (!rtable || ((unsigned int)req->rtr_req.rtr_vrf_id >= fs->rtb_max_vrfs) || ((unsigned int)(req->rtr_req.rtr_prefix_len) > (RT_IP_ADDR_SIZE(req->rtr_req.rtr_family)*8))) return -EINVAL; if (req->rtr_req.rtr_prefix) { if (req->rtr_req.rtr_family == AF_INET) pmask = ~((1 << (32 - req->rtr_req.rtr_prefix_len)) - 1); else pmask = 0; /* TBD: Assume V6 prefix length will be multiple of 8 */ pmask_byte = req->rtr_req.rtr_prefix_len/8; if (pmask_byte < (RT_IP_ADDR_SIZE(req->rtr_req.rtr_family)-1)) { for (i=pmask_byte+1; i<RT_IP_ADDR_SIZE(req->rtr_req.rtr_family); i++) { req->rtr_req.rtr_prefix[i] = 0; pmask = pmask >> 8; } req->rtr_req.rtr_prefix[pmask_byte] = req->rtr_req.rtr_prefix[pmask_byte] & (pmask & 0xff); } } if (rtable) { if (rtable->algo_add) return rtable->algo_add(rtable, req); else return -1; } else { return -1; } }
int vr_route_dump(vr_route_req *req) { struct vr_route_req vr_req; struct vrouter *router; struct vr_rtable *rtable = NULL; int ret; uint32_t rt_prefix[4], rt_marker[4]; vr_req.rtr_req = *req; vr_req.rtr_req.rtr_prefix_size = req->rtr_prefix_size; if (req->rtr_prefix_size) { vr_req.rtr_req.rtr_prefix = (uint8_t*)&rt_prefix; memcpy(vr_req.rtr_req.rtr_prefix, req->rtr_prefix, RT_IP_ADDR_SIZE(req->rtr_family)); } else { vr_req.rtr_req.rtr_prefix = NULL; } vr_req.rtr_req.rtr_marker_size = req->rtr_marker_size; vr_req.rtr_req.rtr_marker_plen = req->rtr_prefix_len; if (req->rtr_marker_size) { vr_req.rtr_req.rtr_marker = (uint8_t*)&rt_marker; memcpy(vr_req.rtr_req.rtr_marker, req->rtr_marker, RT_IP_ADDR_SIZE(req->rtr_family)); } else { vr_req.rtr_req.rtr_marker = NULL; } router = vrouter_get(req->rtr_rid); if (!router) { ret = -ENOENT; goto generate_error; } else { if (req->rtr_family == AF_BRIDGE) { rtable = router->vr_bridge_rtable; } else { rtable = router->vr_inet_rtable; } if (!rtable) { ret = -ENOENT; goto generate_error; } ret = rtable->algo_dump(NULL, &vr_req); } return ret; generate_error: vr_send_response(ret); return ret; }
int vr_route_add(vr_route_req *req) { struct rtable_fspec *fs; struct vr_route_req vr_req; int ret; uint32_t rt_prefix[4]; fs = vr_get_family(req->rtr_family); if (!fs) { ret = -ENOENT; } else { vr_req.rtr_req = *req; if (req->rtr_prefix_size) { vr_req.rtr_req.rtr_prefix = (uint8_t*)&rt_prefix; memcpy(vr_req.rtr_req.rtr_prefix, req->rtr_prefix, RT_IP_ADDR_SIZE(req->rtr_family)); vr_req.rtr_req.rtr_marker_size = 0; vr_req.rtr_req.rtr_prefix_size = req->rtr_prefix_size; } else { vr_req.rtr_req.rtr_prefix = NULL; } ret = fs->route_add(fs, &vr_req); } vr_send_response(ret); return ret; }
static int vr_send_route_common(struct nl_client *cl, unsigned int op, unsigned int router_id, unsigned int vrf, unsigned int family, uint8_t *prefix, unsigned int prefix_len, unsigned int nh_index, int label, uint8_t *mac, uint32_t replace_len, unsigned int flags) { vr_route_req req; memset(&req, 0, sizeof(req)); req.h_op = op; req.rtr_rid = router_id; req.rtr_vrf_id = vrf; req.rtr_family = family; req.rtr_prefix = prefix; req.rtr_prefix_size = RT_IP_ADDR_SIZE(family); req.rtr_prefix_len = prefix_len; if (mac) { req.rtr_mac = mac; req.rtr_mac_size = VR_ETHER_ALEN; } req.rtr_replace_plen = replace_len; req.rtr_label_flags = flags; req.rtr_label = label; if (label != -1) req.rtr_label_flags |= VR_RT_LABEL_VALID_FLAG; req.rtr_nh_id = nh_index; return vr_sendmsg(cl, &req, "vr_route_req"); }
int inet_route_del(struct rtable_fspec *fs, struct vr_route_req *req) { struct vr_rtable *rtable; struct vrouter *router; if (((unsigned int)(req->rtr_req.rtr_prefix_len) > (RT_IP_ADDR_SIZE(req->rtr_req.rtr_family)*8)) || (unsigned int)(req->rtr_req.rtr_vrf_id) >= fs->rtb_max_vrfs) return -EINVAL; router = vrouter_get(req->rtr_req.rtr_rid); if (!router) return -EINVAL; rtable = router->vr_inet_rtable; if (!rtable || (unsigned int)req->rtr_req.rtr_vrf_id >= fs->rtb_max_vrfs) return -EINVAL; return rtable->algo_del(rtable, req); }
int vr_route_delete(vr_route_req *req) { struct rtable_fspec *fs; struct vr_route_req vr_req; int ret; uint32_t rt_prefix[4]; fs = vr_get_family(req->rtr_family); if (!fs) ret = -ENOENT; else { vr_req.rtr_req = *req; if (req->rtr_family != AF_BRIDGE && !req->rtr_prefix_size) { ret = -EINVAL; goto error; } if (req ->rtr_family == AF_BRIDGE && (!req->rtr_mac_size || !req->rtr_mac)) { ret = -EINVAL; goto error; } if (req ->rtr_family != AF_BRIDGE) { vr_req.rtr_req.rtr_prefix = (uint8_t*)&rt_prefix; memcpy(vr_req.rtr_req.rtr_prefix, req->rtr_prefix, RT_IP_ADDR_SIZE(req->rtr_family)); } vr_req.rtr_req.rtr_marker_size = 0; ret = fs->route_del(fs, &vr_req); } error: vr_send_response(ret); return ret; }
int vr_route_get(vr_route_req *req) { struct vr_route_req vr_req; struct vrouter *router; int ret = 0; uint32_t rt_prefix[4]; struct vr_rtable *rtable; vr_req.rtr_req = *req; vr_req.rtr_req.rtr_marker_size = 0; vr_req.rtr_req.rtr_prefix_size = req->rtr_prefix_size; if (req->rtr_prefix_size) { vr_req.rtr_req.rtr_prefix = (uint8_t*)&rt_prefix; memcpy(vr_req.rtr_req.rtr_prefix, req->rtr_prefix, RT_IP_ADDR_SIZE(req->rtr_family)); } else vr_req.rtr_req.rtr_prefix = NULL; router = vrouter_get(req->rtr_rid); if (!router) { ret = -ENOENT; goto generate_response; } else { rtable = router->vr_inet_rtable; if (!rtable) { ret = -ENOENT; goto generate_response; } ret = rtable->algo_get(vr_req.rtr_req.rtr_vrf_id, &vr_req); } generate_response: vr_message_response(VR_ROUTE_OBJECT_ID, ret ? NULL : &vr_req, ret); return ret; }