Support packets in flight
[samplevnf.git] / VNFs / DPPD-PROX / arp.h
index 279bdad..ebf8a89 100644 (file)
 #define _ARP_H_
 
 #include <rte_ether.h>
+#include "prox_compat.h"
+#include "etypes.h"
+#include "mbuf_utils.h"
 
 #define ARP_REQUEST    0x100
 #define ARP_REPLY      0x200
 
 struct _arp_ipv4 {
-       struct ether_addr sha; /* Sender hardware address */
+       prox_rte_ether_addr sha; /* Sender hardware address */
        uint32_t spa;          /* Sender protocol address */
-       struct ether_addr tha; /* Target hardware address */
+       prox_rte_ether_addr tha; /* Target hardware address */
        uint32_t tpa;          /* Target protocol address */
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((__aligned__(2)));
 typedef struct _arp_ipv4 arp_ipv4_t;
 
 struct my_arp_t {
@@ -37,36 +40,79 @@ struct my_arp_t {
        uint8_t    plen;
        uint16_t   oper;
        arp_ipv4_t data;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((__aligned__(2)));
 
 struct ether_hdr_arp {
-       struct ether_hdr ether_hdr;
+       prox_rte_ether_hdr ether_hdr;
        struct my_arp_t arp;
 };
 
-static int arp_is_gratuitous(struct ether_hdr_arp *hdr)
+static int arp_is_gratuitous(struct my_arp_t *arp)
 {
-       return hdr->arp.data.spa == hdr->arp.data.tpa;
+       return arp->data.spa == arp->data.tpa;
 }
 
-static inline void prepare_arp_reply(struct ether_hdr_arp *hdr_arp, struct ether_addr *s_addr)
+// This build an arp reply based on a an request
+static inline void build_arp_reply(prox_rte_ether_hdr *ether_hdr, prox_rte_ether_addr *s_addr, struct my_arp_t *arp)
 {
-       uint32_t ip_source = hdr_arp->arp.data.spa;
+       uint32_t ip_source = arp->data.spa;
 
-       hdr_arp->arp.data.spa = hdr_arp->arp.data.tpa;
-       hdr_arp->arp.data.tpa = ip_source;
-       hdr_arp->arp.oper = 0x200;
-       memcpy(&hdr_arp->arp.data.tha, &hdr_arp->arp.data.sha, sizeof(struct ether_addr));
-       memcpy(&hdr_arp->arp.data.sha, s_addr, sizeof(struct ether_addr));
+       memcpy(ether_hdr->d_addr.addr_bytes, ether_hdr->s_addr.addr_bytes, sizeof(prox_rte_ether_addr));
+       memcpy(ether_hdr->s_addr.addr_bytes, s_addr, sizeof(prox_rte_ether_addr));
+
+       arp->data.spa = arp->data.tpa;
+       arp->data.tpa = ip_source;
+       arp->oper = 0x200;
+       memcpy(&arp->data.tha, &arp->data.sha, sizeof(prox_rte_ether_addr));
+       memcpy(&arp->data.sha, s_addr, sizeof(prox_rte_ether_addr));
+}
+
+static inline void build_arp_request(struct rte_mbuf *mbuf, prox_rte_ether_addr *src_mac, uint32_t ip_dst, uint32_t ip_src, uint16_t vlan)
+{
+       struct ether_hdr_arp *hdr_arp;
+       prox_rte_vlan_hdr *vlan_hdr;
+       prox_rte_ether_hdr *ether_hdr;
+       struct my_arp_t *arp;
+       uint64_t mac_bcast = 0xFFFFFFFFFFFF;
+       init_mbuf_seg(mbuf);
+
+       if (vlan) {
+               ether_hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
+               vlan_hdr = (prox_rte_vlan_hdr *)(ether_hdr + 1);
+               arp = (struct my_arp_t *)(vlan_hdr + 1);
+               ether_hdr->ether_type = ETYPE_VLAN;
+               vlan_hdr->eth_proto = ETYPE_ARP;
+               vlan_hdr->vlan_tci = rte_cpu_to_be_16(vlan);
+               rte_pktmbuf_pkt_len(mbuf) = 42 + sizeof(prox_rte_vlan_hdr);
+               rte_pktmbuf_data_len(mbuf) = 42 + sizeof(prox_rte_vlan_hdr);
+       } else {
+               ether_hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
+               arp = (struct my_arp_t *)(ether_hdr + 1);
+               ether_hdr->ether_type = ETYPE_ARP;
+               rte_pktmbuf_pkt_len(mbuf) = 42;
+               rte_pktmbuf_data_len(mbuf) = 42;
+       }
+
+       memcpy(&ether_hdr->d_addr.addr_bytes, &mac_bcast, 6);
+       memcpy(&ether_hdr->s_addr.addr_bytes, src_mac, 6);
+       arp->htype = 0x100,
+       arp->ptype = 0x0008;
+       arp->hlen = 6;
+       arp->plen = 4;
+       arp->oper = 0x100;
+       arp->data.spa = ip_src;
+       arp->data.tpa = ip_dst;
+       memset(&arp->data.tha, 0, sizeof(prox_rte_ether_addr));
+       memcpy(&arp->data.sha, src_mac, sizeof(prox_rte_ether_addr));
 }
 
-static void create_mac(struct ether_hdr_arp *hdr, struct ether_addr *addr)
+static void create_mac(struct my_arp_t *arp, prox_rte_ether_addr *addr)
 {
         addr->addr_bytes[0] = 0x2;
         addr->addr_bytes[1] = 0;
         // Instead of sending a completely random MAC address, create the following MAC:
         // 02:00:x1:x2:x3:x4 where x1:x2:x3:x4 is the IP address
-        memcpy(addr->addr_bytes + 2, (uint32_t *)&hdr->arp.data.tpa, 4);
+        memcpy(addr->addr_bytes + 2, (uint32_t *)&arp->data.tpa, 4);
 }
 
 #endif /* _ARP_H_ */