OCT 1. 拆分DHCP服务代码,供其它模块调用

This commit is contained in:
huangxin 2023-04-20 16:46:20 +08:00
parent 4eeb3e6b99
commit ff887e21e3
8 changed files with 219 additions and 104 deletions

View File

@ -19,9 +19,9 @@ FUNCTION(LINUX_INSTALL_SYSTEM_PACKAGE)
MESSAGE("Run this command to install system(${OS_DISTRIB_NAME}) dependencies libraries:") MESSAGE("Run this command to install system(${OS_DISTRIB_NAME}) dependencies libraries:")
IF (${OS_DISTRIB_NAME} MATCHES "CentOS") IF (${OS_DISTRIB_NAME} MATCHES "CentOS")
MESSAGE(FATAL_ERROR "$sudo yum -y install libcurl-devel czmq-devel openssl-devel") MESSAGE(FATAL_ERROR "$sudo yum -y install libcurl-devel czmq-devel openssl-devel libjson-c-devel")
ELSEIF (${OS_DISTRIB_NAME} MATCHES "Ubuntu") ELSEIF (${OS_DISTRIB_NAME} MATCHES "Ubuntu")
MESSAGE(FATAL_ERROR "$sudo apt -y install libcurl4-openssl-dev libczmq-dev libssl-dev") MESSAGE(FATAL_ERROR "$sudo apt -y install libcurl4-openssl-dev libczmq-dev libssl-dev libjson-c-dev")
ENDIF () ENDIF ()
ELSE () ELSE ()
MESSAGE(FATAL_ERROR "Run command to install system dependencies libraries [libcurl,libssl,libcrypto,libzmq] by yourself") MESSAGE(FATAL_ERROR "Run command to install system dependencies libraries [libcurl,libssl,libcrypto,libzmq] by yourself")

View File

@ -44,6 +44,7 @@ int get_all_network_info(PSYS_NIC_INFO pInfo);
const char *u32_to_str_ip(unsigned int ip); const char *u32_to_str_ip(unsigned int ip);
unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned char *pUdp); unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned char *pUdp);
unsigned short ip_checksum(unsigned char *pIp); unsigned short ip_checksum(unsigned char *pIp);
int string_mac_to_bytes(const char *pStrMac, unsigned char macByte[6]);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -18,6 +18,7 @@
#include "misc.h" #include "misc.h"
#include "zlog_module.h" #include "zlog_module.h"
#include "common.h" #include "common.h"
#include "sds/sds.h"
PSYS_NIC_INFO g_sysNicInfo = NULL; PSYS_NIC_INFO g_sysNicInfo = NULL;
@ -309,7 +310,7 @@ int get_all_network_info(PSYS_NIC_INFO pInfo) {
return -ERR_MALLOC_MEMORY; return -ERR_MALLOC_MEMORY;
} }
LOG_MOD(info, ZLOG_MOD_MISC, "Malloc memory size: %lu * %lu\n", sizeof(NIC_CTX), nicCnt); LOG_MOD(trace, ZLOG_MOD_MISC, "Malloc memory size: %lu * %lu\n", sizeof(NIC_CTX), nicCnt);
memset(pNicInfo->pNicCtx, 0, sizeof(NIC_CTX) * nicCnt); memset(pNicInfo->pNicCtx, 0, sizeof(NIC_CTX) * nicCnt);
@ -416,3 +417,30 @@ unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned cha
csum = ((csum & 0xFFFF0000) >> 16) + (csum & 0xFFFF); csum = ((csum & 0xFFFF0000) >> 16) + (csum & 0xFFFF);
return (unsigned short)(~csum); return (unsigned short)(~csum);
} }
int string_mac_to_bytes(const char *pStrMac, unsigned char macByte[6]) {
sds *tokens;
int i, nCnt;
if (pStrMac == NULL || strlen(pStrMac) != strlen("00:00:00:00:00:00")) {
LOG_MOD(error, ZLOG_MOD_MISC, "Input params error\n");
return -ERR_INPUT_PARAMS;
}
tokens = sdssplitlen(pStrMac, (int)strlen(pStrMac), ":", 1, &nCnt);
if (nCnt != 6) {
LOG_MOD(error, ZLOG_MOD_MISC, "Input MAC[%s] error: %d\n", pStrMac, nCnt);
return -ERR_INPUT_PARAMS;
}
for (i = 0; i < nCnt; i++) {
macByte[i] = strtoul(tokens[i], NULL, 16);
}
if (tokens) {
sdsfreesplitres(tokens, nCnt);
}
return ERR_SUCCESS;
}

View File

@ -5,7 +5,6 @@
#include "common.h" #include "common.h"
#include "dhcp_options.h" #include "dhcp_options.h"
#include "user_errno.h" #include "user_errno.h"
#include "zlog_module.h"
static const DHCP_OPTION_CFG g_opCfg[] = { static const DHCP_OPTION_CFG g_opCfg[] = {
// region DHCP optinos configure table // region DHCP optinos configure table

View File

@ -1,97 +1,28 @@
// //
// Created by xajhuang on 2023/3/16. // Created by xajhuang on 2023/3/16.
// //
#include <uv.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/if_packet.h>
#include <net/if.h> #include <net/if.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <pcap/pcap.h> #include <pcap/pcap.h>
#include <unistd.h>
#include "service/dhcpd.h"
#include "user_errno.h" #include "user_errno.h"
#include "task_manager.h" #include "task_manager.h"
#include "zlog_module.h" #include "zlog_module.h"
#include "network/vlan.h"
#include "dhcp_options.h" #include "dhcp_options.h"
#include "config.h" #include "config.h"
#include "misc.h" #include "misc.h"
#include "user_mgr.h" #include "user_mgr.h"
#include "rfc2131.h"
#include "dhcp_network.h"
#define DHCP_COOKIE_VAL (0x63825363)
#define PKG_MMAP_BLOCKSIZ (1 << 22)
#define PKG_MMAP_FRAMESIZ (1 << 11)
#define PKG_MMAP_BLOCKNUM (64)
#define MAX_DHCP_PKG_SIZE (512)
#define VLAN_VNI_ID(x) ntohs((x))
#define DHCP_XID(x) ntohl((x))
#define MAXIMUM_SNAPLEN (262144) #define MAXIMUM_SNAPLEN (262144)
#define MAC_TO_STR(mac, str) \
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])
typedef struct {
U8 unicast;
U8 cliMac[ETH_ALEN];
U32 xid;
U32 reqIpAddr;
U32 leaseTime;
char clientId[256];
char vendorClassId[256];
char hostName[256];
} DHCP_REQ, *PDHCP_REQ;
typedef struct {
int sock;
struct sockaddr_ll addr;
struct iovec *rx;
struct iovec *tx;
uint8_t *map_recv;
uint8_t *map_send;
struct tpacket_req3 recv;
struct tpacket_req3 send;
unsigned int index;
} PACKET_MMAP_RING, *PPACKET_MMAP_RING;
typedef struct {
char *pIfName;
U32 ipAddr;
U32 netmask;
U8 macAddr[ETH_ALEN];
S8 hostname[MAX_PATH];
} NIC_INFO, *PNIC_INFO;
struct block_desc {
uint32_t version;
uint32_t offset_to_priv;
struct tpacket_hdr_v1 h1;
};
#pragma pack(1)
typedef struct {
VLAN_PKG_HDR vlan_hdr;
DHCP_PROTO dhcp;
} DHCP_PACKAGE, *PDHCP_PACKAGE;
typedef struct {
uv_work_t uvWork;
unsigned short nSize;
unsigned char *pPkgBase;
void *pData;
} PKG_PROCESS_INFO, *PPKG_PROCESS_INFO;
typedef struct {
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 TORs (Top of Rack switch) at Facebook run DHCP relayers, these relayers are
responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT
@ -219,7 +150,7 @@ static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo; static NIC_INFO g_nicInfo;
static uv_udp_t g_uvRawSockReq; static uv_udp_t g_uvRawSockReq;
void *get_pkg_memory() { void *get_pkg_free_buf() {
int i; int i;
ssize_t ret; ssize_t ret;
struct tpacket3_hdr *hdr; struct tpacket3_hdr *hdr;
@ -250,7 +181,7 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
U8 *pOpt; U8 *pOpt;
U16 csum; U16 csum;
int tolSize; int tolSize;
PDHCP_PACKAGE pRsp = get_pkg_memory(); PDHCP_PACKAGE pRsp = get_pkg_free_buf();
if (pRsp == NULL) { if (pRsp == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE); LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
@ -510,6 +441,7 @@ static void after_msg_recv(uv_work_t *req, int status) {
void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) { void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
static unsigned int block_num = 0; static unsigned int block_num = 0;
PRECV_CB_DATA pCbData = handle->data;
if (status >= 0 && (events & UV_READABLE)) { if (status >= 0 && (events & UV_READABLE)) {
struct block_desc *pbd = (struct block_desc *)g_pkgRing.rx[block_num].iov_base; struct block_desc *pbd = (struct block_desc *)g_pkgRing.rx[block_num].iov_base;
@ -546,7 +478,15 @@ void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
pMsg->pPkgInfo[i].uvWork.data = &pMsg->pPkgInfo[i]; pMsg->pPkgInfo[i].uvWork.data = &pMsg->pPkgInfo[i];
pMsg->pPkgInfo[i].pData = pMsg; pMsg->pPkgInfo[i].pData = pMsg;
if (pCbData) {
uv_queue_work(get_task_manager(),
&(pMsg->pPkgInfo[i].uvWork),
pCbData->work_cb ? pCbData->work_cb : on_sock_recv,
pCbData->after_work_cb ? pCbData->after_work_cb : after_msg_recv);
} else {
uv_queue_work(get_task_manager(), &(pMsg->pPkgInfo[i].uvWork), on_sock_recv, after_msg_recv); 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); ppd = (struct tpacket3_hdr *)((uint8_t *)ppd + ppd->tp_next_offset);
} }
} }
@ -556,7 +496,7 @@ void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
} }
} }
static int create_udp_socket() { int create_udp_raw_socket(const char *pNicName) {
struct sockaddr_ll addr; struct sockaddr_ll addr;
unsigned int size; unsigned int size;
int i; int i;
@ -660,7 +600,7 @@ static int create_udp_socket() {
// 9. bind socket // 9. bind socket
memset(&addr, 0, sizeof(struct sockaddr_ll)); memset(&addr, 0, sizeof(struct sockaddr_ll));
addr.sll_ifindex = (int)if_nametoindex(g_nicInfo.pIfName); addr.sll_ifindex = (int)if_nametoindex(pNicName);
addr.sll_family = PF_PACKET; addr.sll_family = PF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL); addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_hatype = 0; addr.sll_hatype = 0;
@ -677,7 +617,7 @@ static int create_udp_socket() {
return ERR_SUCCESS; return ERR_SUCCESS;
} }
static void socket_send_task(uv_timer_t *UNUSED(pArg)) { void socket_send_task(uv_timer_t *UNUSED(pArg)) {
int i; int i;
struct tpacket3_hdr *hdr; struct tpacket3_hdr *hdr;
@ -694,17 +634,16 @@ static void socket_send_task(uv_timer_t *UNUSED(pArg)) {
} }
} }
void init_filter() { void init_filter(const char *pNetFilter) {
#ifdef USED_DEFAULT_BPF #ifdef USED_DEFAULT_BPF
bpf.len = sizeof(g_filterCode) / (sizeof(struct sock_filter)); bpf.len = sizeof(g_filterCode) / (sizeof(struct sock_filter));
bpf.filter = g_filterCode; bpf.filter = g_filterCode;
#else #else
static pcap_t *pd; static pcap_t *pd;
pd = pcap_open_dead(DLT_EN10MB, MAXIMUM_SNAPLEN); pd = pcap_open_dead(DLT_EN10MB, MAXIMUM_SNAPLEN);
struct bpf_program fcode; struct bpf_program fcode;
char *cmd_buf = "vlan and udp and port 67 and port 68"; //char *cmd_buf = "vlan and udp and port 67 and port 68";
pcap_compile(pd, &fcode, cmd_buf, 1, 0); pcap_compile(pd, &fcode, pNetFilter, 1, 0);
struct bpf_insn *insn = fcode.bf_insns; struct bpf_insn *insn = fcode.bf_insns;
struct sock_filter *g_filters = (struct sock_filter *)malloc(fcode.bf_len * sizeof(struct sock_filter)); struct sock_filter *g_filters = (struct sock_filter *)malloc(fcode.bf_len * sizeof(struct sock_filter));
@ -723,9 +662,26 @@ void init_filter() {
#endif #endif
} }
int dhcpd_init() { void init_raw_socket_poll(void *pRecv, void *pClean) {
static RECV_CB_DATA rcData;
static uv_poll_t uvSocket; static uv_poll_t uvSocket;
static uv_timer_t uvTm; static uv_timer_t uvTm;
uv_udp_init(get_task_manager(), &g_uvRawSockReq);
uv_udp_open(&g_uvRawSockReq, g_pkgRing.sock);
uv_poll_init_socket(get_task_manager(), &uvSocket, g_pkgRing.sock);
rcData.work_cb = pRecv;
rcData.after_work_cb = pClean;
uvSocket.data = &rcData;
uv_poll_start(&uvSocket, UV_READABLE, raw_sock_recv_cb);
uv_timer_init(get_task_manager(), &uvTm);
uv_timer_start(&uvTm, socket_send_task, 3000, 100);
}
int dhcpd_init() {
int ret; int ret;
size_t size = MAX_PATH; size_t size = MAX_PATH;
@ -735,11 +691,11 @@ int dhcpd_init() {
get_nic_info(g_nicInfo.pIfName, &g_nicInfo.ipAddr, &g_nicInfo.netmask, NULL, g_nicInfo.macAddr); get_nic_info(g_nicInfo.pIfName, &g_nicInfo.ipAddr, &g_nicInfo.netmask, NULL, g_nicInfo.macAddr);
init_filter(); init_filter("vlan and udp and port 67 and port 68");
ret = create_udp_socket(); ret = create_udp_raw_socket(g_nicInfo.pIfName);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Create receive RAW Socket Error\n"); LOG_MOD(error, ZLOG_MOD_DHCPD, "Create receive RAW Socket Error: %s(%d)\n", getErrorEnumNameString(-ret), ret);
return ret; return ret;
} }
@ -747,14 +703,25 @@ int dhcpd_init() {
dhcp_option_cfg_init(); dhcp_option_cfg_init();
dhcp_lease_init(); dhcp_lease_init();
uv_udp_init(get_task_manager(), &g_uvRawSockReq); init_raw_socket_poll(NULL, NULL);
uv_udp_open(&g_uvRawSockReq, g_pkgRing.sock);
return ERR_SUCCESS;
uv_poll_init_socket(get_task_manager(), &uvSocket, g_pkgRing.sock); }
uv_poll_start(&uvSocket, UV_READABLE, raw_sock_recv_cb);
int dhcp_uninit() {
uv_timer_init(get_task_manager(), &uvTm); unsigned int size = g_pkgRing.recv.tp_block_size * g_pkgRing.recv.tp_block_nr +
uv_timer_start(&uvTm, socket_send_task, 3000, 100); g_pkgRing.send.tp_block_size * g_pkgRing.send.tp_block_nr;
close(g_pkgRing.sock);
g_pkgRing.sock = -1;
if (g_pkgRing.tx) {
free(g_pkgRing.tx);
}
if (g_pkgRing.rx) {
free(g_pkgRing.rx);
}
munmap(g_pkgRing.map_recv, size);
return ERR_SUCCESS; return ERR_SUCCESS;
} }

View File

@ -0,0 +1,84 @@
//
// Created by xajhuang on 2023/4/20.
//
#ifndef VCPE_DHCP_NETWORK_H
#define VCPE_DHCP_NETWORK_H
#include <uv.h>
#include <linux/if_packet.h>
#include "network/vlan.h"
#include "service/dhcpd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAC_TO_STR(mac, str) \
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])
#define PKG_MMAP_BLOCKSIZ (1 << 22)
#define PKG_MMAP_FRAMESIZ (1 << 11)
#define PKG_MMAP_BLOCKNUM (64)
typedef struct {
int sock;
struct sockaddr_ll addr;
struct iovec *rx;
struct iovec *tx;
uint8_t *map_recv;
uint8_t *map_send;
struct tpacket_req3 recv;
struct tpacket_req3 send;
unsigned int index;
} PACKET_MMAP_RING, *PPACKET_MMAP_RING;
typedef struct {
char *pIfName;
U32 ipAddr;
U32 netmask;
U8 macAddr[ETH_ALEN];
S8 hostname[MAX_PATH];
} NIC_INFO, *PNIC_INFO;
struct block_desc {
uint32_t version;
uint32_t offset_to_priv;
struct tpacket_hdr_v1 h1;
};
typedef struct {
uv_work_cb work_cb;
uv_after_work_cb after_work_cb;
} RECV_CB_DATA, *PRECV_CB_DATA;
#pragma pack(1)
typedef struct {
VLAN_PKG_HDR vlan_hdr;
DHCP_PROTO dhcp;
} DHCP_PACKAGE, *PDHCP_PACKAGE;
typedef struct {
uv_work_t uvWork;
unsigned short nSize;
unsigned char *pPkgBase;
void *pData;
} PKG_PROCESS_INFO, *PPKG_PROCESS_INFO;
typedef struct {
unsigned int nf;
PPKG_PROCESS_INFO pPkgInfo;
} PKG_MSG, *PPKG_MSG;
#pragma pack()
void raw_sock_recv_cb(uv_poll_t *handle, int status, int events);
void socket_send_task(uv_timer_t *UNUSED(pArg));
void init_raw_socket_poll(void *pRecv, void *pClean);
int create_udp_raw_socket(const char *pNicName);
void init_filter(const char *pNetFilter);
void *get_pkg_free_buf();
U32 pkg_mmap_tx(U8 *pData, U32 nBytes);
int dhcp_uninit();
#ifdef __cplusplus
}
#endif
#endif //VCPE_DHCP_NETWORK_H

View File

@ -4,6 +4,7 @@
#ifndef VCPE_DHCP_OPTIONS_H #ifndef VCPE_DHCP_OPTIONS_H
#define VCPE_DHCP_OPTIONS_H #define VCPE_DHCP_OPTIONS_H
#include "common.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -0,0 +1,35 @@
//
// Created by xajhuang on 2023/4/20.
//
#ifndef VCPE_RFC2131_H
#define VCPE_RFC2131_H
#include <linux/if_ether.h>
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DHCP_COOKIE_VAL (0x63825363)
#define MAX_DHCP_PKG_SIZE (512)
#define VLAN_VNI_ID(x) ntohs((x))
#define DHCP_XID(x) ntohl((x))
#define DHCP_CLI_PORT (68)
#define DHCP_SVR_PORT (67)
typedef struct {
U8 unicast;
U8 cliMac[ETH_ALEN];
U32 xid;
U32 reqIpAddr;
U32 leaseTime;
char clientId[256];
char vendorClassId[256];
char hostName[256];
} DHCP_REQ, *PDHCP_REQ;
#ifdef __cplusplus
}
#endif
#endif //VCPE_RFC2131_H