diff --git a/lib/if.c b/lib/if.c index f003754ad036..30de6805ce65 100644 --- a/lib/if.c +++ b/lib/if.c @@ -1,3 +1,4 @@ + /* * Interface functions. * Copyright (C) 1997, 98 Kunihiro Ishiguro @@ -46,6 +47,52 @@ struct if_master int (*if_delete_hook) (struct interface *); } if_master; +/* Compare interface names */ +int +if_cmp_func (struct interface *ifp1, struct interface *ifp2) +{ + unsigned int l1, l2; + long int x1, x2; + char *p1, *p2; + int res; + + p1 = ifp1->name; + p2 = ifp2->name; + + while (1) { + /* look up to any number */ + l1 = strcspn(p1, "0123456789"); + l2 = strcspn(p2, "0123456789"); + + /* name lengths are different -> compare names */ + if (l1 != l2) + return (strcmp(p1, p2)); + + res = strncmp(p1, p2, l1); + + /* names are different -> compare them */ + if (res) + return res; + + /* with identical name part, go to numeric part */ + + p1 += l1; + p2 += l1; + + x1 = strtol(p1, &p1, 10); + x2 = strtol(p2, &p2, 10); + + /* let's compare numbers now */ + if (x1 < x2) + return -1; + if (x1 > x2) + return 1; + + /* numbers were equal, lets do it again.. + (it happens with name like "eth123.456:789") */ + } +} + /* Create new interface structure. */ struct interface * if_new () @@ -58,13 +105,17 @@ if_new () } struct interface * -if_create () +if_create (char *name, int namelen) { struct interface *ifp; ifp = if_new (); - listnode_add (iflist, ifp); + assert (name); + assert (namelen <= (INTERFACE_NAMSIZ + 1)); + strncpy (ifp->name, name, namelen); + ifp->name[INTERFACE_NAMSIZ] = '\0'; + listnode_add_sort (iflist, ifp); ifp->connected = list_new (); ifp->connected->del = (void (*) (void *)) connected_free; @@ -248,10 +299,7 @@ if_get_by_name (char *name) ifp = if_lookup_by_name (name); if (ifp == NULL) - { - ifp = if_create (); - strncpy (ifp->name, name, IFNAMSIZ); - } + ifp = if_create (name, INTERFACE_NAMSIZ); return ifp; } @@ -430,10 +478,7 @@ DEFUN (interface, ifp = if_lookup_by_name (argv[0]); if (ifp == NULL) - { - ifp = if_create (); - strncpy (ifp->name, argv[0], INTERFACE_NAMSIZ); - } + ifp = if_create (argv[0], INTERFACE_NAMSIZ); vty->index = ifp; vty->node = INTERFACE_NODE; @@ -803,8 +848,10 @@ if_init () iflist = list_new (); ifaddr_ipv4_table = route_table_init (); - if (iflist) + if (iflist) { + iflist->cmp = (int (*)(void *, void *))if_cmp_func; return; + } memset (&if_master, 0, sizeof if_master); } diff --git a/lib/if.h b/lib/if.h index 9ffe74cfbf50..3fbeed9a8fa7 100644 --- a/lib/if.h +++ b/lib/if.h @@ -180,8 +180,9 @@ struct connected #endif /* IFF_LINK2 */ /* Prototypes. */ +int if_cmp_func (struct interface *, struct interface *); struct interface *if_new (void); -struct interface *if_create (void); +struct interface *if_create (char *name, int namelen); struct interface *if_lookup_by_index (unsigned int); struct interface *if_lookup_by_name (char *); struct interface *if_lookup_exact_address (struct in_addr); diff --git a/lib/zclient.c b/lib/zclient.c index bb7747fae9f4..bba06ee4be39 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -555,10 +555,7 @@ zebra_interface_add_read (struct stream *s) /* If such interface does not exist, make new one. */ if (! ifp) - { - ifp = if_create (); - strncpy (ifp->name, ifname_tmp, IFNAMSIZ); - } + ifp = if_create (ifname_tmp, INTERFACE_NAMSIZ); /* Read interface's index. */ ifp->ifindex = stream_getl (s); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 8fa3fd6305ff..067d551debf0 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -745,7 +745,8 @@ ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data) if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_vl_new(): creating pseudo zebra interface"); - vi = if_create (); + snprintf (ifname, INTERFACE_NAMSIZ + 1, "VLINK%d", vlink_count); + vi = if_create (ifname, INTERFACE_NAMSIZ); co = connected_new (); co->ifp = vi; listnode_add (vi->connected, co); @@ -769,10 +770,9 @@ ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data) voi->ifp->mtu = OSPF_VL_MTU; voi->type = OSPF_IFTYPE_VIRTUALLINK; - sprintf (ifname, "VLINK%d", vlink_count++); + vlink_count++; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_vl_new(): Created name: %s", ifname); - strncpy (vi->name, ifname, IFNAMSIZ); if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_vl_new(): set if->name to %s", vi->name); diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 952731593648..05eec596d817 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -219,9 +219,8 @@ ifm_read (struct if_msghdr *ifm) return -1; } - ifp = if_create (); + ifp = if_create (sdl->sdl_data, sdl->sdl_nlen); - strncpy (ifp->name, sdl->sdl_data, sdl->sdl_nlen); ifp->ifindex = ifm->ifm_index; ifp->flags = ifm->ifm_flags; #if defined(__bsdi__)