diff --git a/cps/kni.c b/cps/kni.c
index cc049c20..9da9cec6 100644
--- a/cps/kni.c
+++ b/cps/kni.c
@@ -16,22 +16,9 @@
* along with this program. If not, see .
*/
-#include
-#include
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include "gatekeeper_cps.h"
-#include "gatekeeper_lls.h"
+
#include "gatekeeper_main.h"
#include "kni.h"
@@ -443,205 +430,3 @@ kni_create(struct cps_kni *kni, const struct gatekeeper_if *iface,
out:
return ret;
}
-
-static void
-cps_arp_cb(const struct lls_map *map, void *arg,
- __attribute__((unused)) enum lls_reply_ty ty, int *pcall_again)
-{
- struct cps_config *cps_conf = get_cps_conf();
- struct cps_request *req;
- int ret;
-
- if (pcall_again != NULL)
- *pcall_again = false;
- else {
- /*
- * Destination didn't reply, so this callback
- * is the result of a call to put_arp().
- */
- return;
- }
- RTE_VERIFY(!map->stale);
-
- /*
- * If this allocation or queueing of an entry fails, the
- * resolution request will time out after two iterations
- * of the timer and be removed in cps_scan() anyway.
- */
-
- req = mb_alloc_entry(&cps_conf->mailbox);
- if (req == NULL) {
- G_LOG(ERR, "%s: allocation of mailbox message failed\n",
- __func__);
- return;
- }
-
- req->ty = CPS_REQ_ARP;
- req->u.arp.ip = map->addr.ip.v4.s_addr;
- rte_memcpy(&req->u.arp.ha, &map->ha, sizeof(req->u.arp.ha));
- req->u.arp.iface = arg;
-
- ret = mb_send_entry(&cps_conf->mailbox, req);
- if (ret < 0) {
- G_LOG(ERR, "%s: failed to enqueue message to mailbox\n",
- __func__);
- return;
- }
-}
-
-void
-kni_process_arp(struct cps_config *cps_conf, struct gatekeeper_if *iface,
- struct rte_mbuf *buf, const struct rte_ether_hdr *eth_hdr)
-{
- int ret;
- struct rte_arp_hdr *arp_hdr;
- uint16_t pkt_len = rte_pktmbuf_data_len(buf);
- struct arp_request *arp_req = NULL;
- struct arp_request *entry;
-
- if (unlikely(!arp_enabled(cps_conf->lls))) {
- G_LOG(NOTICE, "KNI for %s iface received ARP packet, but the interface is not configured for ARP\n",
- iface->name);
- goto out;
- }
-
- if (unlikely(pkt_len < sizeof(*eth_hdr) + sizeof(*arp_hdr))) {
- G_LOG(ERR, "KNI received ARP packet of size %hu bytes, but it should be at least %zu bytes\n",
- pkt_len, sizeof(*eth_hdr) + sizeof(*arp_hdr));
- goto out;
- }
-
- arp_hdr = rte_pktmbuf_mtod_offset(buf, struct rte_arp_hdr *,
- sizeof(*eth_hdr));
-
- /* If it's a Gratuitous ARP or reply, then no action is needed. */
- if (unlikely(rte_be_to_cpu_16(arp_hdr->arp_opcode) !=
- RTE_ARP_OP_REQUEST || is_garp_pkt(arp_hdr)))
- goto out;
-
- list_for_each_entry(entry, &cps_conf->arp_requests, list) {
- /* There's already a resolution request for this address. */
- if (arp_hdr->arp_data.arp_tip == entry->addr)
- goto out;
- }
-
- ret = rte_mempool_get(cps_conf->arp_mp, (void **)&arp_req);
- if (unlikely(ret < 0)) {
- G_LOG(ERR, "Failed to get a new entry from the ARP request mempool - %s\n",
- rte_strerror(-ret));
- goto out;
- }
-
- arp_req->addr = arp_hdr->arp_data.arp_tip;
- arp_req->stale = false;
- list_add_tail(&arp_req->list, &cps_conf->arp_requests);
-
- hold_arp(cps_arp_cb, iface,
- (struct in_addr *)&arp_hdr->arp_data.arp_tip,
- cps_conf->lcore_id);
-out:
- rte_pktmbuf_free(buf);
-}
-
-static void
-cps_nd_cb(const struct lls_map *map, void *arg,
- __attribute__((unused)) enum lls_reply_ty ty, int *pcall_again)
-{
- struct cps_config *cps_conf = get_cps_conf();
- struct cps_request *req;
- int ret;
-
- if (pcall_again != NULL)
- *pcall_again = false;
- else {
- /*
- * Destination didn't reply, so this callback
- * is the result of a call to put_nd().
- */
- return;
- }
- RTE_VERIFY(!map->stale);
-
- /*
- * If this allocation or queueing of an entry fails, the
- * resolution request will time out after two iterations
- * of the timer and be removed anyway.
- */
-
- req = mb_alloc_entry(&cps_conf->mailbox);
- if (req == NULL) {
- G_LOG(ERR, "%s: allocation of mailbox message failed\n",
- __func__);
- return;
- }
-
- req->ty = CPS_REQ_ND;
- rte_memcpy(req->u.nd.ip, map->addr.ip.v6.s6_addr,
- sizeof(req->u.nd.ip));
- rte_memcpy(&req->u.nd.ha, &map->ha, sizeof(req->u.nd.ha));
- req->u.nd.iface = arg;
-
- ret = mb_send_entry(&cps_conf->mailbox, req);
- if (ret < 0) {
- G_LOG(ERR, "%s: failed to enqueue message to mailbox\n",
- __func__);
- return;
- }
-}
-
-void
-kni_process_nd(struct cps_config *cps_conf, struct gatekeeper_if *iface,
- struct rte_mbuf *buf, const struct rte_ether_hdr *eth_hdr,
- uint16_t pkt_len)
-{
- int ret;
- struct icmpv6_hdr *icmpv6_hdr;
- struct nd_neigh_msg *nd_msg;
- struct nd_request *nd_req = NULL;
- struct nd_request *entry;
-
- if (unlikely(!nd_enabled(cps_conf->lls))) {
- G_LOG(NOTICE, "KNI for %s iface received ND packet, but the interface is not configured for ND\n",
- iface->name);
- goto out;
- }
-
- if (pkt_len < ND_NEIGH_PKT_MIN_LEN(sizeof(*eth_hdr))) {
- G_LOG(NOTICE, "ND packet received is %"PRIx16" bytes but should be at least %lu bytes\n",
- pkt_len, ND_NEIGH_PKT_MIN_LEN(sizeof(*eth_hdr)));
- goto out;
- }
-
- icmpv6_hdr = rte_pktmbuf_mtod_offset(buf, struct icmpv6_hdr *,
- sizeof(*eth_hdr) + sizeof(struct rte_ipv6_hdr));
- if (icmpv6_hdr->type == ND_NEIGHBOR_ADVERTISEMENT_TYPE &&
- icmpv6_hdr->code == ND_NEIGHBOR_ADVERTISEMENT_CODE) {
- G_LOG(NOTICE, "ND Advertisement packet received from KNI attached to %s iface\n",
- iface->name);
- goto out;
- }
-
- nd_msg = (struct nd_neigh_msg *)&icmpv6_hdr[1];
-
- list_for_each_entry(entry, &cps_conf->nd_requests, list) {
- /* There's already a resolution request for this address. */
- if (ipv6_addrs_equal(nd_msg->target, entry->addr))
- goto out;
- }
-
- ret = rte_mempool_get(cps_conf->nd_mp, (void **)&nd_req);
- if (unlikely(ret < 0)) {
- G_LOG(ERR, "Failed to get a new entry from the ND request mempool - %s\n",
- rte_strerror(-ret));
- goto out;
- }
-
- rte_memcpy(nd_req->addr, nd_msg->target, sizeof(nd_req->addr));
- nd_req->stale = false;
- list_add_tail(&nd_req->list, &cps_conf->nd_requests);
-
- hold_nd(cps_nd_cb, iface, (struct in6_addr *)nd_msg->target,
- cps_conf->lcore_id);
-out:
- rte_pktmbuf_free(buf);
-}
diff --git a/cps/kni.h b/cps/kni.h
index f65a0265..c3456230 100644
--- a/cps/kni.h
+++ b/cps/kni.h
@@ -53,22 +53,4 @@ kni_get_ifindex(const struct cps_kni *kni)
return kni->krn_ifindex;
}
-struct arp_request {
- struct list_head list;
- uint32_t addr;
- int stale;
-};
-
-struct nd_request {
- struct list_head list;
- uint8_t addr[16];
- int stale;
-};
-
-void kni_process_arp(struct cps_config *cps_conf, struct gatekeeper_if *iface,
- struct rte_mbuf *buf, const struct rte_ether_hdr *eth_hdr);
-void kni_process_nd(struct cps_config *cps_conf, struct gatekeeper_if *iface,
- struct rte_mbuf *buf, const struct rte_ether_hdr *eth_hdr,
- uint16_t pkt_len);
-
#endif /* _GATEKEEPER_CPS_KNI_H_ */
diff --git a/cps/main.c b/cps/main.c
index d966d2ee..57368b35 100644
--- a/cps/main.c
+++ b/cps/main.c
@@ -280,6 +280,18 @@ tx_to_kni(struct gatekeeper_if *iface, struct cps_kni *kni,
rte_pktmbuf_free_bulk(&pkts[num_tx], num_kni - num_tx);
}
+struct arp_request {
+ struct list_head list;
+ uint32_t addr;
+ int stale;
+};
+
+struct nd_request {
+ struct list_head list;
+ uint8_t addr[16];
+ int stale;
+};
+
static void
process_reqs(struct cps_config *cps_conf)
{
@@ -384,6 +396,208 @@ cps_pkt_is_nd_neighbor(struct gatekeeper_if *iface,
iface->ll_ip6_mc_addr.s6_addr));
}
+static void
+cps_arp_cb(const struct lls_map *map, void *arg,
+ __attribute__((unused)) enum lls_reply_ty ty, int *pcall_again)
+{
+ struct cps_config *cps_conf = get_cps_conf();
+ struct cps_request *req;
+ int ret;
+
+ if (pcall_again != NULL)
+ *pcall_again = false;
+ else {
+ /*
+ * Destination didn't reply, so this callback
+ * is the result of a call to put_arp().
+ */
+ return;
+ }
+ RTE_VERIFY(!map->stale);
+
+ /*
+ * If this allocation or queueing of an entry fails, the
+ * resolution request will time out after two iterations
+ * of the timer and be removed in cps_scan() anyway.
+ */
+
+ req = mb_alloc_entry(&cps_conf->mailbox);
+ if (req == NULL) {
+ G_LOG(ERR, "%s: allocation of mailbox message failed\n",
+ __func__);
+ return;
+ }
+
+ req->ty = CPS_REQ_ARP;
+ req->u.arp.ip = map->addr.ip.v4.s_addr;
+ rte_memcpy(&req->u.arp.ha, &map->ha, sizeof(req->u.arp.ha));
+ req->u.arp.iface = arg;
+
+ ret = mb_send_entry(&cps_conf->mailbox, req);
+ if (ret < 0) {
+ G_LOG(ERR, "%s: failed to enqueue message to mailbox\n",
+ __func__);
+ return;
+ }
+}
+
+static void
+process_arp(struct cps_config *cps_conf, struct gatekeeper_if *iface,
+ struct rte_mbuf *buf, const struct rte_ether_hdr *eth_hdr)
+{
+ int ret;
+ struct rte_arp_hdr *arp_hdr;
+ uint16_t pkt_len = rte_pktmbuf_data_len(buf);
+ struct arp_request *arp_req = NULL;
+ struct arp_request *entry;
+
+ if (unlikely(!arp_enabled(cps_conf->lls))) {
+ G_LOG(NOTICE, "KNI for %s iface received ARP packet, but the interface is not configured for ARP\n",
+ iface->name);
+ goto out;
+ }
+
+ if (unlikely(pkt_len < sizeof(*eth_hdr) + sizeof(*arp_hdr))) {
+ G_LOG(ERR, "KNI received ARP packet of size %hu bytes, but it should be at least %zu bytes\n",
+ pkt_len, sizeof(*eth_hdr) + sizeof(*arp_hdr));
+ goto out;
+ }
+
+ arp_hdr = rte_pktmbuf_mtod_offset(buf, struct rte_arp_hdr *,
+ sizeof(*eth_hdr));
+
+ /* If it's a Gratuitous ARP or reply, then no action is needed. */
+ if (unlikely(rte_be_to_cpu_16(arp_hdr->arp_opcode) !=
+ RTE_ARP_OP_REQUEST || is_garp_pkt(arp_hdr)))
+ goto out;
+
+ list_for_each_entry(entry, &cps_conf->arp_requests, list) {
+ /* There's already a resolution request for this address. */
+ if (arp_hdr->arp_data.arp_tip == entry->addr)
+ goto out;
+ }
+
+ ret = rte_mempool_get(cps_conf->arp_mp, (void **)&arp_req);
+ if (unlikely(ret < 0)) {
+ G_LOG(ERR, "Failed to get a new entry from the ARP request mempool - %s\n",
+ rte_strerror(-ret));
+ goto out;
+ }
+
+ arp_req->addr = arp_hdr->arp_data.arp_tip;
+ arp_req->stale = false;
+ list_add_tail(&arp_req->list, &cps_conf->arp_requests);
+
+ hold_arp(cps_arp_cb, iface,
+ (struct in_addr *)&arp_hdr->arp_data.arp_tip,
+ cps_conf->lcore_id);
+out:
+ rte_pktmbuf_free(buf);
+}
+
+static void
+cps_nd_cb(const struct lls_map *map, void *arg,
+ __attribute__((unused)) enum lls_reply_ty ty, int *pcall_again)
+{
+ struct cps_config *cps_conf = get_cps_conf();
+ struct cps_request *req;
+ int ret;
+
+ if (pcall_again != NULL)
+ *pcall_again = false;
+ else {
+ /*
+ * Destination didn't reply, so this callback
+ * is the result of a call to put_nd().
+ */
+ return;
+ }
+ RTE_VERIFY(!map->stale);
+
+ /*
+ * If this allocation or queueing of an entry fails, the
+ * resolution request will time out after two iterations
+ * of the timer and be removed anyway.
+ */
+
+ req = mb_alloc_entry(&cps_conf->mailbox);
+ if (req == NULL) {
+ G_LOG(ERR, "%s: allocation of mailbox message failed\n",
+ __func__);
+ return;
+ }
+
+ req->ty = CPS_REQ_ND;
+ rte_memcpy(req->u.nd.ip, map->addr.ip.v6.s6_addr,
+ sizeof(req->u.nd.ip));
+ rte_memcpy(&req->u.nd.ha, &map->ha, sizeof(req->u.nd.ha));
+ req->u.nd.iface = arg;
+
+ ret = mb_send_entry(&cps_conf->mailbox, req);
+ if (ret < 0) {
+ G_LOG(ERR, "%s: failed to enqueue message to mailbox\n",
+ __func__);
+ return;
+ }
+}
+
+static void
+process_nd(struct cps_config *cps_conf, struct gatekeeper_if *iface,
+ struct rte_mbuf *buf, const struct rte_ether_hdr *eth_hdr,
+ uint16_t pkt_len)
+{
+ int ret;
+ struct icmpv6_hdr *icmpv6_hdr;
+ struct nd_neigh_msg *nd_msg;
+ struct nd_request *nd_req = NULL;
+ struct nd_request *entry;
+
+ if (unlikely(!nd_enabled(cps_conf->lls))) {
+ G_LOG(NOTICE, "KNI for %s iface received ND packet, but the interface is not configured for ND\n",
+ iface->name);
+ goto out;
+ }
+
+ if (pkt_len < ND_NEIGH_PKT_MIN_LEN(sizeof(*eth_hdr))) {
+ G_LOG(NOTICE, "ND packet received is %"PRIx16" bytes but should be at least %lu bytes\n",
+ pkt_len, ND_NEIGH_PKT_MIN_LEN(sizeof(*eth_hdr)));
+ goto out;
+ }
+
+ icmpv6_hdr = rte_pktmbuf_mtod_offset(buf, struct icmpv6_hdr *,
+ sizeof(*eth_hdr) + sizeof(struct rte_ipv6_hdr));
+ if (icmpv6_hdr->type == ND_NEIGHBOR_ADVERTISEMENT_TYPE &&
+ icmpv6_hdr->code == ND_NEIGHBOR_ADVERTISEMENT_CODE) {
+ G_LOG(NOTICE, "ND Advertisement packet received from KNI attached to %s iface\n",
+ iface->name);
+ goto out;
+ }
+
+ nd_msg = (struct nd_neigh_msg *)&icmpv6_hdr[1];
+
+ list_for_each_entry(entry, &cps_conf->nd_requests, list) {
+ /* There's already a resolution request for this address. */
+ if (ipv6_addrs_equal(nd_msg->target, entry->addr))
+ goto out;
+ }
+
+ ret = rte_mempool_get(cps_conf->nd_mp, (void **)&nd_req);
+ if (unlikely(ret < 0)) {
+ G_LOG(ERR, "Failed to get a new entry from the ND request mempool - %s\n",
+ rte_strerror(-ret));
+ goto out;
+ }
+
+ rte_memcpy(nd_req->addr, nd_msg->target, sizeof(nd_req->addr));
+ nd_req->stale = false;
+ list_add_tail(&nd_req->list, &cps_conf->nd_requests);
+
+ hold_nd(cps_nd_cb, iface, (struct in6_addr *)nd_msg->target,
+ cps_conf->lcore_id);
+out:
+ rte_pktmbuf_free(buf);
+}
+
static void
process_egress(struct cps_config *cps_conf, struct gatekeeper_if *iface,
struct cps_kni *kni, uint16_t tx_queue, uint16_t cps_max_pkt_burst)
@@ -406,13 +620,13 @@ process_egress(struct cps_config *cps_conf, struct gatekeeper_if *iface,
switch (ether_type) {
case RTE_ETHER_TYPE_ARP:
/* Intercept ARP packet and handle it. */
- kni_process_arp(cps_conf, iface, bufs[i], eth_hdr);
+ process_arp(cps_conf, iface, bufs[i], eth_hdr);
break;
case RTE_ETHER_TYPE_IPV6: {
uint16_t pkt_len = rte_pktmbuf_data_len(bufs[i]);
if (cps_pkt_is_nd_neighbor(iface, eth_hdr, pkt_len)) {
/* Intercept ND packet and handle it. */
- kni_process_nd(cps_conf, iface,
+ process_nd(cps_conf, iface,
bufs[i], eth_hdr, pkt_len);
break;
}