gpt4 book ai didi

c - Linux IPv6 源地址选择,当接口(interface)有 >1 个 IPv6 地址 : How to deprecate one?

转载 作者:太空狗 更新时间:2023-10-29 12:23:37 24 4
gpt4 key购买 nike

在 Linux 中为传出流量选择 IPv6 源地址的上下文中:

我在接口(interface)上有一些 IPv6 地址。我希望内核选择其中一个作为源 IPv6 地址。我不希望内核选择我将要发送的这个地址作为传出数据包的源地址。

更具体地说,在这个片段中,当 dontUseAsSourceAddressForOutgoingPkts 为真时,我希望内核选择已经在此接口(interface)上的任何其他 IPv6 地址。哪些标志会产生这种效果?如果我为 IPv6 寻址使用了错误的 ifaddrmsg 结构,我应该使用哪一个?

包含更多上下文的片段:

int
NetLnkSock::IpAdd(const std::string &ifname,
const IpAddr &ipaddr,
int prefixlen,
bool dontUseAsSourceAddressForOutgoingPkts)
ifreq ifr;
nlmsghdr *nlh;
ifaddrmsg *ifa;
nlmsgerr *nlerr;
static uint32_t msg_seq = 0;
NlSock nlsock;
LogDev::Ostream logostr;

nlsock.bind();
memset(&ifr, 0, sizeof(ifr));

if (ifname.size() > IFNAMSIZ)
throw NetLnkNameErr();

copy(ifname.begin(), ifname.end(), ifr.ifr_name);
ifr.ifr_name[ifname.end() - ifname.begin()] = '\0';

nlh = (nlmsghdr *)rcvbuf;

nlh->nlmsg_len = sizeof(nlmsghdr);

nlh->nlmsg_type = RTM_NEWADDR;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;

nlh->nlmsg_seq = ++msg_seq;
nlh->nlmsg_pid = 0;

ifa = (ifaddrmsg *)&nlh[1];
ifa->ifa_family = (ipaddr.is_v4()) ? AF_INET : AF_INET6;
ifa->ifa_prefixlen = prefixlen;
/*
* My question is about the behavior of the kernel
* vis a vis source address selection for outgoing traffic
* where there are multiple IP's on this interface.
* How do the flags below impact the kernel's choice
* for source address selection?
*/
ifa->ifa_flags =
(dontUseAsSourceAddressForOutgoingPkts && ipaddr.is_v6()) ?
(IFA_F_SECONDARY | IFA_F_DEPRECATED) : 0;
/*
* I would like for the kernel to select any other IPv6
* address already on this interface when
* dontUseAsSourceAddressForOutgoingPkts is true.
* Will these flags yield that effect?
*/
ifa->ifa_scope = RT_SCOPE_UNIVERSE;
ifa->ifa_index = ifr.ifr_ifindex;
nlh->nlmsg_len += sizeof(ifaddrmsg);
if (ipaddr.is_v4()) {
IpAddr ip4_bcast;
char *buf = rcvbuf + nlh->nlmsg_len;

ip4_bcast.create_netmask(prefixlen, ipaddr);
ip4_bcast.from_v4(~ip4_bcast.get_v4() | ipaddr.get_v4());

nlh->nlmsg_len += NLMSG_ALIGN(setRtAttr(buf, IFA_LOCAL,
&ipaddr.get_v4(), sizeof(in_addr_t)));

/*
* Always send the netmask and broadcast even on delete.
* Linux seems to ignore the prefixlen set in the original
* message and simply matches by ip address on deletes.
*/
buf = rcvbuf + nlh->nlmsg_len;
nlh->nlmsg_len += NLMSG_ALIGN(setRtAttr(buf, IFA_ADDRESS,
&ipaddr.get_v4(), sizeof(in_addr_t)));

buf = rcvbuf + nlh->nlmsg_len;
nlh->nlmsg_len += NLMSG_ALIGN(setRtAttr(buf, IFA_BROADCAST,
&ip4_bcast.get_v4(), sizeof(in_addr_t)));


} else { /* AF_INET6 */
char *buf = rcvbuf + nlh->nlmsg_len;

buf = rcvbuf + nlh->nlmsg_len;
if (ipaddr.domain() != RD_DEFAULT_ID) { // Hal doesn't support route domains
throw NetLnkIpAddrErr();
}
nlh->nlmsg_len += NLMSG_ALIGN(setRtAttr(buf, IFA_LOCAL,
&ipaddr.get_v6(), sizeof(in6_addr)));
buf = rcvbuf + nlh->nlmsg_len;
nlh->nlmsg_len += NLMSG_ALIGN(setRtAttr(buf, IFA_ADDRESS,
&ipaddr.get_v6(), sizeof(in6_addr)));

}
nlsock.sendNlReq(rcvbuf);
}

最佳答案

RFC 3484状态:

  1. 源地址选择

    <...>

    规则 3:避免使用已弃用的地址。地址 SA 和 SB 具有相同的范围。如果两者之一源地址是“首选”,其中之一是“弃用”(在RFC 2462 意义上的),然后选择“首选”的那个。

    <...>

rtnetlink(7) man pages简要提及一个名为 ifa_cacheinfo 的结构。

This struct包含两个重要的标志:ifa_valid 和 ifa_prefered。为了将 IPv6 地址标记为已弃用,请将其 prefered_lft 设置为零。此外,通常也将 valid_lft 设置为 0xffffffff(永远)以强调此 IPv6 地址已明确弃用的性质。 p>

/* 
* You have just put a new IPv6 address on the kernel with
* net link. You don't want it chosen as the source address
* of packets leaving this interface if there's at least one
* other IPv6 address already on this interface.
*
* Mark this IPv6 address as Deprecated on this interface,
* Causing LINUX not to choose it for source address of
* packets outgoing from this interface when there exists
* another, non-deprecated IPv6 address on this interface
*/
struct ifa_cacheinfo ci;
// This address is valid forever
ci.ifa_valid = 0xffffffff;
// A prefered ttl of 0 immediately deprecates this IPv6
ci.ifa_preferred = 0;
// <Send this cacheinfo to the kernel using net link>

关于c - Linux IPv6 源地址选择,当接口(interface)有 >1 个 IPv6 地址 : How to deprecate one?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50051836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com