diff --git a/worker/SCRIPT_PC 1.sh b/worker/SCRIPT_PC 1.sh new file mode 100644 index 0000000..7753bed --- /dev/null +++ b/worker/SCRIPT_PC 1.sh @@ -0,0 +1,7 @@ +INTERFACE="eth0" + +sudo ip link set $INTERFACE up +sudo ip addr add 10.0.0.2/24 dev $INTERFACE +sudo ip route add default via $GATEWAY dev $INTERFACE + +sudo ip route add 10.0.0.0/24 via 10.0.1.1 dev $INTERFACE diff --git a/worker/SCRIPT_PC 2.sh b/worker/SCRIPT_PC 2.sh new file mode 100644 index 0000000..cd72255 --- /dev/null +++ b/worker/SCRIPT_PC 2.sh @@ -0,0 +1,6 @@ +INTERFACE="enp3s0" + +sudo ip addr add 10.0.1.2/24 dev $INTERFACE +sudo ip link set dev $INTERFACE up +sudo ip route add 10.0.1.0/24 via 10.0.1.1 dev $INTERFACE +sudo ip addr set dev $INTERFACE up \ No newline at end of file diff --git a/worker/SCRIPT_PLATA_IP.sh b/worker/SCRIPT_PLATA_IP.sh new file mode 100644 index 0000000..808934c --- /dev/null +++ b/worker/SCRIPT_PLATA_IP.sh @@ -0,0 +1,7 @@ +ip link set eth0 up +ip link set eth1 up + +ip addr add 10.0.0.1/24 dev eth0 #подключен к ПК 1 +ip addr add 10.0.0.2/24 dev eth1 #подключен к ПК 2 + +sysctl -w net.ipv4.ip_forward=1 diff --git a/worker/SCRIPT_PLATA_OFFLOAD.sh b/worker/SCRIPT_PLATA_OFFLOAD.sh new file mode 100644 index 0000000..024f6c2 --- /dev/null +++ b/worker/SCRIPT_PLATA_OFFLOAD.sh @@ -0,0 +1,9 @@ + +sudo ethtool -K eth0 tx off rx off +sudo ethtool -K eth1 tx off rx off +sudo ethtool -K eth0 tx-checksum-ip-generic off +sudo ethtool -K eth1 tx-checksum-ip-generic off + + +sudo ethtool -k eth0 | grep checksum +sudo ethtool -k eth1 | grep checksum diff --git a/worker/src/dpdk_filter/net_port.c b/worker/src/dpdk_filter/net_port.c index 21390ed..0e6d607 100644 --- a/worker/src/dpdk_filter/net_port.c +++ b/worker/src/dpdk_filter/net_port.c @@ -49,8 +49,8 @@ struct net_port *init_struct_tap_port(const char *tap_iface_name, return NULL; } - snprintf(port->dev_args, sizeof(port->dev_args), "iface=%s, remote=%s", - tap_iface_name, tap_iface_name); + snprintf(port->dev_args, sizeof(port->dev_args), "iface=%s", + tap_iface_name); snprintf(port->dev_name, sizeof(port->dev_name), "net_tap_%s", tap_iface_name); strncpy(port->iface_name, tap_iface_name, sizeof(port->iface_name) - 1); @@ -83,6 +83,9 @@ struct net_port *init_struct_af_xdp_port(const char *iface_name, int net_port_init(struct net_port *port) { int ret; struct rte_eth_conf port_conf = {0}; + port_conf.txmode.offloads = RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | + RTE_ETH_TX_OFFLOAD_TCP_CKSUM | + RTE_ETH_TX_OFFLOAD_UDP_CKSUM; const char *dev_name = port->dev_name; uint16_t port_id; diff --git a/worker/src/dpdk_filter/proc_packets.c b/worker/src/dpdk_filter/proc_packets.c index 19bb286..39662d2 100644 --- a/worker/src/dpdk_filter/proc_packets.c +++ b/worker/src/dpdk_filter/proc_packets.c @@ -2,16 +2,70 @@ #include "domain_cache.h" #include "ip_cache.h" #include +#include +#include +#include +#include +#include +#include + extern bool worker_classify(const char *type, const char *target, struct requested_classification *out_req); const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS] = {22}; +static inline uint16_t checksum(void *data, uint16_t len) { + uint32_t sum = 0; + uint16_t *ptr = data; + + while (len > 1) { + sum += *ptr++; + len -= 2; + } + + if (len) { + sum += *((uint8_t *)ptr); + } + + while (sum >> 16) { + sum = (sum & 0xffff) + (sum >> 16); + } + + return (uint16_t)(~sum); +} + void package_sending_decision(bool solution_is_send, struct rte_mbuf *pkt, struct net_port *port_out, uint16_t queue_number) { if (solution_is_send) { + struct rte_ether_hdr *eth = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); + + if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) { + struct rte_ipv4_hdr *ip = (struct rte_ipv4_hdr *)(eth + 1); + uint16_t ip_hdr_len = (ip->version_ihl & 0x0F) * 4; + uint16_t ip_len = rte_be_to_cpu_16(ip->total_length); + uint16_t l4_len = ip_len - ip_hdr_len; + + if (ip->next_proto_id == IPPROTO_ICMP) { + struct rte_icmp_hdr *icmp = (struct rte_icmp_hdr *)((char *)ip + ip_hdr_len); + icmp->icmp_cksum = 0; + icmp->icmp_cksum = checksum(icmp, l4_len); + } + + else if (ip->next_proto_id == IPPROTO_TCP) { + struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *)((char *)ip + ip_hdr_len); + tcp->cksum = 0; + tcp->cksum = rte_ipv4_udptcp_cksum(ip, tcp); + } + + else if (ip->next_proto_id == IPPROTO_UDP) { + struct rte_udp_hdr *udp = (struct rte_udp_hdr *)((char *)ip + ip_hdr_len); + udp->dgram_cksum = 0; + udp->dgram_cksum = rte_ipv4_udptcp_cksum(ip, udp); + } + } + struct rte_mbuf *tx_pkt[1] = {pkt}; uint16_t ret = rte_eth_tx_burst(port_out->port_id, queue_number, tx_pkt, 1); @@ -25,6 +79,7 @@ void package_sending_decision(bool solution_is_send, struct rte_mbuf *pkt, rte_pktmbuf_free(pkt); } + bool check_is_exception(uint16_t *port) { for (int i = 0; i < LEN_LIST_EXCEPTION_PORTS; i++) { if (*port == LIST_EXCEPTION_PORTS[i]) { diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index bd03edd..eee68c5 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -92,17 +92,38 @@ void Worker::initDPDK(int argc, char **argv) { void Worker::forward_to_out(struct net_port *incoming_port, struct net_port *outgoing_port, uint16_t queue_number) { - struct rte_mbuf *tap_pkts[32]; - uint16_t nb_tap = - rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); + struct rte_mbuf *tap_pkts[FORWARD_TO_OUT_BURST_SIZE]; + uint16_t nb_tap = rte_eth_rx_burst(incoming_port->port_id, queue_number, + tap_pkts, FORWARD_TO_OUT_BURST_SIZE); for (int i = 0; i < nb_tap; i++) { - int ret = - rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); - if (ret < 1) { - spdlog::warn("Failed to send packet"); - // PLUG (to be added later) - need to add processing for this case - rte_pktmbuf_free(tap_pkts[i]); - } + struct rte_ether_hdr *eth = rte_pktmbuf_mtod(tap_pkts[i], struct rte_ether_hdr *); + + if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) { + struct rte_ipv4_hdr *ip = (struct rte_ipv4_hdr *)(eth + 1); + uint16_t ip_hdr_len = (ip->version_ihl & 0x0F) * 4; + uint16_t ip_len = rte_be_to_cpu_16(ip->total_length); + uint16_t l4_len = ip_len - ip_hdr_len; + + if (ip->next_proto_id == IPPROTO_ICMP) { + struct rte_icmp_hdr *icmp = (struct rte_icmp_hdr *)((char *)ip + ip_hdr_len); + icmp->icmp_cksum = 0; + icmp->icmp_cksum = checksum(icmp, l4_len); + } else if (ip->next_proto_id == IPPROTO_TCP) { + struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *)((char *)ip + ip_hdr_len); + tcp->cksum = 0; + tcp->cksum = rte_ipv4_udptcp_cksum(ip, tcp); + } else if (ip->next_proto_id == IPPROTO_UDP) { + struct rte_udp_hdr *udp = (struct rte_udp_hdr *)((char *)ip + ip_hdr_len); + udp->dgram_cksum = 0; + udp->dgram_cksum = rte_ipv4_udptcp_cksum(ip, udp); + } + } + + int ret = rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); + if (ret < 1) { + LOG_ERROR("Failed to send packet"); + rte_pktmbuf_free(tap_pkts[i]); + } } }