Example #1
0
File: prefixes.c Project: biels/oor
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);
}
Example #2
0
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));
}
Example #3
0
File: lisp_ms.c Project: biels/oor
static locator_t *
get_locator_with_afi(mapping_t *m, int afi)
{
	glist_t *loct_list = NULL;
	glist_entry_t *it_list = NULL;
	glist_entry_t *it_loct = NULL;
    locator_t *loct = NULL;
    lisp_addr_t *addr = NULL;
    int lafi = 0;
    int afi_type = 0;

    glist_for_each_entry(it_list,mapping_locators_lists(m)){
    	loct_list = (glist_t *)glist_entry_data(it_list);
    	locator_list_lafi_type(loct_list,&lafi,&afi_type);
    	if (lafi == LM_AFI_NO_ADDR || (lafi == LM_AFI_IP && afi_type != afi)){
    		continue;
    	}
    	glist_for_each_entry(it_loct,loct_list){
    		loct = (locator_t *)glist_entry_data(it_loct);
    		if (locator_state(loct) == DOWN){
    			continue;
    		}
    		addr = locator_addr(loct);
    		addr = lisp_addr_get_ip_addr(addr);
    		if (lisp_addr_ip_afi (addr) == afi){
    			return (loct);
    		}
    	}
Example #4
0
/*
 * Get lafi and type of a list
 */
void locator_list_lafi_type (
		glist_t         *loct_list,
		int				*lafi,
		int				*type)
{
	locator_t *loct = NULL;
	lisp_addr_t *addr = NULL;

	*lafi = 0;
	*type = 0;
	if (loct_list == NULL || glist_size(loct_list) == 0){
		return;
	}

    loct = (locator_t *)glist_first_data(loct_list);
    addr = locator_addr(loct);
    *lafi = lisp_addr_lafi(addr);
    switch(*lafi){
    case LM_AFI_NO_ADDR:
    	*type = 0;
    	return;
    case LM_AFI_IP:
    	*type = lisp_addr_ip_afi(addr);
    	return;
    case LM_AFI_IPPREF:
    	LMLOG(LDBG_2, "locator_list_lafi_type: locator list should not contain prefixes");
    	return;
    case LM_AFI_LCAF:
    	*type = lisp_addr_lcaf_type(addr);
    	return;
    }


}
Example #5
0
int
vpnapi_control_dp_updated_addr(oor_ctrl_t *ctrl, iface_t *iface,
        lisp_addr_t *old_addr,lisp_addr_t *new_addr)
{
    int addr_afi;
    vpnapi_ctr_dplane_data_t * data;

    data = (vpnapi_ctr_dplane_data_t *)ctrl->control_data_plane->control_dp_data;
    addr_afi = lisp_addr_ip_afi(new_addr);

    /* Check if the detected change of address id the same. */
    if (lisp_addr_cmp(old_addr, new_addr) == 0) {
        OOR_LOG(LDBG_2, "vpnapi_control_dp_updated_addr: The change of address detected "
                "for interface %s doesn't affect", iface->iface_name);
        return (GOOD);
    };

    switch (addr_afi){
    case AF_INET:
        vpnapi_control_dp_reset_socket(data, data->ipv4_ctrl_socket, AF_INET);
        break;
    case AF_INET6:
        vpnapi_control_dp_reset_socket(data, data->ipv6_ctrl_socket, AF_INET6);
        break;
    default:
        return (BAD);
    }

    return (GOOD);
}
Example #6
0
struct udphdr *
build_ip_header(uint8_t *cur_ptr, lisp_addr_t *src_addr, lisp_addr_t *dst_addr,
        int ip_len)
{
    struct ip *iph;
    struct ip6_hdr *ip6h;
    struct udphdr *udph;

    switch (lisp_addr_ip_afi(src_addr)) {
    case AF_INET:
        ip_len = ip_len + sizeof(struct ip);
        iph = (struct ip *) cur_ptr;
        iph->ip_hl = 5;
        iph->ip_v = IPVERSION;
        iph->ip_tos = 0;
        iph->ip_len = htons(ip_len);
        iph->ip_id = htons(get_IP_ID());
        iph->ip_off = 0; /* XXX Control packets can be fragmented  */
        iph->ip_ttl = 255;
        iph->ip_p = IPPROTO_UDP;
        iph->ip_src.s_addr = ip_addr_get_v4(lisp_addr_ip(src_addr))->s_addr;
        iph->ip_dst.s_addr = ip_addr_get_v4(lisp_addr_ip(dst_addr))->s_addr;
        iph->ip_sum = 0;
        iph->ip_sum = ip_checksum((uint16_t *) cur_ptr, sizeof(struct ip));

        udph = (struct udphdr *) CO(iph, sizeof(struct ip));
        break;
    case AF_INET6:
        ip6h = (struct ip6_hdr *) cur_ptr;
        ip6h->ip6_hops = 255;
        ip6h->ip6_vfc = (IP6VERSION << 4);
        ip6h->ip6_nxt = IPPROTO_UDP;
        ip6h->ip6_plen = htons(ip_len);
        memcpy(ip6h->ip6_src.s6_addr,ip_addr_get_v6(lisp_addr_ip(src_addr)),
                sizeof(struct in6_addr));
        memcpy(ip6h->ip6_dst.s6_addr,ip_addr_get_v6(lisp_addr_ip(dst_addr)),
                sizeof(struct in6_addr));
        udph = (struct udphdr *) CO(ip6h, sizeof(struct ip6_hdr));
        break;
    default:
        OOR_LOG(LDBG_2,
                "build_ip_header: Uknown AFI of the source address: %d",
                lisp_addr_ip_afi(src_addr));
        return (NULL);
    }
    return (udph);
}
Example #7
0
File: prefixes.c Project: biels/oor
/*
 * If prefix b is contained in prefix a, then return TRUE. Otherwise return FALSE.
 * If both prefixs are the same it also returns TRUE
 */
int
pref_is_prefix_b_part_of_a (lisp_addr_t *a_prefix,lisp_addr_t *b_prefix)
{
    lisp_addr_t * a_network_addr;
    lisp_addr_t * b_network_addr_prefix_a;
    int a_pref_len;
    int b_pref_len;
    int res;


    if (!lisp_addr_is_ip_pref(a_prefix) || !lisp_addr_is_ip_pref(b_prefix)){
        return FALSE;
    }

    if (lisp_addr_ip_afi(a_prefix) != lisp_addr_ip_afi(b_prefix)){
        return FALSE;
    }

    a_pref_len = lisp_addr_get_plen(a_prefix);
    b_pref_len = lisp_addr_get_plen(b_prefix);

    if (a_pref_len > b_pref_len){
        return FALSE;
    }

    a_network_addr = pref_get_network_address(a_prefix);

    lisp_addr_set_plen(b_prefix, a_pref_len);

    b_network_addr_prefix_a = pref_get_network_address(b_prefix);

    lisp_addr_set_plen(b_prefix, b_pref_len);

    if (lisp_addr_cmp (a_network_addr, b_network_addr_prefix_a) == 0){
        res = TRUE;
    }else{
        res = FALSE;
    }
    lisp_addr_del(a_network_addr);
    lisp_addr_del(b_network_addr_prefix_a);

    return (res);
}
Example #8
0
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);
}
Example #9
0
int
send_datagram_packet (int sock, const void *packet, int packet_length,
        lisp_addr_t *addr_dest, int port_dest)
{
    struct sockaddr_in sock_addr_v4;
    struct sockaddr_in6 sock_addr_v6;
    struct sockaddr *sock_addr = NULL;
    int sock_addr_len = 0;

    switch (lisp_addr_ip_afi(addr_dest)){
    case AF_INET:
        memset(&sock_addr_v4,0,sizeof(sock_addr_v4));           /* be sure */
        sock_addr_v4.sin_port        = htons(port_dest);
        sock_addr_v4.sin_family      = AF_INET;
        sock_addr_v4.sin_addr.s_addr = ip_addr_get_v4(lisp_addr_ip(addr_dest))->s_addr;
        sock_addr = (struct sockaddr *) &sock_addr_v4;
        sock_addr_len = sizeof(sock_addr_v4);
        break;
    case AF_INET6:
        memset(&sock_addr_v6,0,sizeof(sock_addr_v6));                   /* be sure */
        sock_addr_v6.sin6_family   = AF_INET6;
        sock_addr_v6.sin6_port     = htons(port_dest);
        memcpy(&sock_addr_v6.sin6_addr, ip_addr_get_v6(lisp_addr_ip(addr_dest)),sizeof(struct in6_addr));
        sock_addr = (struct sockaddr *) &sock_addr_v6;
        sock_addr_len = sizeof(sock_addr_v6);
        break;
    default:
        OOR_LOG(LDBG_2, "send_datagram_packet: Unknown afi %d",lisp_addr_ip_afi(addr_dest));
        return (BAD);
    }

    if (sendto(sock, packet, packet_length, 0, sock_addr, sock_addr_len) < 0){
        OOR_LOG(LDBG_2, "send_datagram_packet: send failed %s.",strerror ( errno ));
        return (BAD);
    }
    return (GOOD);
}
Example #10
0
/* Calculate the hash of the 5 tuples of a packet */
uint32_t
pkt_tuple_hash(packet_tuple_t *tuple)
{
    int hash = 0;
    int len = 0;
    int port = tuple->src_port;
    uint32_t *tuples = NULL;

    port = port + ((int)tuple->dst_port << 16);
    switch (lisp_addr_ip_afi(&tuple->src_addr)){
    case AF_INET:
        /* 1 integer src_addr
         * + 1 integer dst_adr
         * + 1 integer (ports)
         * + 1 integer protocol
         * + 1 iid*/
        len = 5;
        tuples = xmalloc(len * sizeof(uint32_t));
        lisp_addr_copy_to(&tuples[0], &tuple->src_addr);
        lisp_addr_copy_to(&tuples[1], &tuple->dst_addr);
        tuples[2] = port;
        tuples[3] = tuple->protocol;
        tuples[4] = tuple->iid;
        break;
    case AF_INET6:
        /* 4 integer src_addr
         * + 4 integer dst_adr
         * + 1 integer (ports)
         * + 1 integer protocol
         * + 1 iid */
        len = 11;
        tuples = xmalloc(len * sizeof(uint32_t));
        lisp_addr_copy_to(&tuples[0], &tuple->src_addr);
        lisp_addr_copy_to(&tuples[4], &tuple->dst_addr);
        tuples[8] = port;
        tuples[9] = tuple->protocol;
        tuples[10] = tuple->iid;
        break;
    }

    /* XXX: why 2013 used as initial value? */
    hash = hashword(tuples, len, 2013);
    free(tuples);
    return (hash);

}
Example #11
0
void
vpnapi_control_dp_process_new_gateway(oor_ctrl_t *ctrl, iface_t *iface,
        lisp_addr_t *gateway)
{
    int afi;
    vpnapi_ctr_dplane_data_t * data;

    afi = lisp_addr_ip_afi(gateway);
    data = (vpnapi_ctr_dplane_data_t *)ctrl->control_data_plane->control_dp_data;

    /* Recreate sockets */
    switch(afi){
    case AF_INET:
        vpnapi_control_dp_reset_socket(data, data->ipv4_ctrl_socket,AF_INET);
        break;
    case AF_INET6:
        vpnapi_control_dp_reset_socket(data, data->ipv6_ctrl_socket,AF_INET6);
        break;
    default:
        return;
    }
}
Example #12
0
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);

}