netlink套接字主要用于同一PC用户进程与kernel之间的通信。
AF_INET套接字主要用于PC与PC间的通信。
netlink套接字可以使用标准的套接字APIs来创建。socket(), bind(), sendmsg(), recvmsg()和close(),很容易地应用到netlink socket。
netlink标准接口包含于头文件linux/netlink.h中
CPU网口收发任务初始化
struct socketaddr_nl{
sa_family_t nl_family; //AF_NETLINK
unsigned short nl_pad; //填充0
pid_t nl_pid; //进程pid
u_32 nl_groups //多播组
}nl;
struct msghdr{
void *msg_name;
int msg_namelen;
struct iovec *msg_iov;
_kernel_size_t msg_iovlen;
void *msg_control;
_kernel_size_t msg_controllen;
unsigned msg_flags
};
收包进程:
int sock_rfd; //套接字描述符
void RxPktTask(void)
{
struct socketaddr_nl src_addr;
int RecPktId;
sock_rfd = socket(PF_NETLINK, sock_RAW, NETLINK_COMTO_KERNEL);
if(0 == sock_rfd)
{
printf("create RxPktTask socket fail\n");
}
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = NETLINK_PID;
src_addr.nl_groups = 0;
//将套接字绑定到一个已知的地址上
bind(sock_rfd, (struct socketaddr_nl*)src_addr, sizeof(src_addr));
RecPktId = taskSpawn("DX107RecPkt",50,0,0x2000,(FUNCPTR)DX107RecPktTask);
if(0 == RecPktId)
{
printf("DX107RecPktId Creation error!\n\r");
return;
}
}
void DX107RecPktTask(void)
{
int size;
struct iovec iov;
struct msghdr msg;
UINT8 mem[2048];
memset(&msg, 0, sizeof(struct msghdr));
iov.iov_base = (void*)mem;
iov.iov_len = MAX_PAYLOAD;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
while(1)
{
//谁发包都可以将其唤醒
size = recvmsg(sock_rfd, &msg, 0);
if(size > 0 && size < 2048)
{
hwRxPktProcess(mem, (UINT32)size);
}
else
{
printf("\n %s%d the size of pkt received from bsp is %d, error = %d, errorNo = %s\n",
__FUNCTION__, __LINE__, size, errno, strerror(errno));
}
}
}
发包进程:
int sock_tfd;
struct socketaddr_nl dest_addr;
void TxPktInit(void)
{
sock_tfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_COMTO_KERNEL);
if(0 == sock_tfd)
{
printf("create TxPktTask socket fail\n");
}
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0;
dest_addr.nl_groups = 0;
bind(sock_tfd, (struct socketaddr_nl*)&dest_addr, sizeof(dest_addr));
}
void DX107TxPktToBSP(UINT8 *packet, UINT16 length)
{
struct msghdr msg;
struct iovec iov;
int size;
memset(&msg, 0, sizeof(msg));
iov.iov_base = (void *)packet;
iov.lov_len = length;
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
size = sendmsg(sock_tfd, &msg, 0);
if(size < 0)
{
printf("\n DX107 tx pkt task send msg to bsp fail!\n");
}
return;
}