int vpnapi_control_dp_send_msg(oor_ctrl_t *ctrl, lbuf_t *buff, uconn_t *udp_conn) { int ret; int sock; ip_addr_t *src_addr, *dst_addr; vpnapi_ctr_dplane_data_t * data; data = (vpnapi_ctr_dplane_data_t *)ctrl->control_data_plane->control_dp_data; if (lisp_addr_lafi(&udp_conn->ra) != LM_AFI_IP) { OOR_LOG(LDBG_2, "vpnapi_control_dp_send_msg: Destination address %s of UDP connection is not a IP. " "Discarding!", lisp_addr_to_char(&udp_conn->ra)); return(BAD); } src_addr = lisp_addr_ip(&udp_conn->la); dst_addr = lisp_addr_ip(&udp_conn->ra); if (!lisp_addr_is_no_addr(&udp_conn->la) && (ip_addr_afi(src_addr) != ip_addr_afi(dst_addr))) { OOR_LOG(LDBG_2, "vpnapi_control_dp_send_msg: src %s and dst %s of UDP connection have " "different IP AFI. Discarding!", ip_addr_to_char(src_addr), ip_addr_to_char(dst_addr)); return(BAD); } switch (ip_addr_afi(dst_addr)){ case AF_INET: if (udp_conn->lp == LISP_CONTROL_PORT){ sock = data->ipv4_ctrl_socket; }else{ sock = data->ipv4_data_socket; } break; case AF_INET6: sock = data->ipv6_ctrl_socket; break; default: return (BAD); } ret = send_datagram_packet (sock, lbuf_data(buff), lbuf_size(buff), &udp_conn->ra, udp_conn->rp); if (ret != GOOD) { OOR_LOG(LDBG_1, "Failed to send contrl message from RLOC: %s -> %s", lisp_addr_to_char(&udp_conn->la), lisp_addr_to_char(&udp_conn->ra)); return(BAD); } else { OOR_LOG(LDBG_1, "Sent control message IP: %s -> %s UDP: %d -> %d", lisp_addr_to_char(&udp_conn->la), lisp_addr_to_char(&udp_conn->ra), udp_conn->lp, udp_conn->rp); return(GOOD); } }
static int vpnapi_output_unicast(lbuf_t *b, packet_tuple_t *tuple) { fwd_info_t *fi; fwd_entry_t *fe; fi = ttable_lookup(&ttable, tuple); if (!fi) { fi = ctrl_get_forwarding_info(tuple); if (!fi){ return (BAD); } fe = fi->fwd_info; if (fe && fe->srloc && fe->drloc) { switch (lisp_addr_ip_afi(fe->srloc)){ case AF_INET: fe->out_sock = &(((vpnapi_data_t *)dplane_vpnapi.datap_data)->ipv4_data_socket); break; case AF_INET6: fe->out_sock = &(((vpnapi_data_t *)dplane_vpnapi.datap_data)->ipv6_data_socket); break; default: LMLOG(LDBG_3,"OUTPUT: No output socket for afi %d", lisp_addr_ip_afi(fe->srloc)); return(BAD); } } ttable_insert(&ttable, pkt_tuple_clone(tuple), fi); }else{ fe = fi->fwd_info; } /* Packets with no/negative map cache entry AND no PETR * OR packets with missing src or dst RLOCs * forward them natively */ if (!fe || !fe->srloc || !fe->drloc) { LMLOG(LDBG_3,"OUTPUT: Packet with non lisp destination. No PeTRs compatibles to be used. Discarding packet"); return(BAD); } LMLOG(LDBG_3,"OUTPUT: Sending encapsulated packet: RLOC %s -> %s\n", lisp_addr_to_char(fe->srloc), lisp_addr_to_char(fe->drloc)); /* push lisp data hdr */ lisp_data_push_hdr(b); return(send_datagram_packet (*(fe->out_sock), lbuf_data(b), lbuf_size(b), fe->drloc, LISP_DATA_PORT)); }
lisp_addr_t * pref_get_network_address(lisp_addr_t *address) { lisp_addr_t *network_address = NULL; if (!lisp_addr_is_ip_pref(address)){ OOR_LOG(LDBG_2, "get_network_address: Address %s is not a prefix ", lisp_addr_to_char(address)); return (NULL); } switch (lisp_addr_ip_afi(address)){ case AF_INET: network_address = pref_get_network_address_v4(address); break; case AF_INET6: network_address = pref_get_network_address_v6(address); break; default: OOR_LOG(LDBG_2, "get_network_address: Afi not supported (%d). It should never " "reach this point", lisp_addr_ip_afi(address)); break; } return (network_address); }
static void parse_mcinfo_list(cfg_t *cfg, shash_t *ht) { mc_t *mc; lisp_addr_t *laddr; char *name; int i, count; count = 0; for (i = 0; i < cfg_size(cfg, "multicast-info"); i++) { cfg_t *mcnode = cfg_getnsec(cfg, "multicast-info", i); name = cfg_getstr(mcnode, "mc-info-name"); laddr = lisp_addr_new_lafi(LM_AFI_LCAF); lisp_addr_lcaf_set_type(laddr, LCAF_MCAST_INFO); mc = mc_type_new(); lisp_addr_ip_from_char(cfg_getstr(mcnode, "source"), mc->src); mc->src_plen = cfg_getint(mcnode, "source-mask-length"); lisp_addr_ip_from_char(cfg_getstr(mcnode, "group"), mc->grp); mc->src_plen = cfg_getint(mcnode, "group-mask-length"); mc->iid = cfg_getint(mcnode, "iid"); lisp_addr_lcaf_set_addr(laddr, mc); OOR_LOG(LDBG_1, "Configuration file: parsed multicast-info: %s", lisp_addr_to_char(laddr)); shash_insert(ht, strdup(name), laddr); count ++; } if (count != 0) { OOR_LOG(LINF, "Parsed configured multicast addresses"); } }
int parse_database_mapping(cfg_t *cfg, lisp_xtr_t *xtr, shash_t *lcaf_ht) { int n,i; mapping_t *mapping; map_local_entry_t *map_loc_e; void *fwd_map_inf; n = cfg_size(cfg, "database-mapping"); for (i = 0; i < n; i++) { mapping = parse_mapping(cfg_getnsec(cfg, "database-mapping", i),&(xtr->super),lcaf_ht,TRUE); if (mapping == NULL){ continue; } map_loc_e = map_local_entry_new_init(mapping); if (map_loc_e == NULL){ mapping_del(mapping); continue; } fwd_map_inf = xtr->fwd_policy->new_map_loc_policy_inf(xtr->fwd_policy_dev_parm,mapping,NULL); if (fwd_map_inf == NULL){ OOR_LOG(LERR, "Couldn't create forward information for mapping with EID: %s. Discarding it...", lisp_addr_to_char(mapping_eid(mapping))); map_local_entry_del(map_loc_e); continue; } map_local_entry_set_fwd_info(map_loc_e, fwd_map_inf, xtr->fwd_policy->del_map_loc_policy_inf); if (add_local_db_map_local_entry(map_loc_e,xtr) != GOOD){ map_local_entry_del(map_loc_e); continue; } } return (GOOD); }
int lisp_msg_parse_mapping_record_split(lbuf_t *b, lisp_addr_t *eid, glist_t *loc_list, locator_t **probed_) { void *mrec_hdr = NULL, *loc_hdr = NULL; locator_t *loc = NULL, *probed = NULL; int i = 0, len = 0; probed = NULL; mrec_hdr = lbuf_data(b); lbuf_pull(b, sizeof(mapping_record_hdr_t)); len = lisp_addr_parse(lbuf_data(b), eid); if (len <= 0) { return(BAD); } lbuf_pull(b, len); lisp_addr_set_plen(eid, MAP_REC_EID_PLEN(mrec_hdr)); OOR_LOG(LDBG_1, " %s eid: %s", mapping_record_hdr_to_char(mrec_hdr), lisp_addr_to_char(eid)); for (i = 0; i < MAP_REC_LOC_COUNT(mrec_hdr); i++) { loc_hdr = lbuf_data(b); loc = locator_new(); if (lisp_msg_parse_loc(b, loc) != GOOD) { return(BAD); } glist_add(loc, loc_list); if (LOC_PROBED(loc_hdr)) { if (probed != NULL) { OOR_LOG(LDBG_1, "Multiple probed locators! Probing only the first one: %s", lisp_addr_to_char(locator_addr(loc))); }else{ probed = loc; } } } if (probed_ != NULL) { *probed_ = probed; } return(GOOD); }
/* * Bind a socket to a specific address and port if specified * Afi is used when the src address is not specified */ int bind_socket(int sock, int afi, lisp_addr_t *src_addr, int src_port) { int result = TRUE; struct sockaddr *sock_addr; int sock_addr_len; struct sockaddr_in sock_addr_v4; struct sockaddr_in6 sock_addr_v6; switch(afi){ case AF_INET: memset ( ( char * ) &sock_addr_v4, 0, sizeof ( sock_addr_v4 ) ); sock_addr_v4.sin_family = AF_INET; if (src_port != 0){ sock_addr_v4.sin_port = htons(src_port); } if (src_addr != NULL){ sock_addr_v4.sin_addr.s_addr = ip_addr_get_v4(lisp_addr_ip(src_addr))->s_addr; }else{ sock_addr_v4.sin_addr.s_addr = INADDR_ANY; } sock_addr = ( struct sockaddr * ) &sock_addr_v4; sock_addr_len = sizeof ( struct sockaddr_in ); break; case AF_INET6: memset ( ( char * ) &sock_addr_v6, 0, sizeof ( sock_addr_v6 ) ); sock_addr_v6.sin6_family = AF_INET6; if (src_port != 0){ sock_addr_v6.sin6_port = htons(src_port); } if (src_addr != NULL){ memcpy(&(sock_addr_v6.sin6_addr),ip_addr_get_v6(lisp_addr_ip(src_addr)),sizeof(struct in6_addr)); }else{ sock_addr_v6.sin6_addr = in6addr_any; } sock_addr = ( struct sockaddr * ) &sock_addr_v6; sock_addr_len = sizeof ( struct sockaddr_in6 ); break; default: return (BAD); } if (bind(sock,sock_addr,sock_addr_len) != 0){ OOR_LOG(LDBG_1, "bind_socket: %s", strerror(errno)); result = BAD; }else{ OOR_LOG(LDBG_1, "bind_socket: Binded socket %d to source address %s and port %d with afi %d", sock, lisp_addr_to_char(src_addr),src_port, afi); } return (result); }
/* Process a LISP protocol message sitting on * socket s with address family afi */ int vpnapi_control_dp_recv_msg(sock_t *sl) { uconn_t uc; lbuf_t *b; oor_ctrl_t *ctrl; oor_ctrl_dev_t *dev; ctrl = sl->arg; /* Only one device supported for now */ dev = glist_first_data(ctrl->devices); uc.lp = LISP_CONTROL_PORT; b = lisp_msg_create_buf(); if (sock_ctrl_recv(sl->fd, b, &uc) != GOOD) { OOR_LOG(LDBG_1, "Couldn't retrieve socket information" "for control message! Discarding packet!"); lbuf_del(b); return (BAD); } if (lbuf_size(b) < 4){ OOR_LOG(LDBG_3, "Received a non LISP message in the " "control port! Discarding packet!"); return (BAD); } lbuf_reset_lisp(b); OOR_LOG(LDBG_1, "Received %s, IP: %s -> %s, UDP: %d -> %d", lisp_msg_hdr_to_char(b), lisp_addr_to_char(&uc.ra), lisp_addr_to_char(&uc.la), uc.rp, uc.lp); /* direct call of ctrl device * TODO: check type to decide where to send msg*/ ctrl_dev_recv(dev, b, &uc); lbuf_del(b); return (GOOD); }
map_local_entry_t * map_local_entry_new_init(mapping_t *map) { map_local_entry_t *mle; mle = xzalloc(sizeof(map_local_entry_t)); if (mle == NULL){ OOR_LOG(LDBG_1, "map_local_entry_new_init: Can't create local database mapping with EID prefix %s.", lisp_addr_to_char(mapping_eid(map))); return (NULL); } mle->mapping = map; return (mle); }
int vpnapi_output(lbuf_t *b) { packet_tuple_t tpl; if (pkt_parse_5_tuple(b, &tpl) != GOOD) { return (BAD); } LMLOG(LDBG_3,"OUTPUT: Received EID %s -> %s, Proto: %d, Port: %d -> %d ", lisp_addr_to_char(&tpl.src_addr), lisp_addr_to_char(&tpl.dst_addr), tpl.protocol, tpl.src_port, tpl.dst_port); /* If already LISP packet, do not encapsulate again */ if (is_lisp_packet(&tpl)) { LMLOG(LDBG_3,"OUTPUT: Is a lisp packet, do not encapsulate again"); return (vpnapi_forward_native(b, &tpl.dst_addr)); } vpnapi_output_unicast(b, &tpl); return(GOOD); }
char * pkt_tuple_to_char(packet_tuple_t *tpl) { static char buf[2][200]; static int i=0; /* hack to allow more than one locator per line */ i++; i = i % 2; *buf[i] = '\0'; if (tpl == NULL){ sprintf(buf[i], "_NULL_"); return (buf[i]); } sprintf(buf[i], "Src_addr: %s, ", lisp_addr_to_char(&tpl->src_addr)); sprintf(buf[i] + strlen(buf[i]), "Dst addr: %s, ", lisp_addr_to_char(&tpl->dst_addr)); sprintf(buf[i] + strlen(buf[i]), "Proto: "); switch (tpl->protocol){ case IPPROTO_UDP: sprintf(buf[i] + strlen(buf[i]), "UDP, "); break; case IPPROTO_TCP: sprintf(buf[i] + strlen(buf[i]), "TCP, "); break; case IPPROTO_ICMP: sprintf(buf[i] + strlen(buf[i]), "ICMP, "); break; default: sprintf(buf[i] + strlen(buf[i]), "%d, ",tpl->protocol); break; } sprintf(buf[i] + strlen(buf[i]), "Src Port: %d, ",tpl->src_port); sprintf(buf[i] + strlen(buf[i]), "Dst Port: %d\n",tpl->dst_port); sprintf(buf[i] + strlen(buf[i]), "IID|VNI: %d\n",tpl->iid); return (buf[i]); }
int lisp_msg_parse_itr_rlocs(lbuf_t *b, glist_t *rlocs) { lisp_addr_t *tloc; void *mreq_hdr = lbuf_lisp(b); int i; tloc = lisp_addr_new(); for (i = 0; i < MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1; i++) { if (lisp_msg_parse_addr(b, tloc) != GOOD) { return(BAD); } glist_add(lisp_addr_clone(tloc), rlocs); OOR_LOG(LDBG_1," itr-rloc: %s", lisp_addr_to_char(tloc)); } lisp_addr_del(tloc); return(GOOD); }
char * locator_to_char(locator_t *l) { static char buf[5][500]; static int i=0; if (l == NULL){ sprintf(buf[i], "_NULL_"); return (buf[i]); } /* hack to allow more than one locator per line */ i++; i = i % 5; *buf[i] = '\0'; sprintf(buf[i] + strlen(buf[i]), "%s, ", lisp_addr_to_char(locator_addr(l))); sprintf(buf[i] + strlen(buf[i]), "%s, ", l->state ? "Up" : "Down"); sprintf(buf[i] + strlen(buf[i]), "%d/%-d, %d/%d", l->priority, l->weight, l->mpriority, l->mweight); return (buf[i]); }
static void parse_elp_list(cfg_t *cfg, shash_t *ht) { elp_node_t *enode; elp_t *elp; lisp_addr_t *laddr; char *name; int i, j; for(i = 0; i < cfg_size(cfg, "explicit-locator-path"); i++) { cfg_t *selp = cfg_getnsec(cfg, "explicit-locator-path", i); name = cfg_getstr(selp, "elp-name"); elp = elp_type_new(); for (j = 0; j < cfg_size(selp, "elp-node");j++) { cfg_t *senode = cfg_getnsec(selp, "elp-node", j); enode = xzalloc(sizeof(elp_node_t)); enode->addr = lisp_addr_new(); if (lisp_addr_ip_from_char(cfg_getstr(senode, "address"), enode->addr) != GOOD) { elp_node_del(enode); OOR_LOG(LDBG_1, "parse_elp_list: Couldn't parse ELP node %s", cfg_getstr(senode, "address")); continue; } enode->L = cfg_getbool(senode, "lookup") ? 1 : 0; enode->P = cfg_getbool(senode, "probe") ? 1 : 0; enode->S = cfg_getbool(senode, "strict") ? 1: 0; glist_add_tail(enode, elp->nodes); } laddr = lisp_addr_new_lafi(LM_AFI_LCAF); lisp_addr_lcaf_set_type(laddr, LCAF_EXPL_LOC_PATH); lisp_addr_lcaf_set_addr(laddr, elp); OOR_LOG(LDBG_1, "Configuration file: parsed explicit-locator-path: %s", lisp_addr_to_char(laddr)); shash_insert(ht, strdup(name), laddr); } }
int lisp_msg_parse_loc(lbuf_t *b, locator_t *loc) { int len; void *hdr; hdr = lbuf_data(b); len = locator_parse(lbuf_data(b), loc); if (len <= 0) { return(BAD); } lbuf_pull(b, len); OOR_LOG(LDBG_1, " %s, addr: %s", locator_record_hdr_to_char(hdr), lisp_addr_to_char(locator_addr(loc))); return(GOOD); }
int vpnapi_control_dp_updated_route(oor_ctrl_t *ctrl, int command, iface_t *iface, lisp_addr_t *src_pref, lisp_addr_t *dst_pref, lisp_addr_t *gateway) { if (lisp_addr_ip_afi(gateway) != LM_AFI_NO_ADDR && lisp_addr_ip_afi(dst_pref) == LM_AFI_NO_ADDR) { /* Check if the addres is a global address*/ if (ip_addr_is_link_local(lisp_addr_ip(gateway)) == TRUE) { OOR_LOG(LDBG_3,"vpnapi_updated_route: the extractet address " "from the netlink messages is a local link address: %s " "discarded", lisp_addr_to_char(gateway)); return (GOOD); } vpnapi_control_dp_process_new_gateway(ctrl,iface,gateway); } return (GOOD); }
static void parse_rle_list(cfg_t *cfg, shash_t *ht) { rle_node_t *rnode; rle_t *rle; lisp_addr_t *laddr; char *name; int i, j; for (i = 0; i < cfg_size(cfg, "replication-list"); i++) { cfg_t *selp = cfg_getnsec(cfg, "replication-list", i); name = cfg_getstr(selp, "rle-name"); laddr = lisp_addr_new_lafi(LM_AFI_LCAF); lisp_addr_lcaf_set_type(laddr, LCAF_RLE); rle = rle_type_new(); for (j = 0; j < cfg_size(selp, "rle-node"); j++) { cfg_t *rlenode = cfg_getnsec(selp, "rle-node", j); rnode = rle_node_new(); if (lisp_addr_ip_from_char(cfg_getstr(rlenode, "address"), rnode->addr) != GOOD) { rle_node_del(rnode); OOR_LOG(LDBG_1, "parse_rle_list: Couldn't parse RLE node %s", cfg_getstr(rlenode, "address")); } rnode->level = cfg_getint(rlenode, "level"); glist_add_tail(rnode, rle->nodes); } lisp_addr_lcaf_set_addr(laddr, (void *)rle); OOR_LOG(LDBG_1, "Configuration file: parsed replication-list: %s", lisp_addr_to_char(laddr)); shash_insert(ht, strdup(name), laddr); } }
int configure_ms(cfg_t *cfg) { char *iface_name; iface_t *iface; lisp_site_prefix_t *site; shash_t *lcaf_ht; int i; lisp_ms_t *ms; mapping_t *mapping; /* create and configure xtr */ if (ctrl_dev_create(MS_MODE, &ctrl_dev) != GOOD) { OOR_LOG(LCRIT, "Failed to create MS. Aborting!"); exit_cleanup(); } ms = CONTAINER_OF(ctrl_dev, lisp_ms_t, super); /* create lcaf hash table */ lcaf_ht = parse_lcafs(cfg); /* CONTROL INTERFACE */ /* TODO: should work with all interfaces in the future */ iface_name = cfg_getstr(cfg, "control-iface"); if (iface_name) { iface = add_interface(iface_name); if (iface == NULL) { return(BAD); } } if (iface_address(iface, AF_INET) == NULL){ iface_setup_addr(iface, AF_INET); data_plane->datap_add_iface_addr(iface,AF_INET); lctrl->control_data_plane->control_dp_add_iface_addr(lctrl,iface,AF_INET); } if (iface_address(iface, AF_INET6) == NULL){ iface_setup_addr(iface, AF_INET6); data_plane->datap_add_iface_addr(iface,AF_INET6); lctrl->control_data_plane->control_dp_add_iface_addr(lctrl,iface,AF_INET6); } /* LISP-SITE CONFIG */ for (i = 0; i < cfg_size(cfg, "lisp-site"); i++) { cfg_t *ls = cfg_getnsec(cfg, "lisp-site", i); site = build_lisp_site_prefix(ms, cfg_getstr(ls, "eid-prefix"), cfg_getint(ls, "iid"), cfg_getint(ls, "key-type"), cfg_getstr(ls, "key"), cfg_getbool(ls, "accept-more-specifics") ? 1:0, cfg_getbool(ls, "proxy-reply") ? 1:0, cfg_getbool(ls, "merge") ? 1 : 0, lcaf_ht); if (site != NULL) { if (mdb_lookup_entry(ms->lisp_sites_db, site->eid_prefix) != NULL){ OOR_LOG(LDBG_1, "Configuration file: Duplicated lisp-site: %s . Discarding...", lisp_addr_to_char(site->eid_prefix)); lisp_site_prefix_del(site); continue; } OOR_LOG(LDBG_1, "Adding lisp site prefix %s to the lisp-sites " "database", lisp_addr_to_char(site->eid_prefix)); ms_add_lisp_site_prefix(ms, site); }else{ OOR_LOG(LERR, "Can't add lisp-site prefix %s. Discarded ...", cfg_getstr(ls, "eid-prefix")); } } /* LISP REGISTERED SITES CONFIG */ for (i = 0; i< cfg_size(cfg, "ms-static-registered-site"); i++ ) { cfg_t *mss = cfg_getnsec(cfg, "ms-static-registered-site", i); mapping = parse_mapping(mss,&(ms->super),lcaf_ht,FALSE); if (mapping == NULL){ OOR_LOG(LERR, "Can't create static register site for %s", cfg_getstr(mss, "eid-prefix")); continue; } /* If the mapping doesn't exist, add it the the database */ if (mdb_lookup_entry_exact(ms->reg_sites_db, mapping_eid(mapping)) == NULL){ if (ms_add_registered_site_prefix(ms, mapping) == GOOD){ OOR_LOG(LDBG_1, "Added static registered site for %s to the registered sites list!", lisp_addr_to_char(mapping_eid(mapping))); }else{ OOR_LOG(LERR, "Failed to add static registered site for %s to the registered sites list!", lisp_addr_to_char(mapping_eid(mapping))); mapping_del(mapping); } }else{ OOR_LOG(LERR, "Configuration file: Duplicated static registered site for %s. Discarded ...", cfg_getstr(mss, "eid-prefix")); mapping_del(mapping); continue; } } /* destroy the hash table */ shash_destroy(lcaf_ht); return(GOOD); }
int configure_rtr(cfg_t *cfg) { lisp_xtr_t *xtr; shash_t *lcaf_ht; mapping_t *mapping; map_local_entry_t *map_loc_e; void *fwd_map_inf; int n,i; /* CREATE AND CONFIGURE RTR (xTR in fact) */ if (ctrl_dev_create(RTR_MODE, &ctrl_dev) != GOOD) { OOR_LOG(LCRIT, "Failed to create RTR. Aborting!"); return (BAD); } lcaf_ht = parse_lcafs(cfg); xtr = CONTAINER_OF(ctrl_dev, lisp_xtr_t, super); if (configure_tunnel_router(cfg, xtr, lcaf_ht)!=GOOD){ return (BAD); } /* INTERFACES CONFIG */ n = cfg_size(cfg, "rtr-ifaces"); if (n) { cfg_t *rifs = cfg_getsec(cfg, "rtr-ifaces"); int nr = cfg_size(rifs, "rtr-iface"); for(i = 0; i < nr; i++) { cfg_t *ri = cfg_getnsec(rifs, "rtr-iface", i); if (add_rtr_iface(xtr, cfg_getstr(ri, "iface"), cfg_getint(ri, "ip_version"), cfg_getint(ri, "priority"), cfg_getint(ri, "weight")) == GOOD) { OOR_LOG(LDBG_1, "Configured interface %s for RTR", cfg_getstr(ri, "iface")); } else{ OOR_LOG(LERR, "Can't configure iface %s for RTR", cfg_getstr(ri, "iface")); } } } /* RTR DATABASE MAPPINGS (like for instance replication lists) */ n = cfg_size(cfg, "rtr-database-mapping"); for (i = 0; i < n; i++) { mapping = parse_mapping(cfg_getnsec(cfg, "rtr-database-mapping",i),&(xtr->super),lcaf_ht,TRUE); if (mapping == NULL){ continue; } map_loc_e = map_local_entry_new_init(mapping); if (map_loc_e == NULL){ mapping_del(mapping); continue; } fwd_map_inf = xtr->fwd_policy->new_map_loc_policy_inf(xtr->fwd_policy_dev_parm,mapping,NULL); if (fwd_map_inf == NULL){ OOR_LOG(LERR, "Couldn't create forward information for rtr database mapping with EID: %s. Discarding it...", lisp_addr_to_char(mapping_eid(mapping))); map_local_entry_del(map_loc_e); continue; } map_local_entry_set_fwd_info(map_loc_e, fwd_map_inf, xtr->fwd_policy->del_map_loc_policy_inf); if (add_local_db_map_local_entry(map_loc_e,xtr) != GOOD){ map_local_entry_del(map_loc_e); continue; } if (add_local_db_map_local_entry(map_loc_e,xtr) != GOOD){ map_local_entry_del(map_loc_e); } } /* Deallocate PiTRs and PeTRs elements */ glist_destroy(xtr->pitrs); xtr->pitrs = NULL; shash_destroy(lcaf_ht); return(GOOD); }
int configure_tunnel_router(cfg_t *cfg, lisp_xtr_t *xtr, shash_t *lcaf_ht) { int i,n,ret; char *map_resolver; char *encap; mapping_t *mapping; /* FWD POLICY STRUCTURES */ xtr->fwd_policy = fwd_policy_class_find("flow_balancing"); xtr->fwd_policy_dev_parm = xtr->fwd_policy->new_dev_policy_inf(ctrl_dev,NULL); if ((encap = cfg_getstr(cfg, "encapsulation")) != NULL) { if (strcmp(encap, "LISP") == 0) { xtr->encap_type = ENCP_LISP; }else if (strcmp(encap, "VXLAN-GPE") == 0){ xtr->encap_type = ENCP_VXLAN_GPE; }else{ OOR_LOG(LERR, "Unknown encapsulation type: %s",encap); return (BAD); } } /* RETRIES */ ret = cfg_getint(cfg, "map-request-retries"); xtr->map_request_retries = (ret != 0) ? ret : DEFAULT_MAP_REQUEST_RETRIES; /* RLOC PROBING CONFIG */ cfg_t *dm = cfg_getnsec(cfg, "rloc-probing", 0); if (dm != NULL) { xtr->probe_interval = cfg_getint(dm, "rloc-probe-interval"); xtr->probe_retries = cfg_getint(dm, "rloc-probe-retries"); xtr->probe_retries_interval = cfg_getint(dm, "rloc-probe-retries-interval"); validate_rloc_probing_parameters(&xtr->probe_interval, &xtr->probe_retries, &xtr->probe_retries_interval); } else { OOR_LOG(LDBG_1, "Configuration file: RLOC probing not defined. " "Setting default values: RLOC Probing Interval: %d sec.", RLOC_PROBING_INTERVAL); xtr->probe_interval = RLOC_PROBING_INTERVAL; xtr->probe_retries = DEFAULT_RLOC_PROBING_RETRIES; xtr->probe_retries_interval = DEFAULT_RLOC_PROBING_RETRIES_INTERVAL; } /* MAP-RESOLVER CONFIG */ n = cfg_size(cfg, "map-resolver"); for(i = 0; i < n; i++) { if ((map_resolver = cfg_getnstr(cfg, "map-resolver", i)) != NULL) { if (add_server(map_resolver, xtr->map_resolvers) == GOOD){ OOR_LOG(LDBG_1, "Added %s to map-resolver list", map_resolver); }else{ OOR_LOG(LCRIT,"Can't add %s Map Resolver.",map_resolver); } } } /* STATIC MAP-CACHE CONFIG */ n = cfg_size(cfg, "static-map-cache"); for (i = 0; i < n; i++) { cfg_t *smc = cfg_getnsec(cfg, "static-map-cache", i); mapping = parse_mapping(smc,&(xtr->super),lcaf_ht,FALSE); if (mapping == NULL){ OOR_LOG(LERR, "Can't add static Map Cache entry with EID prefix %s. Discarded ...", cfg_getstr(smc, "eid-prefix")); continue; } if (mcache_lookup_exact(xtr->map_cache, mapping_eid(mapping)) == NULL){ if (tr_mcache_add_static_mapping(xtr, mapping) == GOOD){ OOR_LOG(LDBG_1, "Added static Map Cache entry with EID prefix %s in the database.", lisp_addr_to_char(mapping_eid(mapping))); }else{ OOR_LOG(LERR, "Can't add static Map Cache entry with EID prefix %s. Discarded ...", mapping_eid(mapping)); mapping_del(mapping); } }else{ OOR_LOG(LERR, "Configuration file: Duplicated static Map Cache entry with EID prefix %s." "Discarded ...",cfg_getstr(smc, "eid-prefix")); mapping_del(mapping); continue; } continue; } return (GOOD); }
uint8_t * build_ip_udp_pcket(uint8_t *orig_pkt, int orig_pkt_len,lisp_addr_t *addr_from, lisp_addr_t *addr_dest, int port_from,int port_dest, int *encap_pkt_len) { uint8_t *encap_pkt; void *iph_ptr; struct udphdr *udph_ptr; int ip_hdr_len; int udp_hdr_len; int udp_hdr_and_payload_len; uint16_t udpsum; if (lisp_addr_ip_afi(addr_from) != lisp_addr_ip_afi(addr_dest)) { OOR_LOG(LDBG_2, "add_ip_udp_header: Different AFI addresses %d (%s) and %d (%s)", lisp_addr_ip_afi(addr_from), lisp_addr_to_char(addr_from), lisp_addr_ip_afi(addr_dest), lisp_addr_to_char(addr_dest)); return (NULL); } if ((lisp_addr_ip_afi(addr_from) != AF_INET) && (lisp_addr_ip_afi(addr_from) != AF_INET6)) { OOR_LOG(LDBG_2, "add_ip_udp_header: Unknown AFI %d", lisp_addr_ip_afi(addr_from)); return (NULL); } /* Headers lengths */ ip_hdr_len = ip_sock_afi_to_hdr_len(lisp_addr_ip_afi(addr_from)); udp_hdr_len = sizeof(struct udphdr); udp_hdr_and_payload_len = udp_hdr_len + orig_pkt_len; /* Assign memory for the original packet plus the new headers */ *encap_pkt_len = ip_hdr_len + udp_hdr_len + orig_pkt_len; if ((encap_pkt = (uint8_t *) malloc(*encap_pkt_len)) == NULL) { OOR_LOG(LDBG_2, "add_ip_udp_header: Couldn't allocate memory for the packet to be generated %s", strerror(errno)); return (NULL); } /* Make sure it's clean */ memset(encap_pkt, 0, *encap_pkt_len); /* IP header */ iph_ptr = encap_pkt; if ((udph_ptr = build_ip_header(iph_ptr, addr_from, addr_dest, udp_hdr_and_payload_len)) == NULL) { OOR_LOG(LDBG_2, "add_ip_udp_header: Couldn't build the inner ip header"); free(encap_pkt); return (NULL); } /* UDP header */ #ifdef BSD udph_ptr->uh_sport = htons(port_from); udph_ptr->uh_dport = htons(port_dest); udph_ptr->uh_ulen = htons(udp_payload_len); udph_ptr->uh_sum = 0; #else udph_ptr->source = htons(port_from); udph_ptr->dest = htons(port_dest); udph_ptr->len = htons(udp_hdr_and_payload_len); udph_ptr->check = 0; #endif /* Copy original packet after the headers */ memcpy(CO(udph_ptr, udp_hdr_len), orig_pkt, orig_pkt_len); /* * Now compute the headers checksums */ if ((udpsum = udp_checksum(udph_ptr, udp_hdr_and_payload_len, iph_ptr, lisp_addr_ip_afi(addr_from))) == -1) { free(encap_pkt); return (NULL); } udpsum(udph_ptr) = udpsum; return (encap_pkt); }