OCT 1. 备份代码

This commit is contained in:
huangxin 2023-03-20 10:47:22 +08:00
parent b36960f878
commit 325c51d940
8 changed files with 332 additions and 133 deletions

View File

@ -81,21 +81,6 @@ typedef struct {
U8 options[0];
} DHCP_PROTO, *PDHCP_PROTO;
typedef struct {
U8 flags;
U8 res1;
U8 res2;
U8 res3;
U32 vni;
} VXLAN_HDR, *PVXLAN_HDR;
typedef struct {
U16 out_priority_cfi_and_id;
U16 in_type;
U16 in_priority_cfi_and_id;
U16 origin_type;
} QINQ_HDR, *PQINQ_HDR;
#pragma pack(pop)
int dhcpd_init();

View File

@ -5,9 +5,9 @@ PROJECT(${LIB_PROJECT_TARGET} VERSION 1.1.0)
STRING(REPLACE ";" ", " BUILD_CONFIG_INFO "${COMMON_DEFINE}")
CONFIGURE_FILE(lib_config.h.in lib_config.h)
INCLUDE_DIRECTORIES(include ../opendhcp183 ./mongoose
INCLUDE_DIRECTORIES(include ../opendhcp183 mongoose
./ ./include ../lwip/src/include ../lwip/src/arch_linux/include ../include)
FILE(GLOB C_HEADS include/*.h include/uthash/*.h include/s2j/*.h vector/*.h ${CMAKE_BINARY_DIR}/*.h ${PROJECT_BINARY_DIR}/*.h)
FILE(GLOB C_HEADS ./include/network/*.h include/*.h include/uthash/*.h include/s2j/*.h vector/*.h ${CMAKE_BINARY_DIR}/*.h ${PROJECT_BINARY_DIR}/*.h)
AUX_SOURCE_DIRECTORY(json C_SRC)
AUX_SOURCE_DIRECTORY(args C_SRC)

View File

@ -0,0 +1,37 @@
//
// Created by xajhuang on 2023/3/18.
//
#ifndef VCPE_VLAN_H
#define VCPE_VLAN_H
#ifdef __cplusplus
extern "C" {
#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <linux/if_ether.h>
#include "common.h"
#pragma pack(push)
#pragma pack(1)
#define VXLAN_VIN_ID_PACK(x) ((ntohs(x)) & 0xFFF)
typedef struct vlan_hdr {
U16 id;
U16 type;
} VLAN_HDR, *PVLAN_HDR;
typedef struct {
struct ethhdr eth;
struct vlan_hdr vlan;
struct iphdr ip;
struct udphdr udp;
} VLAN_PKG_HDR, *PVLAN_PKG_HDR;
#pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif //VCPE_VLAN_H

View File

@ -4,5 +4,52 @@
#ifndef VCPE_VXLAN_H
#define VCPE_VXLAN_H
#ifdef __cplusplus
extern "C" {
#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <linux/if_ether.h>
#include "common.h"
#pragma pack(push)
#pragma pack(1)
typedef struct vxlan_hdr {
U8 flags;
U8 res1;
U8 res2;
U8 res3;
U32 vni;
} VXLAN_HDR, *PVXLAN_HDR;
typedef struct qinq_hdr {
#if __BYTE_ORDER == __LITTLE_ENDIAN
U32 priority : 3;
U32 dei : 1;
U32 id : 12;
#elif __BYTE_ORDER == __BIG_ENDIAN
U32 id : 12;
U32 dei : 1;
U32 priority : 3;
#else
#error "Please fix <bits/endian.h>"
#endif
} QINQ_HDR, *PQINQ_HDR;
typedef struct {
struct ethhdr eth;
struct iphdr ip;
struct udphdr udp;
struct vxlan_hdr vxlan;
struct ethhdr eth_in;
struct qinq_hdr qinq;
} VXLAN_PKG_HDR, *PVXLAN_PKG_HDR;
#pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif //VCPE_VXLAN_H

View File

@ -23,48 +23,49 @@ extern "C" {
ERR_CODE(ERR_GET_FILE_SIZE, 11, "获取文件大小失败") \
ERR_CODE(ERR_COPY_FILE, 12, "复制文件失败") \
ERR_CODE(ERR_MALLOC_MEMORY, 13, "分配内存失败") \
ERR_CODE(ERR_EVP_KEY_SIZE, 14, "秘钥大小不正确") \
ERR_CODE(ERR_UNSUP_EVP_TYPE, 15, "不支持的加解密算法") \
ERR_CODE(ERR_EVP_INIT_KEY, 16, "初始化秘钥失败") \
ERR_CODE(ERR_EVP_UPDATE, 17, "加解密数据失败") \
ERR_CODE(ERR_EVP_FINALE, 18, "错误的加解密结果") \
ERR_CODE(ERR_EVP_CREATE_CTX, 19, "初始化加解密失败") \
ERR_CODE(ERR_AES_KEYGEN, 20, "AES秘钥失败") \
ERR_CODE(ERR_EVP_ENCRYPTION, 21, "加密失败") \
ERR_CODE(ERR_EVP_DECRYPTION, 22, "解密失败") \
ERR_CODE(ERR_CONFIG_INIT, 23, "配置文件初始化失败") \
ERR_CODE(ERR_UNCOMPATIBILITY_TYPE, 24, "未兼容的类型") \
ERR_CODE(ERR_STRING_TO_NUMBER, 25, "字符串转数字失败") \
ERR_CODE(ERR_UNKNOWN_CFG_ID, 26, "未识别的配置项") \
ERR_CODE(ERR_ZLOG_INIT, 27, "日志系统初始化失败") \
ERR_CODE(ERR_SYS_GET_CPU_INFO, 28, "获取CPU信息失败") \
ERR_CODE(ERR_SYS_NOT_FOUND_CPU, 29, "找不到CPU信息") \
ERR_CODE(ERR_SYS_DISK_GET_INFO, 30, "获取磁盘空间占用信息失败") \
ERR_CODE(ERR_SYS_IPMI_UNSUP, 31, "服务器IPMI接口不支持") \
ERR_CODE(ERR_SYS_SENSOR_GET_INFO, 32, "获取传感器信息失败") \
ERR_CODE(ERR_DB_CONNECT, 33, "数据库连接失败") \
ERR_CODE(ERR_MQ_CREATE_MQ, 34, "创建消息队列失败") \
ERR_CODE(ERR_MQ_CREATE_REP, 35, "创建REP消息队列失败") \
ERR_CODE(ERR_MQ_BIND_SOCKET, 36, "消息队列BIND Socket失败") \
ERR_CODE(ERR_MQ_CONN_SERVER, 37, "消息队列连接服务器失败") \
ERR_CODE(ERR_MQ_SEND_MSG, 38, "消息队列发送消息失败") \
ERR_CODE(ERR_JSON_CREAT_OBJ, 39, "创建JSON对象失败") \
ERR_CODE(ERR_JSON_PARSE_OBJ, 40, "解析JSON对象失败") \
ERR_CODE(ERR_JSON_VALID_SCH, 41, "JSON数据验证失败") \
ERR_CODE(ERR_CREATE_NETIF, 42, "创建网络接口失败") \
ERR_CODE(ERR_CREATE_PPPOE_NETIF, 43, "创建PPPoE网络接口失败") \
ERR_CODE(ERR_CREATE_PPP_SESSION, 44, "创建PPP连接失败") \
ERR_CODE(ERR_MISC_GET_IPADDR, 45, "获取网卡IP地址失败") \
ERR_CODE(ERR_MISC_GET_NETMASK, 46, "获取网卡子网掩码失败") \
ERR_CODE(ERR_MISC_GET_GATEWAY, 47, "获取网卡网关地址失败") \
ERR_CODE(ERR_MISC_GET_MACADDR, 48, "获取网卡MAC地址失败") \
ERR_CODE(ERR_MENU_EXIT, 49, "菜单执行完后自动退出") \
ERR_CODE(ERR_HTTP_UNSUP_METHOD, 50, "不支持的 HTTP 请求方法") \
ERR_CODE(ERR_HTTP_UNSUP_PAGE, 51, "找不到 HTTP 服务") \
ERR_CODE(ERR_PROTO_DECODE, 52, "HTTP 协议解析失败") \
ERR_CODE(ERR_MSG_CONTENT, 53, "msgContent内容不正确") \
ERR_CODE(ERR_SOCK_CREATE, 54, "创建套接字失败") \
ERR_CODE(ERR_SOCK_SETOPT, 55, "设置套接字参数失败")
ERR_CODE(ERR_MMAP_MEMORY, 14, "共享内存失败") \
ERR_CODE(ERR_EVP_KEY_SIZE, 15, "秘钥大小不正确") \
ERR_CODE(ERR_UNSUP_EVP_TYPE, 16, "不支持的加解密算法") \
ERR_CODE(ERR_EVP_INIT_KEY, 17, "初始化秘钥失败") \
ERR_CODE(ERR_EVP_UPDATE, 18, "加解密数据失败") \
ERR_CODE(ERR_EVP_FINALE, 19, "错误的加解密结果") \
ERR_CODE(ERR_EVP_CREATE_CTX, 20, "初始化加解密失败") \
ERR_CODE(ERR_AES_KEYGEN, 21, "AES秘钥失败") \
ERR_CODE(ERR_EVP_ENCRYPTION, 22, "加密失败") \
ERR_CODE(ERR_EVP_DECRYPTION, 23, "解密失败") \
ERR_CODE(ERR_CONFIG_INIT, 24, "配置文件初始化失败") \
ERR_CODE(ERR_UNCOMPATIBILITY_TYPE, 25, "未兼容的类型") \
ERR_CODE(ERR_STRING_TO_NUMBER, 26, "字符串转数字失败") \
ERR_CODE(ERR_UNKNOWN_CFG_ID, 27, "未识别的配置项") \
ERR_CODE(ERR_ZLOG_INIT, 28, "日志系统初始化失败") \
ERR_CODE(ERR_SYS_GET_CPU_INFO, 29, "获取CPU信息失败") \
ERR_CODE(ERR_SYS_NOT_FOUND_CPU, 30, "找不到CPU信息") \
ERR_CODE(ERR_SYS_DISK_GET_INFO, 31, "获取磁盘空间占用信息失败") \
ERR_CODE(ERR_SYS_IPMI_UNSUP, 32, "服务器IPMI接口不支持") \
ERR_CODE(ERR_SYS_SENSOR_GET_INFO, 33, "获取传感器信息失败") \
ERR_CODE(ERR_DB_CONNECT, 34, "数据库连接失败") \
ERR_CODE(ERR_MQ_CREATE_MQ, 35, "创建消息队列失败") \
ERR_CODE(ERR_MQ_CREATE_REP, 36, "创建REP消息队列失败") \
ERR_CODE(ERR_MQ_BIND_SOCKET, 37, "消息队列BIND Socket失败") \
ERR_CODE(ERR_MQ_CONN_SERVER, 38, "消息队列连接服务器失败") \
ERR_CODE(ERR_MQ_SEND_MSG, 39, "消息队列发送消息失败") \
ERR_CODE(ERR_JSON_CREAT_OBJ, 40, "创建JSON对象失败") \
ERR_CODE(ERR_JSON_PARSE_OBJ, 41, "解析JSON对象失败") \
ERR_CODE(ERR_JSON_VALID_SCH, 42, "JSON数据验证失败") \
ERR_CODE(ERR_CREATE_NETIF, 43, "创建网络接口失败") \
ERR_CODE(ERR_CREATE_PPPOE_NETIF, 44, "创建PPPoE网络接口失败") \
ERR_CODE(ERR_CREATE_PPP_SESSION, 45, "创建PPP连接失败") \
ERR_CODE(ERR_MISC_GET_IPADDR, 46, "获取网卡IP地址失败") \
ERR_CODE(ERR_MISC_GET_NETMASK, 47, "获取网卡子网掩码失败") \
ERR_CODE(ERR_MISC_GET_GATEWAY, 48, "获取网卡网关地址失败") \
ERR_CODE(ERR_MISC_GET_MACADDR, 49, "获取网卡MAC地址失败") \
ERR_CODE(ERR_MENU_EXIT, 50, "菜单执行完后自动退出") \
ERR_CODE(ERR_HTTP_UNSUP_METHOD, 51, "不支持的 HTTP 请求方法") \
ERR_CODE(ERR_HTTP_UNSUP_PAGE, 52, "找不到 HTTP 服务") \
ERR_CODE(ERR_PROTO_DECODE, 53, "HTTP 协议解析失败") \
ERR_CODE(ERR_MSG_CONTENT, 54, "msgContent内容不正确") \
ERR_CODE(ERR_SOCK_CREATE, 55, "创建套接字失败") \
ERR_CODE(ERR_SOCK_SETOPT, 56, "设置套接字参数失败")
#define GENERATE_ENUM(ENUM, no, x) ENUM,

View File

@ -79,6 +79,7 @@ typedef enum {
zlog_put_mdc("vni", zlog_vni_tag_get()); \
} \
hzlog_##level(zlog_get_mod_cat((mod)), format, ##__VA_ARGS__); \
printf("\n"); \
} \
} while (0)

View File

@ -7712,7 +7712,7 @@ static void rx_dhcp_server(struct mip_if *ifp, struct pkt *pkt) {
if (end < (uint8_t *)(pkt->dhcp + 1)) {
return;
}
// struct dhcp *req = pkt->dhcp;
// struct dhcp *recv_req = pkt->dhcp;
struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
res.yiaddr = ifp->ip;
((uint8_t *)(&res.yiaddr))[3]++; // Offer our IP + 1

View File

@ -6,35 +6,59 @@
#include <string.h>
#include <linux/filter.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include "service/dhcpd.h"
#include "user_errno.h"
#include "task_manager.h"
#include "zlog_module.h"
#include "network/vlan.h"
#define PKG_MMAP_BLOCKSIZ (1 << 22)
#define PKG_MMAP_FRAMESIZ (1 << 11)
#define PKG_MMAP_BLOCKNUM (64)
typedef struct {
struct iovec *rd;
uint8_t *map;
struct tpacket_req3 req;
} PACKET_MMAP_RING, *PPACKET_MMAP_RING;
struct block_desc {
uint32_t version;
uint32_t offset_to_priv;
struct tpacket_hdr_v1 h1;
};
#pragma pack(1)
typedef struct {
struct ethhdr eth;
struct iphdr ip;
struct udphdr udp;
VLAN_PKG_HDR vlan_hdr;
DHCP_PROTO dhcp;
} DHCP_PACKAGE, *PDHCP_PACKAGE;
#pragma pack()
typedef struct {
uv_work_t uvWork;
unsigned short nSize;
unsigned char *pPkgBase;
void *pData;
} PKG_PROCESS_INFO, *PPKG_PROCESS_INFO;
typedef struct {
unsigned int vni;
unsigned short q1;
unsigned short q2;
} VXLAN_TAG, *PVXLAN_TAG;
unsigned int nf;
PPKG_PROCESS_INFO pPkgInfo;
} PKG_MSG, *PPKG_MSG;
#pragma pack()
/*
TORs (Top of Rack switch) at Facebook run DHCP relayers, these relayers are
responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT
messages) originating within their racks to anycast VIPs, one DHCPv4 and one
for DHCPv6.
*/
static struct sock_filter g_filterCode[] = {
#ifdef UDP_DHCP_FILTER // create by: tcpdump "udp and port 67 and port 68" -dd
{0x28, 0, 0, 0x0000000c},
@ -64,6 +88,7 @@ static struct sock_filter g_filterCode[] = {
{0x6, 0, 0, 0x00040000},
{0x6, 0, 0, 0x00000000},
#endif
#if 0
// create by: tcpdump "vxlan" -dd
{0x28, 0, 0, 0x0000000c},
{0x15, 2, 0, 0x00008100},
@ -71,36 +96,41 @@ static struct sock_filter g_filterCode[] = {
{0x15, 0, 1, 0x00009100},
{0x6, 0, 0, 0x00040000},
{0x6, 0, 0, 0x00000000},
#endif
// create by: tcpdump "vlan" -dd
{0x30, 0, 0, 0xfffff030},
{0x15, 4, 0, 0x00000001},
{0x28, 0, 0, 0x0000000c},
{0x15, 2, 0, 0x00008100},
{0x15, 1, 0, 0x000088a8},
{0x15, 0, 1, 0x00009100},
{0x6, 0, 0, 0x00040000},
{0x6, 0, 0, 0x00000000},
};
static PACKET_MMAP_RING g_pkgRing;
static struct sock_fprog bpf = {
.len = sizeof(g_filterCode) / (sizeof(struct sock_filter)),
.filter = g_filterCode,
};
static void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
*buf = uv_buf_init(malloc(suggested_size), suggested_size);
}
static void on_sock_recv(uv_work_t *req) {
PPKG_PROCESS_INFO pWork = (PPKG_PROCESS_INFO)req->data;
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)pWork->pPkgBase;
static void package_process(uv_work_t *req) {
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)req->data;
}
static void on_read(uv_udp_t *req, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
if (nread > 0) {
uv_work_t *pWork = (uv_work_t *)malloc(sizeof(uv_work_t));
if (!pWork) {
free(buf->base);
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Malloc %lu memory error\n", sizeof(uv_work_t));
return;
}
pWork->data = (void *)buf;
uv_queue_work(get_task_manager(), pWork, package_process, NULL);
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)buf->base;
//LOG_MSG_HEX(debug, pkg, pWork->nSize);
#if 0
LOG_MOD(info, ZLOG_MOD_OPENDHCPD, "vlan = %u\n", VXLAN_VIN_ID_PACK(pkg->vlan_hdr.vlan.id));
LOG_MSG(info, "xid: 0x%08X\n", ntohl(pkg->dhcp.xid));
LOG_MSG(info,
"dest mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
pkg->vlan_hdr.eth.h_dest[0],
pkg->vlan_hdr.eth.h_dest[1],
pkg->vlan_hdr.eth.h_dest[2],
pkg->vlan_hdr.eth.h_dest[3],
pkg->vlan_hdr.eth.h_dest[4],
pkg->vlan_hdr.eth.h_dest[5]);
LOG_MSG(info,
"client mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
pkg->dhcp.chaddr[0],
@ -109,64 +139,161 @@ static void on_read(uv_udp_t *req, ssize_t nread, const uv_buf_t *buf, const str
pkg->dhcp.chaddr[3],
pkg->dhcp.chaddr[4],
pkg->dhcp.chaddr[5]);
//LOG_MSG_HEX(debug, buf->base, nread);
#endif
}
free(buf->base);
static void after_msg_recv(uv_work_t *req, int status) {
PPKG_PROCESS_INFO pInfo = (PPKG_PROCESS_INFO)req->data;
PPKG_MSG pMsg = (PPKG_MSG)pInfo->pData;
pMsg->nf -= 1;
if (pMsg->nf <= 0) {
LOG_MOD(debug, ZLOG_MOD_OPENDHCPD, "Free all resources: %p\n", pMsg);
free(pMsg->pPkgInfo);
free(pMsg);
}
}
void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
static unsigned int block_num = 0;
if (status >= 0) {
struct block_desc *pbd = (struct block_desc *)g_pkgRing.rd[block_num].iov_base;
if ((pbd->h1.block_status & TP_STATUS_USER) != 0) {
int i;
unsigned int num_pkts = pbd->h1.num_pkts;
struct tpacket3_hdr *ppd;
uv_loop_t *pLoop = get_task_manager();
if (num_pkts > 0) {
unsigned int memSize = sizeof(PKG_PROCESS_INFO) * num_pkts;
PPKG_MSG pMsg = (PPKG_MSG)malloc(sizeof(PKG_MSG));
if (pMsg == NULL) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Malloc memory error: %lu\n", sizeof(PKG_MSG));
return;
}
memset(pMsg, 0, sizeof(PKG_MSG));
pMsg->pPkgInfo = (PPKG_PROCESS_INFO)malloc(memSize);
if (pMsg->pPkgInfo == NULL) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Malloc memory error: %u\n", memSize);
free(pMsg);
return;
}
memset(pMsg->pPkgInfo, 0, memSize);
pMsg->nf = num_pkts;
ppd = (struct tpacket3_hdr *)((uint8_t *)pbd + pbd->h1.offset_to_first_pkt);
for (i = 0; i < num_pkts; i++) {
pMsg->pPkgInfo[i].pPkgBase = ((uint8_t *)ppd + ppd->tp_mac);
pMsg->pPkgInfo[i].nSize = ppd->tp_snaplen;
pMsg->pPkgInfo[i].uvWork.data = &pMsg->pPkgInfo[i];
pMsg->pPkgInfo[i].pData = pMsg;
uv_queue_work(get_task_manager(), &(pMsg->pPkgInfo[i].uvWork), on_sock_recv, after_msg_recv);
ppd = (struct tpacket3_hdr *)((uint8_t *)ppd + ppd->tp_next_offset);
}
}
}
pbd->h1.block_status = TP_STATUS_KERNEL;
block_num = (block_num + 1) % PKG_MMAP_BLOCKNUM;
}
}
static int create_udp_socket() {
int i;
int err;
int v = TPACKET_V3;
struct sockaddr_ll addr;
// 1. create socket
int sock_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sock_fd < 0) {
perror("socket created failure");
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Socket created failure\n");
return -ERR_SOCK_CREATE;
}
// 2. attach filter (no need to call bind)
if ((err = setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))) < 0) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Attaching filter failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
#if 1
// 3. set PACKET_MMAP version
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v))) < 0) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Set PACKET_VERSION option failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
// 4. setup PAKCET_MMAP ring
memset(&g_pkgRing.req, 0, sizeof(g_pkgRing.req));
g_pkgRing.req.tp_block_size = PKG_MMAP_BLOCKSIZ;
g_pkgRing.req.tp_frame_size = PKG_MMAP_FRAMESIZ;
g_pkgRing.req.tp_block_nr = PKG_MMAP_BLOCKNUM;
g_pkgRing.req.tp_frame_nr = (PKG_MMAP_BLOCKSIZ * PKG_MMAP_BLOCKNUM) / PKG_MMAP_FRAMESIZ;
g_pkgRing.req.tp_retire_blk_tov = 60;
g_pkgRing.req.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_RX_RING, &g_pkgRing.req, sizeof(g_pkgRing.req))) < 0) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Set PACKET_RX_RING option failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
g_pkgRing.map = mmap(NULL,
g_pkgRing.req.tp_block_size * g_pkgRing.req.tp_block_nr,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_LOCKED,
sock_fd,
0);
if (g_pkgRing.map == MAP_FAILED) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "MMAP socket ring failed\n");
return -ERR_MMAP_MEMORY;
}
// 5. malloc read buffer
g_pkgRing.rd = malloc(g_pkgRing.req.tp_block_nr * sizeof(struct iovec));
if (g_pkgRing.rd == NULL) {
LOG_MOD(error,
ZLOG_MOD_OPENDHCPD,
"Malloc memory failed: %lu\n",
g_pkgRing.req.tp_block_nr * sizeof(struct iovec));
return -ERR_MMAP_MEMORY;
}
for (i = 0; i < g_pkgRing.req.tp_block_nr; ++i) {
g_pkgRing.rd[i].iov_base = g_pkgRing.map + (i * g_pkgRing.req.tp_block_size);
g_pkgRing.rd[i].iov_len = g_pkgRing.req.tp_block_size;
}
#endif
// 6. bind socket
const char *iface_name = "ens192";
memset(&addr, 0, sizeof(addr));
addr.sll_ifindex = (int)if_nametoindex(iface_name);
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_hatype = 0;
addr.sll_pkttype = 0;
addr.sll_halen = 0;
// 2. attach filter (no need to call bind)
if (setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)) < 0) {
perror("attaching filter failed");
if ((err = bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr))) < 0) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Bind raw socket failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
return sock_fd;
}
#if 0
#define MAX_DATE_ITEMS (64)
void fib(uv_work_t *req) {
int cnt = 3;
fprintf(stderr, "Task %ld\n", (long)(req->data));
while (cnt--) {
uv_sleep(1000);
}
}
void after_fib(uv_work_t *req, int status) {
fprintf(stderr, "Finish Task %ld\n", (long)(req->data));
}
#endif
int dhcpd_init() {
static uv_udp_t uvRaw;
#if 0
static unsigned int data[MAX_DATE_ITEMS];
static uv_work_t req[MAX_DATE_ITEMS];
int i;
for (i = 0; i < MAX_DATE_ITEMS; i++) {
req[i].data = (void *)(intptr_t)i;
uv_queue_work(get_task_manager(), &req[i], fib, after_fib);
}
#endif
static uv_poll_t uvSocket;
int sock = create_udp_socket();
@ -174,12 +301,13 @@ int dhcpd_init() {
return sock;
}
LOG_MSG(info, "sizeof DHCP_PACKAGE = %lu\n", sizeof(DHCP_PACKAGE));
//LOG_MSG(info, "sizeof DHCP_PACKAGE = %lu\n", sizeof(DHCP_PACKAGE));
uv_udp_init(get_task_manager(), &uvRaw);
uv_udp_open(&uvRaw, sock);
uv_udp_recv_start(&uvRaw, alloc_buffer, on_read);
uv_poll_init_socket(get_task_manager(), &uvSocket, sock);
uv_poll_start(&uvSocket, UV_READABLE, raw_sock_recv_cb);
return ERR_SUCCESS;
}