src.sin_family = AF_INET;
src.sin_port = rte_cpu_to_be_16(PROX_PSEUDO_PKT_PORT);
for (int vlan_id = 0; vlan_id < prox_port_cfg[vdev_port].n_vlans; vlan_id++) {
- src.sin_addr.s_addr = prox_port_cfg[vdev_port].ip_addr[vlan_id].ip;
+ 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;
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) {
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()) {
{
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;
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;
}
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);
}
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);
}
}
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;
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
}
task->external_ip6_table[ret].nb_requests = 0;
} else {
+ plog_err("UNEXPECTED nb_requests == 0");
tx_drop(mbuf);
}
}
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;
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;