X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=VNFs%2FDPPD-PROX%2Fhandle_master.c;h=58240ba0485f0f1bf281cf6e3a60176010d0c5c8;hb=809edd5270e8a22f2c29d711203d579fdf7addfb;hp=3be55810c58a92b4609f07ed0d8e0a213463d9dc;hpb=91a44713bf414610246df57478b406a5561b725f;p=samplevnf.git diff --git a/VNFs/DPPD-PROX/handle_master.c b/VNFs/DPPD-PROX/handle_master.c index 3be55810..58240ba0 100644 --- a/VNFs/DPPD-PROX/handle_master.c +++ b/VNFs/DPPD-PROX/handle_master.c @@ -73,6 +73,8 @@ const char *actions_string[] = { }; +int (*handle_ctrl_plane)(struct task_base *tbase, struct rte_mbuf **mbuf, uint16_t n_pkts) = NULL; + static struct my_arp_t arp_reply = { .htype = 0x100, .ptype = 8, @@ -167,16 +169,17 @@ void master_init_vdev(struct task_base *tbase, uint8_t port_id, uint8_t core_id, struct sockaddr_in dst, src; src.sin_family = AF_INET; - src.sin_addr.s_addr = prox_port_cfg[vdev_port].ip; src.sin_port = rte_cpu_to_be_16(PROX_PSEUDO_PKT_PORT); - - int fd = socket(AF_INET, SOCK_DGRAM, 0); - PROX_PANIC(fd < 0, "Failed to open socket(AF_INET, SOCK_DGRAM, 0)\n"); - prox_port_cfg[vdev_port].fd = fd; - rc = bind(fd,(struct sockaddr *)&src, sizeof(struct sockaddr_in)); - PROX_PANIC(rc, "Failed to bind("IPv4_BYTES_FMT":%d): errno = %d (%s)\n", IPv4_BYTES(((uint8_t*)&src.sin_addr.s_addr)), src.sin_port, errno, strerror(errno)); - plog_info("DPDK port %d bound("IPv4_BYTES_FMT":%d) to fd %d\n", port_id, IPv4_BYTES(((uint8_t*)&src.sin_addr.s_addr)), src.sin_port, fd); - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); + for (int vlan_id = 0; vlan_id < prox_port_cfg[vdev_port].n_vlans; vlan_id++) { + src.sin_addr.s_addr = rte_be_to_cpu_32(prox_port_cfg[vdev_port].ip_addr[vlan_id].ip); + int fd = socket(AF_INET, SOCK_DGRAM, 0); + PROX_PANIC(fd < 0, "Failed to open socket(AF_INET, SOCK_DGRAM, 0)\n"); + prox_port_cfg[vdev_port].fds[vlan_id] = fd; + rc = bind(fd,(struct sockaddr *)&src, sizeof(struct sockaddr_in)); + PROX_PANIC(rc, "Failed to bind("IPv4_BYTES_FMT":%d): errno = %d (%s)\n", IPv4_BYTES(((uint8_t*)&src.sin_addr.s_addr)), src.sin_port, errno, strerror(errno)); + plog_info("DPDK port %d bound("IPv4_BYTES_FMT":%d) to fd %d\n", port_id, IPv4_BYTES(((uint8_t*)&src.sin_addr.s_addr)), src.sin_port, fd); + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); + } task->max_vdev_id++; } } @@ -258,7 +261,7 @@ static inline void handle_arp_request(struct task_base *tbase, struct rte_mbuf * plogx_dbg("\tMaster handling ARP request for ip "IPv4_BYTES_FMT" on port %d which supports random ip\n", IP4(key.ip), key.port); struct rte_ring *ring = task->internal_port_table[port].ring; create_mac(arp, &mac); - mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM); + mbuf->ol_flags &= ~(RTE_MBUF_F_TX_IP_CKSUM|RTE_MBUF_F_TX_UDP_CKSUM); build_arp_reply(ether_hdr, &mac, arp); tx_ring(tbase, ring, SEND_ARP_REPLY_FROM_MASTER, mbuf); return; @@ -273,7 +276,7 @@ static inline void handle_arp_request(struct task_base *tbase, struct rte_mbuf * tx_drop(mbuf); } else { struct rte_ring *ring = task->internal_ip_table[ret].ring; - mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM); + mbuf->ol_flags &= ~(RTE_MBUF_F_TX_IP_CKSUM|RTE_MBUF_F_TX_UDP_CKSUM); build_arp_reply(ether_hdr, &task->internal_ip_table[ret].mac, arp); tx_ring(tbase, ring, SEND_ARP_REPLY_FROM_MASTER, mbuf); } @@ -338,7 +341,7 @@ static inline void handle_unknown_ip(struct task_base *tbase, struct rte_mbuf *m return; } // We send an ARP request even if one was just sent (and not yet answered) by another task - mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM); + mbuf->ol_flags &= ~(RTE_MBUF_F_TX_IP_CKSUM|RTE_MBUF_F_TX_UDP_CKSUM); build_arp_request(mbuf, &task->internal_port_table[port].mac, ip_dst, ip_src, vlan); tx_ring(tbase, ring, SEND_ARP_REQUEST_FROM_MASTER, mbuf); } @@ -367,7 +370,7 @@ static inline void build_icmp_reply_message(struct task_base *tbase, struct rte_ tx_drop(mbuf); } else { struct rte_ring *ring = task->internal_ip_table[ret].ring; - mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM); + mbuf->ol_flags &= ~(RTE_MBUF_F_TX_IP_CKSUM|RTE_MBUF_F_TX_UDP_CKSUM); tx_ring(tbase, ring, SEND_ICMP_FROM_MASTER, mbuf); } } @@ -375,7 +378,7 @@ static inline void build_icmp_reply_message(struct task_base *tbase, struct rte_ static inline void handle_icmp(struct task_base *tbase, struct rte_mbuf *mbuf) { struct task_master *task = (struct task_master *)tbase; - uint8_t port_id = mbuf->port; + uint8_t port_id = get_port(mbuf); struct port_table *port = &task->internal_port_table[port_id]; prox_rte_ether_hdr *hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); if (hdr->ether_type != ETYPE_IPv4) { @@ -401,7 +404,7 @@ static inline void handle_icmp(struct task_base *tbase, struct rte_mbuf *mbuf) port->n_echo_req = 0; port->last_echo_req_rcvd_tsc = rte_rdtsc(); } - build_icmp_reply_message(tbase, mbuf); + return build_icmp_reply_message(tbase, mbuf); } else if (type == PROX_RTE_IP_ICMP_ECHO_REPLY) { port->n_echo_rep++; if (rte_rdtsc() - port->last_echo_rep_rcvd_tsc > rte_get_tsc_hz()) { @@ -418,21 +421,21 @@ static inline void handle_unknown_ip6(struct task_base *tbase, struct rte_mbuf * { struct task_master *task = (struct task_master *)tbase; struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); - uint8_t port = get_port(mbuf); + uint8_t port_id = get_port(mbuf); struct ipv6_addr *ip_dst = ctrl_ring_get_ipv6_addr(mbuf); uint16_t vlan = ctrl_ring_get_vlan(mbuf); int ret1, ret2, i; - plogx_dbg("\tMaster trying to find MAC of external IP "IPv6_BYTES_FMT" for port %d\n", IPv6_BYTES(ip_dst->bytes), port); - if (unlikely(port >= PROX_MAX_PORTS)) { - plogx_dbg("Port %d not found", port); + plogx_dbg("\tMaster trying to find MAC of external IP "IPv6_BYTES_FMT" for port %d\n", IPv6_BYTES(ip_dst->bytes), port_id); + if (unlikely(port_id >= PROX_MAX_PORTS)) { + plogx_dbg("Port %d not found", port_id); tx_drop(mbuf); return; } - struct ipv6_addr *local_ip_src = &task->internal_port_table[port].local_ipv6_addr; - struct ipv6_addr *global_ip_src = &task->internal_port_table[port].global_ipv6_addr; + struct ipv6_addr *local_ip_src = &task->internal_port_table[port_id].local_ipv6_addr; + struct ipv6_addr *global_ip_src = &task->internal_port_table[port_id].global_ipv6_addr; struct ipv6_addr *ip_src; - if (memcmp(local_ip_src, ip_dst, 8) == 0) + if (memcmp(local_ip_src, ip_dst, prox_port_cfg[port_id].v6_mask_length) == 0) ip_src = local_ip_src; else if (memcmp(global_ip_src, &null_addr, 16)) ip_src = global_ip_src; @@ -444,7 +447,7 @@ static inline void handle_unknown_ip6(struct task_base *tbase, struct rte_mbuf * struct rte_ring *ring = task->ctrl_tx_rings[get_core(mbuf) * MAX_TASKS_PER_CORE + get_task(mbuf)]; if (ring == NULL) { - plogx_dbg("Port %d not registered", port); + plogx_dbg("Port %d not registered", port_id); tx_drop(mbuf); return; } @@ -475,12 +478,12 @@ static inline void handle_unknown_ip6(struct task_base *tbase, struct rte_mbuf * task->external_ip6_table[ret2].nb_requests++; // Only needed for first request - but avoid test and copy the same 6 bytes // In most cases we will only have one request per IP. - //memcpy(&task->external_ip6_table[ret2].mac, &task->internal_port_table[port].mac, sizeof(prox_rte_ether_addr)); + //memcpy(&task->external_ip6_table[ret2].mac, &task->internal_port_table[port_id].mac, sizeof(prox_rte_ether_addr)); } // As timers are not handled by master, we might send an NS request even if one was just sent // (and not yet answered) by another task - build_neighbour_sollicitation(mbuf, &task->internal_port_table[port].mac, ip_dst, ip_src, vlan); + build_neighbour_sollicitation(mbuf, &task->internal_port_table[port_id].mac, ip_dst, ip_src, vlan); tx_ring(tbase, ring, SEND_NDP_FROM_MASTER, mbuf); } @@ -624,6 +627,7 @@ static inline void handle_ns(struct task_base *tbase, struct rte_mbuf *mbuf, pro tx_drop(mbuf); } else { struct rte_ring *ring = task->internal_ip6_table[ret].ring; + if (ring == NULL) return; build_neighbour_advertisement(tbase, mbuf, &task->internal_ip6_table[ret].mac, &key.ip6, PROX_SOLLICITED, vlan); tx_ring(tbase, ring, SEND_NDP_FROM_MASTER, mbuf); } @@ -674,7 +678,7 @@ static inline void handle_na(struct task_base *tbase, struct rte_mbuf *mbuf, pro } if (target_address == NULL) { - tx_drop(mbuf); + target_address = (uint8_t *)&neighbour_advertisement->destination_address; } struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); struct ipv6_addr *key = &neighbour_advertisement->destination_address; @@ -682,6 +686,7 @@ static inline void handle_na(struct task_base *tbase, struct rte_mbuf *mbuf, pro ret = rte_hash_lookup(task->external_ip6_hash, (const void *)key); if (unlikely(ret < 0)) { // entry not found for this IP: we did not ask a request, delete the reply + plog_err("Unkown IP "IPv6_BYTES_FMT"", IPv6_BYTES(neighbour_advertisement->destination_address.bytes)); tx_drop(mbuf); } else { // entry found for this IP @@ -696,6 +701,7 @@ static inline void handle_na(struct task_base *tbase, struct rte_mbuf *mbuf, pro } task->external_ip6_table[ret].nb_requests = 0; } else { + plog_err("UNEXPECTED nb_requests == 0"); tx_drop(mbuf); } } @@ -783,6 +789,7 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); uint32_t ip = get_ip(mbuf); + vlan = ctrl_ring_get_vlan(mbuf); struct rte_ring *ring = task->ctrl_tx_rings[get_core(mbuf) * MAX_TASKS_PER_CORE + get_task(mbuf)]; // First check whether MAC address is not already in kernel MAC table. @@ -803,12 +810,23 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf dst.sin_family = AF_INET; dst.sin_addr.s_addr = ip; dst.sin_port = rte_cpu_to_be_16(PROX_PSEUDO_PKT_PORT); - // TODO VLAN: find the right fd based on the VLAN - int n = sendto(prox_port_cfg[vdev_port].fd, (char*)(&ip), 0, MSG_DONTROUTE, (struct sockaddr *)&dst, sizeof(struct sockaddr_in)); + + int vlan_id; + for (vlan_id = 0; vlan_id < prox_port_cfg[vdev_port].n_vlans; vlan_id++) { + if (prox_port_cfg[vdev_port].vlan_tags[vlan_id] == vlan) + break; + } + if (vlan_id >= prox_port_cfg[vdev_port].n_vlans) { + // Tag not found + plogx_info("\tDid not send to TAP IP "IPv4_BYTES_FMT" as wrong VLAN %d\n", IPv4_BYTES(((uint8_t*)&ip)), vlan); + tx_drop(mbuf); + break; + } + int n = sendto(prox_port_cfg[vdev_port].fds[vlan_id], (char*)(&ip), 0, MSG_DONTROUTE, (struct sockaddr *)&dst, sizeof(struct sockaddr_in)); if (n < 0) { - plogx_info("\tFailed to send to TAP IP "IPv4_BYTES_FMT" using fd %d, error = %d (%s)\n", IPv4_BYTES(((uint8_t*)&ip)), prox_port_cfg[vdev_port].fd, errno, strerror(errno)); + plogx_info("\tFailed to send to TAP IP "IPv4_BYTES_FMT" using fd %d, error = %d (%s)\n", IPv4_BYTES(((uint8_t*)&ip)), prox_port_cfg[vdev_port].fds[vlan_id], errno, strerror(errno)); } else - plogx_dbg("\tSent %d bytes to TAP IP "IPv4_BYTES_FMT" using fd %d\n", n, IPv4_BYTES(((uint8_t*)&ip)), prox_port_cfg[vdev_port].fd); + plogx_dbg("\tSent %d bytes to TAP IP "IPv4_BYTES_FMT" using fd %d\n", n, IPv4_BYTES(((uint8_t*)&ip)), prox_port_cfg[vdev_port].fds[vlan_id]); record_request(tbase, ip, port, ring); tx_drop(mbuf); @@ -891,6 +909,7 @@ void init_ctrl_plane(struct task_base *tbase) .entries = n_entries, .hash_func = rte_hash_crc, .hash_func_init_val = 0, + .socket_id = socket_id, }; if (prox_cfg.flags & DSF_L3_ENABLED) { hash_params.key_len = sizeof(uint32_t); @@ -956,7 +975,7 @@ void init_ctrl_plane(struct task_base *tbase) struct sockaddr_nl sockaddr2; memset(&sockaddr2, 0, sizeof(struct sockaddr_nl)); sockaddr2.nl_family = AF_NETLINK; - sockaddr2.nl_groups = RTMGRP_IPV6_ROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_NOTIFY; + sockaddr2.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_NOTIFY; rc = bind(fd, (struct sockaddr *)&sockaddr2, sizeof(struct sockaddr_nl)); PROX_PANIC(rc < 0, "Failed to bind to RTMGRP_NEIGH netlink group\n"); task->route_fds.fd = fd; @@ -999,7 +1018,11 @@ static void handle_route_event(struct task_base *tbase) struct rtmsg *rtmsg = (struct rtmsg *)NLMSG_DATA(nl_hdr); int rtm_family = rtmsg->rtm_family; - if ((rtm_family == AF_INET) && (rtmsg->rtm_table != RT_TABLE_MAIN) &&(rtmsg->rtm_table != RT_TABLE_LOCAL)) + if (rtm_family != AF_INET) { + plog_warn("Unhandled non IPV4 routing message\n"); + return; + } + if ((rtmsg->rtm_table != RT_TABLE_MAIN) && (rtmsg->rtm_table != RT_TABLE_LOCAL)) return; int dst_len = rtmsg->rtm_dst_len; @@ -1028,8 +1051,14 @@ static void handle_route_event(struct task_base *tbase) } int dpdk_vdev_port = -1; for (int i = 0; i< prox_rte_eth_dev_count_avail(); i++) { - if (strcmp(prox_port_cfg[i].name, interface_name) == 0) - dpdk_vdev_port = i; + for (int vlan_id = 0; vlan_id < prox_port_cfg[i].n_vlans; vlan_id++) { + if (strcmp(prox_port_cfg[i].names[vlan_id], interface_name) == 0) { + dpdk_vdev_port = i; + break; + } + } + if (dpdk_vdev_port != -1) + break; } if (dpdk_vdev_port != -1) { plogx_info("Received netlink message on tap interface %s for IP "IPv4_BYTES_FMT"/%d, Gateway "IPv4_BYTES_FMT"\n", interface_name, IP4(ip), dst_len, IP4(gw_ip));