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:")
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")
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 ()
ELSE ()
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);
unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned char *pUdp);
unsigned short ip_checksum(unsigned char *pIp);
int string_mac_to_bytes(const char *pStrMac, unsigned char macByte[6]);
#ifdef __cplusplus
}
#endif

View File

@ -18,6 +18,7 @@
#include "misc.h"
#include "zlog_module.h"
#include "common.h"
#include "sds/sds.h"
PSYS_NIC_INFO g_sysNicInfo = NULL;
@ -309,7 +310,7 @@ int get_all_network_info(PSYS_NIC_INFO pInfo) {
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);
@ -415,4 +416,31 @@ unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned cha
csum = ((csum & 0xFFFF0000) >> 16) + (csum & 0xFFFF);
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 "dhcp_options.h"
#include "user_errno.h"
#include "zlog_module.h"
static const DHCP_OPTION_CFG g_opCfg[] = {
// region DHCP optinos configure table

View File

@ -1,96 +1,27 @@
//
// Created by xajhuang on 2023/3/16.
//
#include <uv.h>
#include <stdlib.h>
#include <string.h>
#include <linux/filter.h>
#include <linux/if_packet.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <pcap/pcap.h>
#include <unistd.h>
#include "service/dhcpd.h"
#include "user_errno.h"
#include "task_manager.h"
#include "zlog_module.h"
#include "network/vlan.h"
#include "dhcp_options.h"
#include "config.h"
#include "misc.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 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()
#define MAXIMUM_SNAPLEN (262144)
/*
TORs (Top of Rack switch) at Facebook run DHCP relayers, these relayers are
@ -219,7 +150,7 @@ static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo;
static uv_udp_t g_uvRawSockReq;
void *get_pkg_memory() {
void *get_pkg_free_buf() {
int i;
ssize_t ret;
struct tpacket3_hdr *hdr;
@ -250,7 +181,7 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
U8 *pOpt;
U16 csum;
int tolSize;
PDHCP_PACKAGE pRsp = get_pkg_memory();
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
if (pRsp == NULL) {
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) {
static unsigned int block_num = 0;
PRECV_CB_DATA pCbData = handle->data;
if (status >= 0 && (events & UV_READABLE)) {
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].pData = pMsg;
uv_queue_work(get_task_manager(), &(pMsg->pPkgInfo[i].uvWork), on_sock_recv, after_msg_recv);
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);
}
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;
unsigned int size;
int i;
@ -660,7 +600,7 @@ static int create_udp_socket() {
// 9. bind socket
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_protocol = htons(ETH_P_ALL);
addr.sll_hatype = 0;
@ -677,7 +617,7 @@ static int create_udp_socket() {
return ERR_SUCCESS;
}
static void socket_send_task(uv_timer_t *UNUSED(pArg)) {
void socket_send_task(uv_timer_t *UNUSED(pArg)) {
int i;
struct tpacket3_hdr *hdr;
@ -694,21 +634,20 @@ static void socket_send_task(uv_timer_t *UNUSED(pArg)) {
}
}
void init_filter() {
void init_filter(const char *pNetFilter) {
#ifdef USED_DEFAULT_BPF
bpf.len = sizeof(g_filterCode) / (sizeof(struct sock_filter));
bpf.filter = g_filterCode;
#else
static pcap_t *pd;
pd = pcap_open_dead(DLT_EN10MB, MAXIMUM_SNAPLEN);
struct bpf_program fcode;
char *cmd_buf = "vlan and udp and port 67 and port 68";
pcap_compile(pd, &fcode, cmd_buf, 1, 0);
//char *cmd_buf = "vlan and udp and port 67 and port 68";
pcap_compile(pd, &fcode, pNetFilter, 1, 0);
struct bpf_insn *insn = fcode.bf_insns;
struct sock_filter *g_filters = (struct sock_filter *)malloc(fcode.bf_len * sizeof (struct sock_filter));
for (int i = 0; i < fcode.bf_len; ++insn, ++i){
struct bpf_insn *insn = fcode.bf_insns;
struct sock_filter *g_filters = (struct sock_filter *)malloc(fcode.bf_len * sizeof(struct sock_filter));
for (int i = 0; i < fcode.bf_len; ++insn, ++i) {
g_filters[i].code = insn->code;
g_filters[i].jt = insn->jt;
g_filters[i].jf = insn->jf;
@ -723,11 +662,28 @@ void init_filter() {
#endif
}
void init_raw_socket_poll(void *pRecv, void *pClean) {
static RECV_CB_DATA rcData;
static uv_poll_t uvSocket;
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() {
static uv_poll_t uvSocket;
static uv_timer_t uvTm;
int ret;
size_t size = MAX_PATH;
int ret;
size_t size = MAX_PATH;
memset(&g_nicInfo, 0, sizeof(NIC_INFO));
g_nicInfo.pIfName = (char *)config_get_dhcp_nic_name();
@ -735,11 +691,11 @@ int dhcpd_init() {
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) {
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;
}
@ -747,14 +703,25 @@ int dhcpd_init() {
dhcp_option_cfg_init();
dhcp_lease_init();
uv_udp_init(get_task_manager(), &g_uvRawSockReq);
uv_udp_open(&g_uvRawSockReq, g_pkgRing.sock);
init_raw_socket_poll(NULL, NULL);
uv_poll_init_socket(get_task_manager(), &uvSocket, g_pkgRing.sock);
uv_poll_start(&uvSocket, UV_READABLE, raw_sock_recv_cb);
return ERR_SUCCESS;
}
uv_timer_init(get_task_manager(), &uvTm);
uv_timer_start(&uvTm, socket_send_task, 3000, 100);
int dhcp_uninit() {
unsigned int size = g_pkgRing.recv.tp_block_size * g_pkgRing.recv.tp_block_nr +
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;
}

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
#define VCPE_DHCP_OPTIONS_H
#include "common.h"
#ifdef __cplusplus
extern "C" {
#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