This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
At Thu, 14 Oct 2004 22:28:37 -0700,
Ulrich Drepper <drepper@redhat.com> wrote:
> > The current getifaddrs() doesn't set correct sin6_scope_id value.
> > (You can verify it by using getnameinfo().)
>
> That is not enough explanation. Provide some code which shows the
> program and point to the specification which supports your claim that
> there is something wrong.
OK, I attached test code to this mail.
================================================================
On current glibc, this test program outputs bellow.
% ./v6scopeid
(snipped)
------
Interface: eth1
Address: [fe80::208:dff:fee7:f4f7%253] <--- (A)
------ ^^^
On my patch applied glibc, this test program outputs bellow.
(snipped)
------
Interface: eth1
Address: [fe80::208:dff:fee7:f4f7%eth1] <--- (A')
------ ^^^^
Both fields (A) and (A') are displayed via getnameinfo().
================================================================
1. getnameinfo() presumes that sin6_scope_id member of struct
sockaddr_in6 is interface index.
Please see getnameinfo() in libc/inet/getnameinfo.c nearby line#311-:
if (sa->sa_family == AF_INET6)
{
const struct sockaddr_in6 *sin6p;
uint32_t scopeid;
(snipped)
scopeid = sin6p->sin6_scope_id;
if (scopeid != 0)
{
/* Buffer is >= IFNAMSIZ+1. */
char scopebuf[IFNAMSIZ + 1];
char *scopeptr;
int ni_numericscope = 0;
size_t real_hostlen = __strnlen (host, hostlen);
size_t scopelen = 0;
scopebuf[0] = SCOPE_DELIMITER;
scopebuf[1] = '\0';
scopeptr = &scopebuf[1];
if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
|| IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr))
{
if (if_indextoname (scopeid, scopeptr) == NULL) <= presumes scopde is index
++ni_numericscope;
else
scopelen = strlen (scopebuf);
}
2. and also linux kernel set interface index to ifa_index member of struct ifaddrmsg.
LINUX_KERNEL_SOURCE/net/ipv6/addrconf.c: inet6_fill_ifaddr()
(kernel 2.6.8.1)
static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
u32 pid, u32 seq, int event)
{
struct ifaddrmsg *ifm;
struct nlmsghdr *nlh;
struct ifa_cacheinfo ci;
unsigned char *b = skb->tail;
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
ifm = NLMSG_DATA(nlh);
ifm->ifa_family = AF_INET6;
ifm->ifa_prefixlen = ifa->prefix_len;
ifm->ifa_flags = ifa->flags;
ifm->ifa_scope = RT_SCOPE_UNIVERSE;
if (ifa->scope&IFA_HOST)
ifm->ifa_scope = RT_SCOPE_HOST;
else if (ifa->scope&IFA_LINK)
ifm->ifa_scope = RT_SCOPE_LINK;
else if (ifa->scope&IFA_SITE)
ifm->ifa_scope = RT_SCOPE_SITE;
ifm->ifa_index = ifa->idev->dev->ifindex; <= sets interface index here
(snipped)
}
3. In the IETF internet-draft draft-ietf-ipv6-scoping-arch-02.txt:
(This document is in IESG working queue to publish as RFC.)
11.3 Examples
(snipped)
If we use interface names as <zone_id>, those addresses could also be
represented as follows:
fe80::1234%ne0
ff02::5678%pvc1.3
ff08::9abc%interface10
where the interface "ne0" belongs to the 1st link, "pvc1.3" belongs
to the 5th link, and "interface10" belongs to the 10th organization.
Regards,
-mk
Attachment:
v6scopeid.c
Description: Binary data
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |