我是靠谱客的博主 威武小白菜,最近开发中收集的这篇文章主要介绍VPP目的MAC检查,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

对于VPP三层接口,执行目的MAC检查。两个基本的宏掩码如下。由于MAC地址由48bit组成,对于u64的DMAC_MASK掩码,将余下的16bit设置为零。宏DMAC_IGBIT为MAC地址中单播/组播(Individual/Group)标志位。

#define DMAC_MASK clib_net_to_host_u64 (0xFFFFFFFFFFFF0000)
#define DMAC_IGBIT clib_net_to_host_u64 (0x0100000000000000)

比较函数如下,报文的目的MAC与接口的硬件地址不相等,并且目的MAC不是多播地址,认为目的MAC有误。

static_always_inline u8
is_dmac_bad (u64 dmac, u64 hwaddr)
{
u64 r0 = dmac & DMAC_MASK;
return (r0 != hwaddr) && ((r0 & DMAC_IGBIT) == 0);
}

对于接口的次要硬件地址,如果报文的目的MAC地址不等于次要硬件地址,即认为目的MAC有误。

static_always_inline u8
is_sec_dmac_bad (u64 dmac, u64 hwaddr)
{
return ((dmac & DMAC_MASK) != hwaddr);
}

报文DMAC检查如下,首先,检查报文的目的MAC地址与接口的主硬件地址,确定是否合法。对于两个报文做检查的情况,检查第二个报文的目的MAC地址是否合法。

static_always_inline void
ethernet_input_inline_dmac_check (vnet_hw_interface_t * hi,
u64 * dmacs, u8 * dmacs_bad,
u32 n_packets, ethernet_interface_t * ei,
u8 have_sec_dmac)
{
u64 hwaddr = ei->address.as_u64;
ASSERT (0 == ei->address.zero);
dmacs_bad[0] = is_dmac_bad (dmacs[0], hwaddr);
dmacs_bad[1] = ((n_packets > 1) & is_dmac_bad (dmacs[1], hwaddr));
bad = dmacs_bad[0] | dmacs_bad[1];

如果其中有一个(或者两个)报文的目的MAC地址不合法,并且接口还有次要硬件地址,遍历所有的次要硬件地址,检查报文DMAC的合法性。


if (PREDICT_FALSE (bad && have_sec_dmac))
{
ethernet_interface_address_t *sec_addr;
vec_foreach (sec_addr, ei->secondary_addrs)
{
ASSERT (0 == sec_addr->zero);
hwaddr = sec_addr->as_u64;
bad = (eth_input_sec_dmac_check_x1 (hwaddr, dmacs, dmacs_bad) |
eth_input_sec_dmac_check_x1 (hwaddr, dmacs + 1, dmacs_bad + 1));
if (!bad)
return;
}
}

如下调用的次要DMAC检查,如果报文DMAC合法,对于之前的非法MAC判定,以下的位与操作将修正为合法。

static_always_inline u8
eth_input_sec_dmac_check_x1 (u64 hwaddr, u64 * dmac, u8 * dmac_bad)
{
dmac_bad[0] &= is_sec_dmac_bad (dmac[0], hwaddr);
return dmac_bad[0];
}

最后

以上就是威武小白菜为你收集整理的VPP目的MAC检查的全部内容,希望文章能够帮你解决VPP目的MAC检查所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部