OCT 1. 拆分DHCP服务代码,供其它模块调用
This commit is contained in:
parent
4eeb3e6b99
commit
ff887e21e3
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#ifndef VCPE_DHCP_OPTIONS_H
|
||||
#define VCPE_DHCP_OPTIONS_H
|
||||
#include "common.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue