移植说明
链路层分析
输入输出接口实现
链路层分析
struct ifnet ifp;
uint8_t lla[ETHER_ADDR_LEN];
void ether_ifattach(struct ifnet *ifp, const u_int8_t *lla);
接收实现
参考f-stack实现
static void
ff_veth_init(void *arg)
{
struct ff_veth_softc *sc = arg;
struct ifnet *ifp = sc->ifp;
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static int
ff_veth_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
int error = 0;
struct ff_veth_softc *sc = ifp->if_softc;
switch (cmd) {
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
ff_veth_init(sc);
} else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ff_veth_stop(sc);
break;
default:
error = ether_ioctl(ifp, cmd, data);
break;
}
return (error);
}
static int
ff_veth_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct ff_veth_softc *sc = (struct ff_veth_softc *)ifp->if_softc;
return ff_dpdk_if_send(sc->host_ctx, (void*)m, m->m_pkthdr.len);
}
static void
ff_veth_qflush(struct ifnet *ifp)
{
}
void demo_veth_set_interface()
{
struct ifnet *ifp;
ifp = sc->ifp = if_alloc(IFT_ETHER);
ifp->if_init = ff_veth_init;
ifp->if_softc = sc;
if_initname(ifp, sc->host_ifname, IF_DUNIT_NONE);
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = ff_veth_ioctl;
ifp->if_start = ff_veth_start;
ifp->if_transmit = ff_veth_transmit;
ifp->if_qflush = ff_veth_qflush;
ether_ifattach(ifp, sc->mac);
}
发送实现
void
ff_veth_process_packet(void *arg, void *m)
{
struct ifnet *ifp = (struct ifnet *)arg;
struct mbuf *mb = (struct mbuf *)m;
mb->m_pkthdr.rcvif = ifp;
ifp->if_input(ifp, mb);
}
需要注册一个ifnet
结构体与mac地址到ether_ifattach
仿真程序
SOCKET RAW
// socket
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain | AF_UNIX, 本地通讯: | unix(7) | unix(7) | |—-| —- | — | | AF_INET | IPv4 网络协议 | ip(7)| | AF_INET6 | IPv6 网络协议 | ipv6(7)| | AF_IPX | IPX - Novell 协议 | | | AF_NETLINK | 内核用户界面设备 | netlink(7)| | AF_X25 | ITU-T X.25 / ISO-8208 协议 | x25(7)| | AF_AX25 | Amateur radio AX.25 protocol || | AF_ATMPVC | Access to raw ATM PVCs || | AF_APPLETALK | Appletalk | ddp(7)| | AF_PACKET | 底层包连接 | packet(7)|
type
SOCK_STREAM 提供有序的,可靠的,双向的,基于字节流的通讯。可能支持带外传输。
SOCK_DGRAM 提供数据报(不面向连接的, 不可靠的固定最大长度的信息)。
SOCK_SEQPACKET 提供有序的,可靠的,双向的,基于固定最大长度的数据报传输路径;需要一个读取整个伴有输入系统调用的包的用户。
SOCK_RAW 提供未加工(raw)的网络协议通道。
SOCK_RDM 提供可靠的数据报层,但是不保证顺序。
SOCK_PACKET 废弃的,不应该在新的程序中使用,参考 packet(7)。
SOCK_NONBLOCK 设置 O_NONBLOCK 的标志于新打开的文件描述符
SOCK_CLOEXEC 设置 close-on-exec (FD_CLOEXEC) 的标志于新打开的文件描述符
例子实现
socket(AF_INET, SOCK_RAW, IPPROTO_XXX); // 网络层IP数据包
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_XXX)); // 数据链路层数据帧