mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 12:53:26 +00:00
Merge pull request #5535 from opensourcerouting/santa-elf
*: cleanup elves were here
This commit is contained in:
commit
04dd9e420e
4
.gitignore
vendored
4
.gitignore
vendored
@ -33,6 +33,10 @@
|
|||||||
/Makefile
|
/Makefile
|
||||||
/Makefile.in
|
/Makefile.in
|
||||||
|
|
||||||
|
/symalyzer_report.html
|
||||||
|
/jquery-3.4.1.min.js
|
||||||
|
/jquery-3.4.1.min.js.tmp
|
||||||
|
|
||||||
### autoconf/automake subdir stuff
|
### autoconf/automake subdir stuff
|
||||||
|
|
||||||
.deps
|
.deps
|
||||||
|
@ -199,14 +199,6 @@ bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c
|
|||||||
bgpd_bgpd_CFLAGS = $(AM_CFLAGS)
|
bgpd_bgpd_CFLAGS = $(AM_CFLAGS)
|
||||||
bgpd_bgp_btoa_CFLAGS = $(AM_CFLAGS)
|
bgpd_bgp_btoa_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
if ENABLE_BGP_VNC
|
|
||||||
bgpd_bgpd_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c
|
|
||||||
bgpd_bgpd_CFLAGS += -Irfapi -I@top_srcdir@/$(RFPINC)
|
|
||||||
|
|
||||||
bgpd_bgp_btoa_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c
|
|
||||||
bgpd_bgp_btoa_CFLAGS += -Irfapi -I@top_srcdir@/$(RFPINC)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am
|
# RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am
|
||||||
bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM)
|
bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM)
|
||||||
bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM)
|
bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM)
|
||||||
|
@ -41,7 +41,7 @@ static void agg_node_destroy(route_table_delegate_t *delegate,
|
|||||||
XFREE(MTYPE_TMP, anode);
|
XFREE(MTYPE_TMP, anode);
|
||||||
}
|
}
|
||||||
|
|
||||||
route_table_delegate_t agg_table_delegate = {
|
static route_table_delegate_t agg_table_delegate = {
|
||||||
.create_node = agg_node_create,
|
.create_node = agg_node_create,
|
||||||
.destroy_node = agg_node_destroy,
|
.destroy_node = agg_node_destroy,
|
||||||
};
|
};
|
||||||
|
@ -114,12 +114,6 @@ char *buffer_getstr(struct buffer *b)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 if buffer is empty. */
|
|
||||||
int buffer_empty(struct buffer *b)
|
|
||||||
{
|
|
||||||
return (b->head == NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear and free all allocated data. */
|
/* Clear and free all allocated data. */
|
||||||
void buffer_reset(struct buffer *b)
|
void buffer_reset(struct buffer *b)
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,7 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
|
|||||||
. {return yytext[0];}
|
. {return yytext[0];}
|
||||||
%%
|
%%
|
||||||
|
|
||||||
YY_BUFFER_STATE buffer;
|
static YY_BUFFER_STATE buffer;
|
||||||
|
|
||||||
void set_lexer_string (yyscan_t *scn, const char *string)
|
void set_lexer_string (yyscan_t *scn, const char *string)
|
||||||
{
|
{
|
||||||
|
@ -2498,8 +2498,8 @@ DEFUN (no_ipv6_access_list_remark_comment,
|
|||||||
return no_ipv6_access_list_remark(self, vty, argc, argv);
|
return no_ipv6_access_list_remark(self, vty, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void config_write_access_zebra(struct vty *, struct filter *);
|
static void config_write_access_zebra(struct vty *, struct filter *);
|
||||||
void config_write_access_cisco(struct vty *, struct filter *);
|
static void config_write_access_cisco(struct vty *, struct filter *);
|
||||||
|
|
||||||
/* show access-list command. */
|
/* show access-list command. */
|
||||||
static int filter_show(struct vty *vty, const char *name, afi_t afi)
|
static int filter_show(struct vty *vty, const char *name, afi_t afi)
|
||||||
@ -2685,7 +2685,7 @@ DEFUN (show_ipv6_access_list_name,
|
|||||||
return filter_show(vty, argv[idx_word]->arg, AFI_IP6);
|
return filter_show(vty, argv[idx_word]->arg, AFI_IP6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void config_write_access_cisco(struct vty *vty, struct filter *mfilter)
|
static void config_write_access_cisco(struct vty *vty, struct filter *mfilter)
|
||||||
{
|
{
|
||||||
struct filter_cisco *filter;
|
struct filter_cisco *filter;
|
||||||
|
|
||||||
@ -2724,7 +2724,7 @@ void config_write_access_cisco(struct vty *vty, struct filter *mfilter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void config_write_access_zebra(struct vty *vty, struct filter *mfilter)
|
static void config_write_access_zebra(struct vty *vty, struct filter *mfilter)
|
||||||
{
|
{
|
||||||
struct filter_zebra *filter;
|
struct filter_zebra *filter;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
@ -206,7 +206,7 @@ void rcu_thread_unprepare(struct rcu_thread *rt)
|
|||||||
rcu_bump();
|
rcu_bump();
|
||||||
if (rt != &rcu_thread_main)
|
if (rt != &rcu_thread_main)
|
||||||
/* this free() happens after seqlock_release() below */
|
/* this free() happens after seqlock_release() below */
|
||||||
rcu_free_internal(&_mt_RCU_THREAD, rt, rcu_head);
|
rcu_free_internal(MTYPE_RCU_THREAD, rt, rcu_head);
|
||||||
|
|
||||||
rcu_threads_del(&rcu_threads, rt);
|
rcu_threads_del(&rcu_threads, rt);
|
||||||
seqlock_release(&rt->rcu);
|
seqlock_release(&rt->rcu);
|
||||||
@ -269,7 +269,7 @@ static void rcu_bump(void)
|
|||||||
* "last item is being deleted - start over" case, and then we may end
|
* "last item is being deleted - start over" case, and then we may end
|
||||||
* up accessing old RCU queue items that are already free'd.
|
* up accessing old RCU queue items that are already free'd.
|
||||||
*/
|
*/
|
||||||
rcu_free_internal(&_mt_RCU_NEXT, rn, head_free);
|
rcu_free_internal(MTYPE_RCU_NEXT, rn, head_free);
|
||||||
|
|
||||||
/* Only allow the RCU sweeper to run after these 2 items are queued.
|
/* Only allow the RCU sweeper to run after these 2 items are queued.
|
||||||
*
|
*
|
||||||
|
@ -139,6 +139,8 @@ extern void rcu_enqueue(struct rcu_head *head, const struct rcu_action *action);
|
|||||||
#define rcu_free(mtype, ptr, field) \
|
#define rcu_free(mtype, ptr, field) \
|
||||||
do { \
|
do { \
|
||||||
typeof(ptr) _ptr = (ptr); \
|
typeof(ptr) _ptr = (ptr); \
|
||||||
|
if (!_ptr) \
|
||||||
|
break; \
|
||||||
struct rcu_head *_rcu_head = &_ptr->field; \
|
struct rcu_head *_rcu_head = &_ptr->field; \
|
||||||
static const struct rcu_action _rcu_action = { \
|
static const struct rcu_action _rcu_action = { \
|
||||||
.type = RCUA_FREE, \
|
.type = RCUA_FREE, \
|
||||||
|
@ -38,9 +38,9 @@ DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc")
|
|||||||
|
|
||||||
/** headers **/
|
/** headers **/
|
||||||
void grammar_sandbox_init(void);
|
void grammar_sandbox_init(void);
|
||||||
void pretty_print_graph(struct vty *vty, struct graph_node *, int, int,
|
static void pretty_print_graph(struct vty *vty, struct graph_node *, int, int,
|
||||||
struct graph_node **, size_t);
|
struct graph_node **, size_t);
|
||||||
void init_cmdgraph(struct vty *, struct graph **);
|
static void init_cmdgraph(struct vty *, struct graph **);
|
||||||
|
|
||||||
/** shim interface commands **/
|
/** shim interface commands **/
|
||||||
static struct graph *nodegraph = NULL, *nodegraph_free = NULL;
|
static struct graph *nodegraph = NULL, *nodegraph_free = NULL;
|
||||||
@ -491,8 +491,9 @@ void grammar_sandbox_init(void)
|
|||||||
* @param start the node to take as the root
|
* @param start the node to take as the root
|
||||||
* @param level indent level for recursive calls, always pass 0
|
* @param level indent level for recursive calls, always pass 0
|
||||||
*/
|
*/
|
||||||
void pretty_print_graph(struct vty *vty, struct graph_node *start, int level,
|
static void pretty_print_graph(struct vty *vty, struct graph_node *start,
|
||||||
int desc, struct graph_node **stack, size_t stackpos)
|
int level, int desc, struct graph_node **stack,
|
||||||
|
size_t stackpos)
|
||||||
{
|
{
|
||||||
// print this node
|
// print this node
|
||||||
char tokennum[32];
|
char tokennum[32];
|
||||||
@ -550,7 +551,7 @@ void pretty_print_graph(struct vty *vty, struct graph_node *start, int level,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** stuff that should go in command.c + command.h */
|
/** stuff that should go in command.c + command.h */
|
||||||
void init_cmdgraph(struct vty *vty, struct graph **graph)
|
static void init_cmdgraph(struct vty *vty, struct graph **graph)
|
||||||
{
|
{
|
||||||
// initialize graph, add start noe
|
// initialize graph, add start noe
|
||||||
*graph = graph_new();
|
*graph = graph_new();
|
||||||
|
2
lib/if.c
2
lib/if.c
@ -58,7 +58,7 @@ DEFINE_QOBJ_TYPE(interface)
|
|||||||
DEFINE_HOOK(if_add, (struct interface * ifp), (ifp))
|
DEFINE_HOOK(if_add, (struct interface * ifp), (ifp))
|
||||||
DEFINE_KOOH(if_del, (struct interface * ifp), (ifp))
|
DEFINE_KOOH(if_del, (struct interface * ifp), (ifp))
|
||||||
|
|
||||||
struct interface_master{
|
static struct interface_master{
|
||||||
int (*create_hook)(struct interface *ifp);
|
int (*create_hook)(struct interface *ifp);
|
||||||
int (*up_hook)(struct interface *ifp);
|
int (*up_hook)(struct interface *ifp);
|
||||||
int (*down_hook)(struct interface *ifp);
|
int (*down_hook)(struct interface *ifp);
|
||||||
|
@ -339,29 +339,6 @@ void list_delete_node(struct list *list, struct listnode *node)
|
|||||||
listnode_free(node);
|
listnode_free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_add_list(struct list *list, struct list *add)
|
|
||||||
{
|
|
||||||
struct listnode *n;
|
|
||||||
|
|
||||||
for (n = listhead(add); n; n = listnextnode(n))
|
|
||||||
listnode_add(list, n->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct list *list_dup(struct list *list)
|
|
||||||
{
|
|
||||||
struct list *new = list_new();
|
|
||||||
struct listnode *ln;
|
|
||||||
void *data;
|
|
||||||
|
|
||||||
new->cmp = list->cmp;
|
|
||||||
new->del = list->del;
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(list, ln, data))
|
|
||||||
listnode_add(new, data);
|
|
||||||
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
void list_sort(struct list *list, int (*cmp)(const void **, const void **))
|
void list_sort(struct list *list, int (*cmp)(const void **, const void **))
|
||||||
{
|
{
|
||||||
struct listnode *ln, *nn;
|
struct listnode *ln, *nn;
|
||||||
|
@ -207,17 +207,6 @@ extern struct listnode *listnode_lookup(struct list *list, const void *data);
|
|||||||
*/
|
*/
|
||||||
extern void *listnode_head(struct list *list);
|
extern void *listnode_head(struct list *list);
|
||||||
|
|
||||||
/*
|
|
||||||
* Duplicate a list.
|
|
||||||
*
|
|
||||||
* list
|
|
||||||
* list to duplicate
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* copy of the list
|
|
||||||
*/
|
|
||||||
extern struct list *list_dup(struct list *l);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sort a list in place.
|
* Sort a list in place.
|
||||||
*
|
*
|
||||||
@ -295,19 +284,6 @@ extern void list_delete_all_node(struct list *list);
|
|||||||
*/
|
*/
|
||||||
extern void list_delete_node(struct list *list, struct listnode *node);
|
extern void list_delete_node(struct list *list, struct listnode *node);
|
||||||
|
|
||||||
/*
|
|
||||||
* Append a list to an existing list.
|
|
||||||
*
|
|
||||||
* Runtime is O(N) where N = listcount(add).
|
|
||||||
*
|
|
||||||
* list
|
|
||||||
* list to append to
|
|
||||||
*
|
|
||||||
* add
|
|
||||||
* list to append
|
|
||||||
*/
|
|
||||||
extern void list_add_list(struct list *list, struct list *add);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete all nodes which satisfy a condition from a list.
|
* Delete all nodes which satisfy a condition from a list.
|
||||||
* Deletes the node if cond function returns true for the node.
|
* Deletes the node if cond function returns true for the node.
|
||||||
|
23
lib/memory.h
23
lib/memory.h
@ -102,45 +102,42 @@ struct memgroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_MTYPE(name) \
|
#define DECLARE_MTYPE(name) \
|
||||||
extern struct memtype _mt_##name; \
|
extern struct memtype MTYPE_##name[1]; \
|
||||||
extern struct memtype *const MTYPE_##name; \
|
|
||||||
/* end */
|
/* end */
|
||||||
|
|
||||||
#define DEFINE_MTYPE_ATTR(group, mname, attr, desc) \
|
#define DEFINE_MTYPE_ATTR(group, mname, attr, desc) \
|
||||||
attr struct memtype _mt_##mname \
|
attr struct memtype MTYPE_##mname[1] \
|
||||||
__attribute__((section(".data.mtypes"))) = { \
|
__attribute__((section(".data.mtypes"))) = { { \
|
||||||
.name = desc, \
|
.name = desc, \
|
||||||
.next = NULL, \
|
.next = NULL, \
|
||||||
.n_alloc = 0, \
|
.n_alloc = 0, \
|
||||||
.size = 0, \
|
.size = 0, \
|
||||||
.ref = NULL, \
|
.ref = NULL, \
|
||||||
}; \
|
} }; \
|
||||||
static void _mtinit_##mname(void) __attribute__((_CONSTRUCTOR(1001))); \
|
static void _mtinit_##mname(void) __attribute__((_CONSTRUCTOR(1001))); \
|
||||||
static void _mtinit_##mname(void) \
|
static void _mtinit_##mname(void) \
|
||||||
{ \
|
{ \
|
||||||
if (_mg_##group.insert == NULL) \
|
if (_mg_##group.insert == NULL) \
|
||||||
_mg_##group.insert = &_mg_##group.types; \
|
_mg_##group.insert = &_mg_##group.types; \
|
||||||
_mt_##mname.ref = _mg_##group.insert; \
|
MTYPE_##mname->ref = _mg_##group.insert; \
|
||||||
*_mg_##group.insert = &_mt_##mname; \
|
*_mg_##group.insert = MTYPE_##mname; \
|
||||||
_mg_##group.insert = &_mt_##mname.next; \
|
_mg_##group.insert = &MTYPE_##mname->next; \
|
||||||
} \
|
} \
|
||||||
static void _mtfini_##mname(void) __attribute__((_DESTRUCTOR(1001))); \
|
static void _mtfini_##mname(void) __attribute__((_DESTRUCTOR(1001))); \
|
||||||
static void _mtfini_##mname(void) \
|
static void _mtfini_##mname(void) \
|
||||||
{ \
|
{ \
|
||||||
if (_mt_##mname.next) \
|
if (MTYPE_##mname->next) \
|
||||||
_mt_##mname.next->ref = _mt_##mname.ref; \
|
MTYPE_##mname->next->ref = MTYPE_##mname->ref; \
|
||||||
*_mt_##mname.ref = _mt_##mname.next; \
|
*MTYPE_##mname->ref = MTYPE_##mname->next; \
|
||||||
} \
|
} \
|
||||||
/* end */
|
/* end */
|
||||||
|
|
||||||
#define DEFINE_MTYPE(group, name, desc) \
|
#define DEFINE_MTYPE(group, name, desc) \
|
||||||
DEFINE_MTYPE_ATTR(group, name, , desc) \
|
DEFINE_MTYPE_ATTR(group, name, , desc) \
|
||||||
struct memtype *const MTYPE_##name = &_mt_##name; \
|
|
||||||
/* end */
|
/* end */
|
||||||
|
|
||||||
#define DEFINE_MTYPE_STATIC(group, name, desc) \
|
#define DEFINE_MTYPE_STATIC(group, name, desc) \
|
||||||
DEFINE_MTYPE_ATTR(group, name, static, desc) \
|
DEFINE_MTYPE_ATTR(group, name, static, desc) \
|
||||||
static struct memtype *const MTYPE_##name = &_mt_##name; \
|
|
||||||
/* end */
|
/* end */
|
||||||
|
|
||||||
DECLARE_MGROUP(LIB)
|
DECLARE_MGROUP(LIB)
|
||||||
|
@ -51,7 +51,7 @@ static struct ns *ns_lookup_name_internal(const char *name);
|
|||||||
|
|
||||||
RB_GENERATE(ns_head, ns, entry, ns_compare)
|
RB_GENERATE(ns_head, ns, entry, ns_compare)
|
||||||
|
|
||||||
struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
|
static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
|
||||||
|
|
||||||
static struct ns *default_ns;
|
static struct ns *default_ns;
|
||||||
static int ns_current_ns_fd;
|
static int ns_current_ns_fd;
|
||||||
@ -74,7 +74,8 @@ static inline int ns_map_compare(const struct ns_map_nsid *a,
|
|||||||
RB_HEAD(ns_map_nsid_head, ns_map_nsid);
|
RB_HEAD(ns_map_nsid_head, ns_map_nsid);
|
||||||
RB_PROTOTYPE(ns_map_nsid_head, ns_map_nsid, id_entry, ns_map_compare);
|
RB_PROTOTYPE(ns_map_nsid_head, ns_map_nsid, id_entry, ns_map_compare);
|
||||||
RB_GENERATE(ns_map_nsid_head, ns_map_nsid, id_entry, ns_map_compare);
|
RB_GENERATE(ns_map_nsid_head, ns_map_nsid, id_entry, ns_map_compare);
|
||||||
struct ns_map_nsid_head ns_map_nsid_list = RB_INITIALIZER(&ns_map_nsid_list);
|
static struct ns_map_nsid_head ns_map_nsid_list =
|
||||||
|
RB_INITIALIZER(&ns_map_nsid_list);
|
||||||
|
|
||||||
static ns_id_t ns_id_external_numbering;
|
static ns_id_t ns_id_external_numbering;
|
||||||
|
|
||||||
@ -123,7 +124,7 @@ static int have_netns(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Holding NS hooks */
|
/* Holding NS hooks */
|
||||||
struct ns_master {
|
static struct ns_master {
|
||||||
int (*ns_new_hook)(struct ns *ns);
|
int (*ns_new_hook)(struct ns *ns);
|
||||||
int (*ns_delete_hook)(struct ns *ns);
|
int (*ns_delete_hook)(struct ns *ns);
|
||||||
int (*ns_enable_hook)(struct ns *ns);
|
int (*ns_enable_hook)(struct ns *ns);
|
||||||
|
@ -34,7 +34,7 @@ static inline int ns_compare(const struct ns *ns, const struct ns *ns2);
|
|||||||
|
|
||||||
RB_GENERATE(ns_head, ns, entry, ns_compare)
|
RB_GENERATE(ns_head, ns, entry, ns_compare)
|
||||||
|
|
||||||
struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
|
static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
|
||||||
|
|
||||||
static inline int ns_compare(const struct ns *a, const struct ns *b)
|
static inline int ns_compare(const struct ns *a, const struct ns *b)
|
||||||
{
|
{
|
||||||
|
@ -797,7 +797,7 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmd_node nexthop_group_node = {
|
static struct cmd_node nexthop_group_node = {
|
||||||
NH_GROUP_NODE,
|
NH_GROUP_NODE,
|
||||||
"%s(config-nh-group)# ",
|
"%s(config-nh-group)# ",
|
||||||
1
|
1
|
||||||
|
2
lib/ns.h
2
lib/ns.h
@ -71,8 +71,6 @@ struct ns {
|
|||||||
RB_HEAD(ns_head, ns);
|
RB_HEAD(ns_head, ns);
|
||||||
RB_PROTOTYPE(ns_head, ns, entry, ns_compare)
|
RB_PROTOTYPE(ns_head, ns, entry, ns_compare)
|
||||||
|
|
||||||
extern struct ns_head ns_tree;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* API for managing NETNS. eg from zebra daemon
|
* API for managing NETNS. eg from zebra daemon
|
||||||
* one want to manage the list of NETNS, etc...
|
* one want to manage the list of NETNS, etc...
|
||||||
|
492
lib/prefix.c
492
lib/prefix.c
@ -37,394 +37,6 @@ DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec")
|
|||||||
static const uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
|
static const uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
|
||||||
0xf8, 0xfc, 0xfe, 0xff};
|
0xf8, 0xfc, 0xfe, 0xff};
|
||||||
|
|
||||||
static const struct in6_addr maskbytes6[] = {
|
|
||||||
/* /0 */ {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /1 */
|
|
||||||
{{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /2 */
|
|
||||||
{{{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /3 */
|
|
||||||
{{{0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /4 */
|
|
||||||
{{{0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /5 */
|
|
||||||
{{{0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /6 */
|
|
||||||
{{{0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /7 */
|
|
||||||
{{{0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /8 */
|
|
||||||
{{{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /9 */
|
|
||||||
{{{0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /10 */
|
|
||||||
{{{0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /11 */
|
|
||||||
{{{0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /12 */
|
|
||||||
{{{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /13 */
|
|
||||||
{{{0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /14 */
|
|
||||||
{{{0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /15 */
|
|
||||||
{{{0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /16 */
|
|
||||||
{{{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /17 */
|
|
||||||
{{{0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /18 */
|
|
||||||
{{{0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /19 */
|
|
||||||
{{{0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /20 */
|
|
||||||
{{{0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /21 */
|
|
||||||
{{{0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /22 */
|
|
||||||
{{{0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /23 */
|
|
||||||
{{{0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /24 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /25 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /26 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /27 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /28 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /29 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /30 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /31 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /32 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /33 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /34 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /35 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /36 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /37 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /38 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /39 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /40 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /41 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /42 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /43 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /44 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /45 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /46 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /47 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /48 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /49 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /50 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /51 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /52 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /53 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /54 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /55 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /56 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /57 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /58 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /59 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /60 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /61 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /62 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /63 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /64 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /65 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /66 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /67 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /68 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /69 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /70 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /71 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /72 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /73 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /74 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /75 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /76 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /77 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /78 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /79 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /80 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /81 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /82 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /83 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /84 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /85 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /86 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /87 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /88 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /89 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x80, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /90 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xc0, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /91 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xe0, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /92 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xf0, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /93 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xf8, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /94 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xfc, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /95 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xfe, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /96 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0x00, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /97 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0x80, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /98 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xc0, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /99 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xe0, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /100 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xf0, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /101 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xf8, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /102 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xfc, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /103 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xfe, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /104 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0x00, 0x00, 0x00}}},
|
|
||||||
/* /105 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0x80, 0x00, 0x00}}},
|
|
||||||
/* /106 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xc0, 0x00, 0x00}}},
|
|
||||||
/* /107 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xe0, 0x00, 0x00}}},
|
|
||||||
/* /108 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xf0, 0x00, 0x00}}},
|
|
||||||
/* /109 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xf8, 0x00, 0x00}}},
|
|
||||||
/* /110 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xfc, 0x00, 0x00}}},
|
|
||||||
/* /111 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xfe, 0x00, 0x00}}},
|
|
||||||
/* /112 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0x00, 0x00}}},
|
|
||||||
/* /113 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0x80, 0x00}}},
|
|
||||||
/* /114 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xc0, 0x00}}},
|
|
||||||
/* /115 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xe0, 0x00}}},
|
|
||||||
/* /116 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xf0, 0x00}}},
|
|
||||||
/* /117 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xf8, 0x00}}},
|
|
||||||
/* /118 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xfc, 0x00}}},
|
|
||||||
/* /119 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xfe, 0x00}}},
|
|
||||||
/* /120 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0x00}}},
|
|
||||||
/* /121 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0x80}}},
|
|
||||||
/* /122 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xc0}}},
|
|
||||||
/* /123 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xe0}}},
|
|
||||||
/* /124 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xf0}}},
|
|
||||||
/* /125 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xf8}}},
|
|
||||||
/* /126 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xfc}}},
|
|
||||||
/* /127 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xfe}}},
|
|
||||||
/* /128 */
|
|
||||||
{{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff}}}};
|
|
||||||
|
|
||||||
/* Number of bits in prefix type. */
|
/* Number of bits in prefix type. */
|
||||||
#ifndef PNBBY
|
#ifndef PNBBY
|
||||||
#define PNBBY 8
|
#define PNBBY 8
|
||||||
@ -432,15 +44,6 @@ static const struct in6_addr maskbytes6[] = {
|
|||||||
|
|
||||||
#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
|
#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
|
||||||
|
|
||||||
void prefix_hexdump(const struct prefix *p)
|
|
||||||
{
|
|
||||||
char buf[PREFIX_STRLEN];
|
|
||||||
|
|
||||||
zlog_debug("prefix: %s",
|
|
||||||
prefix2str(p, buf, sizeof(buf)));
|
|
||||||
zlog_hexdump(p, sizeof(struct prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_zero_mac(const struct ethaddr *mac)
|
int is_zero_mac(const struct ethaddr *mac)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -461,11 +64,6 @@ unsigned int prefix_bit(const uint8_t *prefix, const uint16_t prefixlen)
|
|||||||
return (prefix[offset] >> shift) & 1;
|
return (prefix[offset] >> shift) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int prefix6_bit(const struct in6_addr *prefix, const uint16_t prefixlen)
|
|
||||||
{
|
|
||||||
return prefix_bit((const uint8_t *)&prefix->s6_addr, prefixlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int str2family(const char *string)
|
int str2family(const char *string)
|
||||||
{
|
{
|
||||||
if (!strcmp("ipv4", string))
|
if (!strcmp("ipv4", string))
|
||||||
@ -1121,31 +719,46 @@ int str2prefix_ipv6(const char *str, struct prefix_ipv6 *p)
|
|||||||
* FIXME return uint8_t as ip_maskleni() does. */
|
* FIXME return uint8_t as ip_maskleni() does. */
|
||||||
int ip6_masklen(struct in6_addr netmask)
|
int ip6_masklen(struct in6_addr netmask)
|
||||||
{
|
{
|
||||||
int len = 0;
|
if (netmask.s6_addr32[0] != 0xffffffffU)
|
||||||
unsigned char val;
|
return __builtin_clz(~ntohl(netmask.s6_addr32[0]));
|
||||||
unsigned char *pnt;
|
if (netmask.s6_addr32[1] != 0xffffffffU)
|
||||||
|
return __builtin_clz(~ntohl(netmask.s6_addr32[1])) + 32;
|
||||||
pnt = (unsigned char *)&netmask;
|
if (netmask.s6_addr32[2] != 0xffffffffU)
|
||||||
|
return __builtin_clz(~ntohl(netmask.s6_addr32[2])) + 64;
|
||||||
while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN) {
|
if (netmask.s6_addr32[3] != 0xffffffffU)
|
||||||
len += 8;
|
return __builtin_clz(~ntohl(netmask.s6_addr32[3])) + 96;
|
||||||
pnt++;
|
/* note __builtin_clz(0) is undefined */
|
||||||
}
|
return 128;
|
||||||
|
|
||||||
if (len < IPV6_MAX_BITLEN) {
|
|
||||||
val = *pnt;
|
|
||||||
while (val) {
|
|
||||||
len++;
|
|
||||||
val <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void masklen2ip6(const int masklen, struct in6_addr *netmask)
|
void masklen2ip6(const int masklen, struct in6_addr *netmask)
|
||||||
{
|
{
|
||||||
assert(masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
|
assert(masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
|
||||||
memcpy(netmask, maskbytes6 + masklen, sizeof(struct in6_addr));
|
|
||||||
|
if (masklen == 0) {
|
||||||
|
/* note << 32 is undefined */
|
||||||
|
memset(netmask, 0, sizeof(*netmask));
|
||||||
|
} else if (masklen <= 32) {
|
||||||
|
netmask->s6_addr32[0] = htonl(0xffffffffU << (32 - masklen));
|
||||||
|
netmask->s6_addr32[1] = 0;
|
||||||
|
netmask->s6_addr32[2] = 0;
|
||||||
|
netmask->s6_addr32[3] = 0;
|
||||||
|
} else if (masklen <= 64) {
|
||||||
|
netmask->s6_addr32[0] = 0xffffffffU;
|
||||||
|
netmask->s6_addr32[1] = htonl(0xffffffffU << (64 - masklen));
|
||||||
|
netmask->s6_addr32[2] = 0;
|
||||||
|
netmask->s6_addr32[3] = 0;
|
||||||
|
} else if (masklen <= 96) {
|
||||||
|
netmask->s6_addr32[0] = 0xffffffffU;
|
||||||
|
netmask->s6_addr32[1] = 0xffffffffU;
|
||||||
|
netmask->s6_addr32[2] = htonl(0xffffffffU << (96 - masklen));
|
||||||
|
netmask->s6_addr32[3] = 0;
|
||||||
|
} else {
|
||||||
|
netmask->s6_addr32[0] = 0xffffffffU;
|
||||||
|
netmask->s6_addr32[1] = 0xffffffffU;
|
||||||
|
netmask->s6_addr32[2] = 0xffffffffU;
|
||||||
|
netmask->s6_addr32[3] = htonl(0xffffffffU << (128 - masklen));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_mask_ipv6(struct prefix_ipv6 *p)
|
void apply_mask_ipv6(struct prefix_ipv6 *p)
|
||||||
@ -1183,33 +796,6 @@ void apply_mask(struct prefix *p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Utility function of convert between struct prefix <=> union sockunion.
|
|
||||||
* FIXME This function isn't used anywhere. */
|
|
||||||
struct prefix *sockunion2prefix(const union sockunion *dest,
|
|
||||||
const union sockunion *mask)
|
|
||||||
{
|
|
||||||
if (dest->sa.sa_family == AF_INET) {
|
|
||||||
struct prefix_ipv4 *p;
|
|
||||||
|
|
||||||
p = prefix_ipv4_new();
|
|
||||||
p->family = AF_INET;
|
|
||||||
p->prefix = dest->sin.sin_addr;
|
|
||||||
p->prefixlen = ip_masklen(mask->sin.sin_addr);
|
|
||||||
return (struct prefix *)p;
|
|
||||||
}
|
|
||||||
if (dest->sa.sa_family == AF_INET6) {
|
|
||||||
struct prefix_ipv6 *p;
|
|
||||||
|
|
||||||
p = prefix_ipv6_new();
|
|
||||||
p->family = AF_INET6;
|
|
||||||
p->prefixlen = ip6_masklen(mask->sin6.sin6_addr);
|
|
||||||
memcpy(&p->prefix, &dest->sin6.sin6_addr,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
return (struct prefix *)p;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Utility function of convert between struct prefix <=> union sockunion. */
|
/* Utility function of convert between struct prefix <=> union sockunion. */
|
||||||
struct prefix *sockunion2hostprefix(const union sockunion *su,
|
struct prefix *sockunion2hostprefix(const union sockunion *su,
|
||||||
struct prefix *prefix)
|
struct prefix *prefix)
|
||||||
@ -1521,14 +1107,6 @@ void apply_classful_mask_ipv4(struct prefix_ipv4 *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr_t ipv4_network_addr(in_addr_t hostaddr, int masklen)
|
|
||||||
{
|
|
||||||
struct in_addr mask;
|
|
||||||
|
|
||||||
masklen2ip(masklen, &mask);
|
|
||||||
return hostaddr & mask.s_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen)
|
in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen)
|
||||||
{
|
{
|
||||||
struct in_addr mask;
|
struct in_addr mask;
|
||||||
|
@ -392,8 +392,6 @@ extern const char *afi2str(afi_t afi);
|
|||||||
|
|
||||||
/* Check bit of the prefix. */
|
/* Check bit of the prefix. */
|
||||||
extern unsigned int prefix_bit(const uint8_t *prefix, const uint16_t prefixlen);
|
extern unsigned int prefix_bit(const uint8_t *prefix, const uint16_t prefixlen);
|
||||||
extern unsigned int prefix6_bit(const struct in6_addr *prefix,
|
|
||||||
const uint16_t prefixlen);
|
|
||||||
|
|
||||||
extern struct prefix *prefix_new(void);
|
extern struct prefix *prefix_new(void);
|
||||||
extern void prefix_free(struct prefix **p);
|
extern void prefix_free(struct prefix **p);
|
||||||
@ -430,8 +428,6 @@ extern void apply_mask(struct prefix *);
|
|||||||
#define prefix_copy(a, b) ({ memset(a, 0, sizeof(*a)); prefix_copy(a, b); })
|
#define prefix_copy(a, b) ({ memset(a, 0, sizeof(*a)); prefix_copy(a, b); })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern struct prefix *sockunion2prefix(const union sockunion *dest,
|
|
||||||
const union sockunion *mask);
|
|
||||||
extern struct prefix *sockunion2hostprefix(const union sockunion *,
|
extern struct prefix *sockunion2hostprefix(const union sockunion *,
|
||||||
struct prefix *p);
|
struct prefix *p);
|
||||||
extern void prefix2sockunion(const struct prefix *, union sockunion *);
|
extern void prefix2sockunion(const struct prefix *, union sockunion *);
|
||||||
@ -453,8 +449,6 @@ extern void apply_classful_mask_ipv4(struct prefix_ipv4 *);
|
|||||||
|
|
||||||
extern uint8_t ip_masklen(struct in_addr);
|
extern uint8_t ip_masklen(struct in_addr);
|
||||||
extern void masklen2ip(const int, struct in_addr *);
|
extern void masklen2ip(const int, struct in_addr *);
|
||||||
/* returns the network portion of the host address */
|
|
||||||
extern in_addr_t ipv4_network_addr(in_addr_t hostaddr, int masklen);
|
|
||||||
/* given the address of a host on a network and the network mask length,
|
/* given the address of a host on a network and the network mask length,
|
||||||
* calculate the broadcast address for that network;
|
* calculate the broadcast address for that network;
|
||||||
* special treatment for /31: returns the address of the other host
|
* special treatment for /31: returns the address of the other host
|
||||||
@ -484,7 +478,6 @@ extern unsigned prefix_hash_key(const void *pp);
|
|||||||
|
|
||||||
extern int str_to_esi(const char *str, esi_t *esi);
|
extern int str_to_esi(const char *str, esi_t *esi);
|
||||||
extern char *esi_to_str(const esi_t *esi, char *buf, int size);
|
extern char *esi_to_str(const esi_t *esi, char *buf, int size);
|
||||||
extern void prefix_hexdump(const struct prefix *p);
|
|
||||||
extern void prefix_evpn_hexdump(const struct prefix_evpn *p);
|
extern void prefix_evpn_hexdump(const struct prefix_evpn *p);
|
||||||
|
|
||||||
static inline int ipv6_martian(struct in6_addr *addr)
|
static inline int ipv6_martian(struct in6_addr *addr)
|
||||||
|
@ -221,7 +221,7 @@ struct route_map_match_set_hooks {
|
|||||||
const char *command, const char *arg);
|
const char *command, const char *arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct route_map_match_set_hooks rmap_match_set_hook;
|
static struct route_map_match_set_hooks rmap_match_set_hook;
|
||||||
|
|
||||||
/* match interface */
|
/* match interface */
|
||||||
void route_map_match_interface_hook(int (*func)(
|
void route_map_match_interface_hook(int (*func)(
|
||||||
@ -623,7 +623,7 @@ struct route_map_list {
|
|||||||
|
|
||||||
/* Master list of route map. */
|
/* Master list of route map. */
|
||||||
static struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL};
|
static struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL};
|
||||||
struct hash *route_map_master_hash = NULL;
|
static struct hash *route_map_master_hash = NULL;
|
||||||
|
|
||||||
static unsigned int route_map_hash_key_make(const void *p)
|
static unsigned int route_map_hash_key_make(const void *p)
|
||||||
{
|
{
|
||||||
@ -683,7 +683,7 @@ struct route_map_dep_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Hashes maintaining dependency between various sublists used by route maps */
|
/* Hashes maintaining dependency between various sublists used by route maps */
|
||||||
struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX];
|
static struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX];
|
||||||
|
|
||||||
static unsigned int route_map_dep_hash_make_key(const void *p);
|
static unsigned int route_map_dep_hash_make_key(const void *p);
|
||||||
static void route_map_clear_all_references(char *rmap_name);
|
static void route_map_clear_all_references(char *rmap_name);
|
||||||
|
@ -121,21 +121,6 @@ int setsockopt_ipv6_pktinfo(int sock, int val)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set multicast hops val to the socket. */
|
|
||||||
int setsockopt_ipv6_checksum(int sock, int val)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
#ifdef GNU_LINUX
|
|
||||||
ret = setsockopt(sock, IPPROTO_RAW, IPV6_CHECKSUM, &val, sizeof(val));
|
|
||||||
#else
|
|
||||||
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_CHECKSUM, &val, sizeof(val));
|
|
||||||
#endif /* GNU_LINUX */
|
|
||||||
if (ret < 0)
|
|
||||||
flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_CHECKSUM");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set multicast hops val to the socket. */
|
/* Set multicast hops val to the socket. */
|
||||||
int setsockopt_ipv6_multicast_hops(int sock, int val)
|
int setsockopt_ipv6_multicast_hops(int sock, int val)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,6 @@ extern int getsockopt_so_sendbuf(const int sock);
|
|||||||
extern int getsockopt_so_recvbuf(const int sock);
|
extern int getsockopt_so_recvbuf(const int sock);
|
||||||
|
|
||||||
extern int setsockopt_ipv6_pktinfo(int, int);
|
extern int setsockopt_ipv6_pktinfo(int, int);
|
||||||
extern int setsockopt_ipv6_checksum(int, int);
|
|
||||||
extern int setsockopt_ipv6_multicast_hops(int, int);
|
extern int setsockopt_ipv6_multicast_hops(int, int);
|
||||||
extern int setsockopt_ipv6_unicast_hops(int, int);
|
extern int setsockopt_ipv6_unicast_hops(int, int);
|
||||||
extern int setsockopt_ipv6_hoplimit(int, int);
|
extern int setsockopt_ipv6_hoplimit(int, int);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
* Wrapper this silliness if we
|
* Wrapper this silliness if we
|
||||||
* don't have systemd
|
* don't have systemd
|
||||||
*/
|
*/
|
||||||
void systemd_send_information(const char *info)
|
static void systemd_send_information(const char *info)
|
||||||
{
|
{
|
||||||
#if defined HAVE_SYSTEMD
|
#if defined HAVE_SYSTEMD
|
||||||
sd_notify(0, info);
|
sd_notify(0, info);
|
||||||
@ -93,8 +93,8 @@ void systemd_send_stopping(void)
|
|||||||
/*
|
/*
|
||||||
* How many seconds should we wait between watchdog sends
|
* How many seconds should we wait between watchdog sends
|
||||||
*/
|
*/
|
||||||
int wsecs = 0;
|
static int wsecs = 0;
|
||||||
struct thread_master *systemd_master = NULL;
|
static struct thread_master *systemd_master = NULL;
|
||||||
|
|
||||||
static int systemd_send_watchdog(struct thread *t)
|
static int systemd_send_watchdog(struct thread *t)
|
||||||
{
|
{
|
||||||
|
@ -32,7 +32,6 @@ extern "C" {
|
|||||||
* To turn on systemd compilation, use --enable-systemd on
|
* To turn on systemd compilation, use --enable-systemd on
|
||||||
* configure run.
|
* configure run.
|
||||||
*/
|
*/
|
||||||
void systemd_send_information(const char *info);
|
|
||||||
void systemd_send_stopping(void);
|
void systemd_send_stopping(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,7 +67,7 @@ static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL;
|
|||||||
static int debug_vrf = 0;
|
static int debug_vrf = 0;
|
||||||
|
|
||||||
/* Holding VRF hooks */
|
/* Holding VRF hooks */
|
||||||
struct vrf_master {
|
static struct vrf_master {
|
||||||
int (*vrf_new_hook)(struct vrf *);
|
int (*vrf_new_hook)(struct vrf *);
|
||||||
int (*vrf_delete_hook)(struct vrf *);
|
int (*vrf_delete_hook)(struct vrf *);
|
||||||
int (*vrf_enable_hook)(struct vrf *);
|
int (*vrf_enable_hook)(struct vrf *);
|
||||||
@ -752,7 +752,7 @@ DEFUN (no_vrf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct cmd_node vrf_node = {VRF_NODE, "%s(config-vrf)# ", 1};
|
static struct cmd_node vrf_node = {VRF_NODE, "%s(config-vrf)# ", 1};
|
||||||
|
|
||||||
DEFUN_NOSH (vrf_netns,
|
DEFUN_NOSH (vrf_netns,
|
||||||
vrf_netns_cmd,
|
vrf_netns_cmd,
|
||||||
|
@ -89,7 +89,7 @@ static char *vty_ipv6_accesslist_name = NULL;
|
|||||||
static vector Vvty_serv_thread;
|
static vector Vvty_serv_thread;
|
||||||
|
|
||||||
/* Current directory. */
|
/* Current directory. */
|
||||||
char vty_cwd[MAXPATHLEN];
|
static char vty_cwd[MAXPATHLEN];
|
||||||
|
|
||||||
/* Login password check. */
|
/* Login password check. */
|
||||||
static int no_password_check = 0;
|
static int no_password_check = 0;
|
||||||
|
@ -87,7 +87,7 @@ static inline int yang_module_compare(const struct yang_module *a,
|
|||||||
}
|
}
|
||||||
RB_GENERATE(yang_modules, yang_module, entry, yang_module_compare)
|
RB_GENERATE(yang_modules, yang_module, entry, yang_module_compare)
|
||||||
|
|
||||||
struct yang_modules yang_modules = RB_INITIALIZER(&yang_modules);
|
static struct yang_modules yang_modules = RB_INITIALIZER(&yang_modules);
|
||||||
|
|
||||||
struct yang_module *yang_module_load(const char *module_name)
|
struct yang_module *yang_module_load(const char *module_name)
|
||||||
{
|
{
|
||||||
|
@ -114,9 +114,6 @@ typedef int (*yang_iterate_cb)(const struct lys_node *snode, void *arg);
|
|||||||
/* Global libyang context for native FRR models. */
|
/* Global libyang context for native FRR models. */
|
||||||
extern struct ly_ctx *ly_native_ctx;
|
extern struct ly_ctx *ly_native_ctx;
|
||||||
|
|
||||||
/* Tree of all loaded YANG modules. */
|
|
||||||
extern struct yang_modules yang_modules;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new YANG module and load it using libyang. If the YANG module is not
|
* Create a new YANG module and load it using libyang. If the YANG module is not
|
||||||
* found in the YANG_MODELS_PATH directory, the program will exit with an error.
|
* found in the YANG_MODELS_PATH directory, the program will exit with an error.
|
||||||
|
347
tools/symalyzer.html
Normal file
347
tools/symalyzer.html
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
- 2019 by David Lamparter, placed in public domain
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Symalyzer report</title>
|
||||||
|
<style type="text/css">
|
||||||
|
html {
|
||||||
|
margin:auto;
|
||||||
|
max-width:70em;
|
||||||
|
font-family:Fira Sans, sans-serif;
|
||||||
|
}
|
||||||
|
dl {
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns: 1.4em 1.4em 1fr 1fr;
|
||||||
|
grid-auto-rows: auto;
|
||||||
|
}
|
||||||
|
dt.dir {
|
||||||
|
background-color:#ff8;
|
||||||
|
color:#000;
|
||||||
|
border:1px solid #000;
|
||||||
|
border-bottom:2px solid #000;
|
||||||
|
font-size:14pt;
|
||||||
|
padding:2pt 15pt;
|
||||||
|
margin:0pt;
|
||||||
|
margin-top:10pt;
|
||||||
|
grid-column:1 / -1;
|
||||||
|
}
|
||||||
|
dt.file {
|
||||||
|
background-color:#ffa;
|
||||||
|
color:#000;
|
||||||
|
border-bottom:1px solid #000;
|
||||||
|
font-size:12pt;
|
||||||
|
padding:2pt 15pt;
|
||||||
|
margin:5pt 0pt;
|
||||||
|
grid-column:1 / -1;
|
||||||
|
}
|
||||||
|
dt.file.filehidden {
|
||||||
|
background-color:#ffc;
|
||||||
|
font-size:10pt;
|
||||||
|
padding:0.5pt 15pt;
|
||||||
|
margin-bottom:-5pt;
|
||||||
|
}
|
||||||
|
dd {
|
||||||
|
display:inline-block;
|
||||||
|
vertical-align:middle;
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
dd.symtype {
|
||||||
|
grid-column:1;
|
||||||
|
|
||||||
|
border:1px solid #666;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
dd.symklass {
|
||||||
|
grid-column:2;
|
||||||
|
|
||||||
|
border:1px solid #666;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
dd.symname {
|
||||||
|
grid-column:3;
|
||||||
|
|
||||||
|
font-family:monospace;
|
||||||
|
padding:0 0.5em;
|
||||||
|
padding-top:2px;
|
||||||
|
border-bottom:1px dashed #ccc;
|
||||||
|
}
|
||||||
|
dd.symloc {
|
||||||
|
grid-column:4;
|
||||||
|
|
||||||
|
padding:0 0.5em;
|
||||||
|
border-bottom:1px dashed #ccc;
|
||||||
|
}
|
||||||
|
.symloc-unknown {
|
||||||
|
font-style:italic;
|
||||||
|
color:#aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.symtype.sym-static {
|
||||||
|
background-color:#cf4;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
.symtype.sym-extrastatic {
|
||||||
|
background-color:#fe8;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
.symtype.sym-liblocal {
|
||||||
|
background-color:#fc6;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.symklass.symk-T {
|
||||||
|
background-color:#ddd;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
.symklass.symk-B,
|
||||||
|
.symklass.symk-C,
|
||||||
|
.symklass.symk-D {
|
||||||
|
background-color:#faa;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
.symklass.symk-R {
|
||||||
|
background-color:#fd8;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.symtype.sym-api {
|
||||||
|
background-color:#d9f;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
.symname.sym-api,
|
||||||
|
.symloc.sym-api {
|
||||||
|
background-color:#f8e8ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt.file.dirhidden,
|
||||||
|
dd.dirhidden {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
dd.filehidden {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
dd.symhidden {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
font-size:10pt;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
margin-bottom:6pt;
|
||||||
|
text-indent:-2.5em;
|
||||||
|
margin-left:2.5em;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
background-color:#eee;
|
||||||
|
color:#060;
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
b.symtype,
|
||||||
|
b.symklass {
|
||||||
|
display:inline-block;
|
||||||
|
text-align:center;
|
||||||
|
border:1px solid #666;
|
||||||
|
width:1.4em;
|
||||||
|
text-indent:0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="jquery-3.4.1.min.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function dirtoggle(elem, visible) {
|
||||||
|
if (visible) {
|
||||||
|
elem.removeClass("dirhidden");
|
||||||
|
} else {
|
||||||
|
elem.addClass("dirhidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = elem.next();
|
||||||
|
while (next.is("dd") || next.is("dt.file")) {
|
||||||
|
if (visible) {
|
||||||
|
next.removeClass("dirhidden");
|
||||||
|
} else {
|
||||||
|
next.addClass("dirhidden");
|
||||||
|
}
|
||||||
|
next = next.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function filetoggle(elem, visible) {
|
||||||
|
if (visible) {
|
||||||
|
elem.removeClass("filehidden");
|
||||||
|
} else {
|
||||||
|
elem.addClass("filehidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = elem.next();
|
||||||
|
while (next.is("dd")) {
|
||||||
|
if (visible) {
|
||||||
|
next.removeClass("filehidden");
|
||||||
|
} else {
|
||||||
|
next.addClass("filehidden");
|
||||||
|
}
|
||||||
|
next = next.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function symtoggle(elem, visible) {
|
||||||
|
if (visible) {
|
||||||
|
elem.removeClass("symhidden");
|
||||||
|
} else {
|
||||||
|
elem.addClass("symhidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = elem.next();
|
||||||
|
while (next.is(".symklass") || next.is(".symname") || next.is(".symloc")) {
|
||||||
|
if (visible) {
|
||||||
|
next.removeClass("symhidden");
|
||||||
|
} else {
|
||||||
|
next.addClass("symhidden");
|
||||||
|
}
|
||||||
|
next = next.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("dt.dir").each(function(){
|
||||||
|
var elem = $(this);
|
||||||
|
|
||||||
|
elem.click(function(){
|
||||||
|
dirtoggle(elem, elem.is(".dirhidden"));
|
||||||
|
});
|
||||||
|
|
||||||
|
dirtoggle(elem, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("dt.file").each(function(){
|
||||||
|
var elem = $(this);
|
||||||
|
|
||||||
|
elem.click(function(){
|
||||||
|
filetoggle(elem, elem.is(".filehidden"));
|
||||||
|
});
|
||||||
|
|
||||||
|
/* filetoggle(elem, false); */
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#f_hide_all").click(function(){
|
||||||
|
$("dt.file").each(function(){
|
||||||
|
filetoggle($(this), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#f_show_all").click(function(){
|
||||||
|
$("dt.file").each(function(){
|
||||||
|
filetoggle($(this), true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#s_show_all").click(function(){
|
||||||
|
$("dd.symtype").each(function(){
|
||||||
|
symtoggle($(this), true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#s_hide_all").click(function(){
|
||||||
|
$("dd.symtype").each(function(){
|
||||||
|
symtoggle($(this), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#s_show_vars").click(function(){
|
||||||
|
$("dd.symtype").each(function(){
|
||||||
|
var elem_type = $(this);
|
||||||
|
if (elem_type.text() === "A") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var elem_klass = elem_type.next();
|
||||||
|
|
||||||
|
if ("BbCDdGgnRrSs".indexOf(elem_klass.text()) >= 0) {
|
||||||
|
symtoggle(elem_type, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#s_show_funcs").click(function(){
|
||||||
|
$("dd.symtype").each(function(){
|
||||||
|
var elem_type = $(this);
|
||||||
|
if (elem_type.text() === "A") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var elem_klass = elem_type.next();
|
||||||
|
|
||||||
|
if ("Tt".indexOf(elem_klass.text()) >= 0) {
|
||||||
|
symtoggle(elem_type, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#s_show_api").click(function(){
|
||||||
|
$("dd.sym-api").each(function(){
|
||||||
|
symtoggle($(this), true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#jsbuttons").show();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table style="display:none" id="jsbuttons">
|
||||||
|
<tr><td>Files</td><td>
|
||||||
|
<button type="button" id="f_hide_all">Hide all</button>
|
||||||
|
<button type="button" id="f_show_all">Show all</button>
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>Symbols</td><td>
|
||||||
|
<button type="button" id="s_hide_all">Hide all</button>
|
||||||
|
<button type="button" id="s_show_all">Show all</button><br>
|
||||||
|
<button type="button" id="s_show_vars">Show variables</button>
|
||||||
|
<button type="button" id="s_show_funcs">Show functions</button>
|
||||||
|
<button type="button" id="s_show_api">Show module/API usage</button>
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
<div style="display:grid;grid-template-columns:1fr 1fr;">
|
||||||
|
<ul>
|
||||||
|
<li><b class="symtype sym-static">S</b> means the symbol is not used outside its own file.
|
||||||
|
It could either be completely unused or used locally. It might be appropriate to make it
|
||||||
|
<code>static</code>.</li>
|
||||||
|
<li><b class="symtype sym-extrastatic">Z</b> means the symbol is not used outside its own file,
|
||||||
|
and it's not visible to the outside of the library or daemon (i.e. ELF hidden linkage.)
|
||||||
|
It could still be completely unused, or used within the library. It might be appropriate to make it
|
||||||
|
<code>static</code>.</li>
|
||||||
|
<li><b class="symtype sym-liblocal">L</b> means the symbol is used from other files in the library,
|
||||||
|
but not from outside. It might be appropriate to make it <code>DSO_LOCAL</code>.</li>
|
||||||
|
<li><b class="symtype sym-api">A</b> means the symbol is used from some other file, most likely a
|
||||||
|
loadable module. Note this is only flagged for symbols in executable files, not libraries.</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li><b class="symklass symk-T">T</b> are normal functions ("program <u>T</u>ext")</li>
|
||||||
|
<li style="text-indent:0;margin-left:0">
|
||||||
|
<b class="symklass symk-B">B</b> (<u>B</u>SS),<br>
|
||||||
|
<b class="symklass symk-C">C</b> (<u>C</u>ommon),<br>
|
||||||
|
<b class="symklass symk-D">D</b> (<u>D</u>ata)<br>
|
||||||
|
are various types of writable global variables</li>
|
||||||
|
<li><b class="symklass symk-R">R</b> are read-only global variables ("<u>R</u>odata")</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<dl>
|
||||||
|
{%- for subdir, subreport in dirgroups.items()|sort %}
|
||||||
|
<dt class="dir">{{ subdir }}</dt>
|
||||||
|
{%- for obj, reports in subreport.items()|sort %}
|
||||||
|
<dt class="file">{{ obj }}</dt>
|
||||||
|
{%- for report in reports|sort %}
|
||||||
|
{#- <dd class="{{ report.idlong }}"> #}
|
||||||
|
<dd class="sym-{{ report.idlong }} symtype" title="{{ report.title }}">{{ report.idshort }}</dd>
|
||||||
|
<dd class="sym-{{ report.idlong }} symk-{{ report.sym.klass }} symklass" title="{{ klasses.get(report.sym.klass, '???') }}">{{ report.sym.klass }}</dd>
|
||||||
|
<dd class="sym-{{ report.idlong }} symname">{{ report.sym.name }}</dd>
|
||||||
|
{% if report.sym.loc %}
|
||||||
|
<dd class="sym-{{ report.idlong }} symloc">{{ report.sym.loc }}</dd>
|
||||||
|
{% else %}
|
||||||
|
<dd class="sym-{{ report.idlong }} symloc symloc-unknown">unknown</dd>
|
||||||
|
{% endif %}
|
||||||
|
{#- </dd> #}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
|
</dl>
|
||||||
|
</body>
|
||||||
|
</html>
|
383
tools/symalyzer.py
Executable file
383
tools/symalyzer.py
Executable file
@ -0,0 +1,383 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
#
|
||||||
|
# 2019 by David Lamparter, placed in public domain
|
||||||
|
#
|
||||||
|
# This tool generates a report of possibly unused symbols in the build. It's
|
||||||
|
# particularly useful for libfrr to find bitrotting functions that aren't even
|
||||||
|
# used anywhere anymore.
|
||||||
|
#
|
||||||
|
# Note that the tool can't distinguish between "a symbol is completely unused"
|
||||||
|
# and "a symbol is used only in its file" since file-internal references are
|
||||||
|
# invisible in nm output. However, the compiler will warn you if a static
|
||||||
|
# symbol is unused.
|
||||||
|
#
|
||||||
|
# This tool is only tested on Linux, it probably needs `nm` from GNU binutils
|
||||||
|
# (as opposed to BSD `nm`). Could use pyelftools instead but that's a lot of
|
||||||
|
# extra work.
|
||||||
|
#
|
||||||
|
# This is a developer tool, please don't put it in any packages :)
|
||||||
|
|
||||||
|
import sys, os, subprocess
|
||||||
|
import re
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
class MakeVars(object):
|
||||||
|
'''
|
||||||
|
makevars['FOO_CFLAGS'] gets you "FOO_CFLAGS" from Makefile
|
||||||
|
'''
|
||||||
|
def __init__(self):
|
||||||
|
self._data = dict()
|
||||||
|
|
||||||
|
def getvars(self, varlist):
|
||||||
|
'''
|
||||||
|
get a batch list of variables from make. faster than individual calls.
|
||||||
|
'''
|
||||||
|
rdfd, wrfd = os.pipe()
|
||||||
|
|
||||||
|
shvars = ['shvar-%s' % s for s in varlist]
|
||||||
|
make = subprocess.Popen(['make', '-s', 'VARFD=%d' % wrfd] + shvars, pass_fds = [wrfd])
|
||||||
|
os.close(wrfd)
|
||||||
|
data = b''
|
||||||
|
|
||||||
|
rdf = os.fdopen(rdfd, 'rb')
|
||||||
|
while True:
|
||||||
|
rdata = rdf.read()
|
||||||
|
if len(rdata) == 0:
|
||||||
|
break
|
||||||
|
data += rdata
|
||||||
|
|
||||||
|
del rdf
|
||||||
|
make.wait()
|
||||||
|
|
||||||
|
data = data.decode('US-ASCII').strip().split('\n')
|
||||||
|
for row in data:
|
||||||
|
k, v = row.split('=', 1)
|
||||||
|
v = v[1:-1]
|
||||||
|
self._data[k] = v
|
||||||
|
|
||||||
|
def __getitem__(self, k):
|
||||||
|
if k not in self._data:
|
||||||
|
self.getvars([k])
|
||||||
|
return self._data[k]
|
||||||
|
|
||||||
|
def get(self, k, defval = None):
|
||||||
|
if k not in self._data:
|
||||||
|
self.getvars([k])
|
||||||
|
return self._data[k] or defval
|
||||||
|
|
||||||
|
SymRowBase = namedtuple('SymRow', ['target', 'object', 'name', 'address', 'klass', 'typ', 'size', 'line', 'section', 'loc'])
|
||||||
|
class SymRow(SymRowBase):
|
||||||
|
'''
|
||||||
|
wrapper around a line of `nm` output
|
||||||
|
'''
|
||||||
|
lib_re = re.compile(r'/lib[^/]+\.(so|la)$')
|
||||||
|
def is_global(self):
|
||||||
|
return self.klass.isupper() or self.klass in 'uvw'
|
||||||
|
def scope(self):
|
||||||
|
if self.lib_re.search(self.target) is None:
|
||||||
|
return self.target
|
||||||
|
# "global"
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_export(self):
|
||||||
|
'''
|
||||||
|
FRR-specific list of symbols which are considered "externally used"
|
||||||
|
|
||||||
|
e.g. hooks are by design APIs for external use, same for qobj_t_*
|
||||||
|
frr_inet_ntop is here because it's used through an ELF alias to
|
||||||
|
"inet_ntop()"
|
||||||
|
'''
|
||||||
|
if self.name in ['main', 'frr_inet_ntop', '_libfrr_version']:
|
||||||
|
return True
|
||||||
|
if self.name.startswith('_hook_'):
|
||||||
|
return True
|
||||||
|
if self.name.startswith('qobj_t_'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class Symbols(dict):
|
||||||
|
'''
|
||||||
|
dict of all symbols in all libs & executables
|
||||||
|
'''
|
||||||
|
|
||||||
|
from_re = re.compile(r'^Symbols from (.*?):$')
|
||||||
|
lt_re = re.compile(r'^(.*/)([^/]+)\.l[oa]$')
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
class ReportSym(object):
|
||||||
|
def __init__(self, sym):
|
||||||
|
self.sym = sym
|
||||||
|
def __repr__(self):
|
||||||
|
return '<%-25s %-40s [%s]>' % (self.__class__.__name__ + ':', self.sym.name, self.sym.loc)
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.sym.name.__lt__(other.sym.name)
|
||||||
|
|
||||||
|
class ReportSymCouldBeStaticAlreadyLocal(ReportSym):
|
||||||
|
idshort = 'Z'
|
||||||
|
idlong = 'extrastatic'
|
||||||
|
title = "symbol is local to library, but only used in its source file (make static?)"
|
||||||
|
class ReportSymCouldBeStatic(ReportSym):
|
||||||
|
idshort = 'S'
|
||||||
|
idlong = 'static'
|
||||||
|
title = "symbol is only used in its source file (make static?)"
|
||||||
|
class ReportSymCouldBeLibLocal(ReportSym):
|
||||||
|
idshort = 'L'
|
||||||
|
idlong = 'liblocal'
|
||||||
|
title = "symbol is only used inside of library"
|
||||||
|
class ReportSymModuleAPI(ReportSym):
|
||||||
|
idshort = 'A'
|
||||||
|
idlong = 'api'
|
||||||
|
title = "symbol (in executable) is referenced externally from a module"
|
||||||
|
|
||||||
|
class Symbol(object):
|
||||||
|
def __init__(self, name):
|
||||||
|
super().__init__()
|
||||||
|
self.name = name
|
||||||
|
self.defs = {}
|
||||||
|
self.refs = []
|
||||||
|
|
||||||
|
def process(self, row):
|
||||||
|
scope = row.scope()
|
||||||
|
if row.section == '*UND*':
|
||||||
|
self.refs.append(row)
|
||||||
|
else:
|
||||||
|
self.defs.setdefault(scope, []).append(row)
|
||||||
|
|
||||||
|
def evaluate(self, out):
|
||||||
|
'''
|
||||||
|
generate output report
|
||||||
|
|
||||||
|
invoked after all object files have been read in, so it can look
|
||||||
|
at inter-object-file relationships
|
||||||
|
'''
|
||||||
|
if len(self.defs) == 0:
|
||||||
|
out.extsyms.add(self.name)
|
||||||
|
return
|
||||||
|
|
||||||
|
for scopename, symdefs in self.defs.items():
|
||||||
|
common_defs = [symdef for symdef in symdefs if symdef.section == '*COM*']
|
||||||
|
proper_defs = [symdef for symdef in symdefs if symdef.section != '*COM*']
|
||||||
|
|
||||||
|
if len(proper_defs) > 1:
|
||||||
|
print(self.name, ' DUPLICATE')
|
||||||
|
print('\tD: %s %s' % (scopename, '\n\t\t'.join([repr(s) for s in symdefs])))
|
||||||
|
for syms in self.refs:
|
||||||
|
print('\tR: %s' % (syms, ))
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(proper_defs):
|
||||||
|
primary_def = proper_defs[0]
|
||||||
|
elif len(common_defs):
|
||||||
|
# "common" = global variables without initializer;
|
||||||
|
# they can occur in multiple .o files and the linker will
|
||||||
|
# merge them into one variable/storage location.
|
||||||
|
primary_def = common_defs[0]
|
||||||
|
else:
|
||||||
|
# undefined symbol, e.g. libc
|
||||||
|
continue
|
||||||
|
|
||||||
|
if scopename is not None and len(self.refs) > 0:
|
||||||
|
for ref in self.refs:
|
||||||
|
if ref.target != primary_def.target and ref.target.endswith('.la'):
|
||||||
|
outobj = out.report.setdefault(primary_def.object, [])
|
||||||
|
outobj.append(out.ReportSymModuleAPI(primary_def))
|
||||||
|
break
|
||||||
|
|
||||||
|
if len(self.refs) == 0:
|
||||||
|
if primary_def.is_export():
|
||||||
|
continue
|
||||||
|
outobj = out.report.setdefault(primary_def.object, [])
|
||||||
|
if primary_def.visible:
|
||||||
|
outobj.append(out.ReportSymCouldBeStatic(primary_def))
|
||||||
|
else:
|
||||||
|
outobj.append(out.ReportSymCouldBeStaticAlreadyLocal(primary_def))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if scopename is None and primary_def.visible:
|
||||||
|
# lib symbol
|
||||||
|
for ref in self.refs:
|
||||||
|
if ref.target != primary_def.target:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
outobj = out.report.setdefault(primary_def.object, [])
|
||||||
|
outobj.append(out.ReportSymCouldBeLibLocal(primary_def))
|
||||||
|
|
||||||
|
|
||||||
|
def evaluate(self):
|
||||||
|
self.extsyms = set()
|
||||||
|
self.report = {}
|
||||||
|
|
||||||
|
for sym in self.values():
|
||||||
|
sym.evaluate(self)
|
||||||
|
|
||||||
|
def load(self, target, files):
|
||||||
|
def libtoolmustdie(fn):
|
||||||
|
m = self.lt_re.match(fn)
|
||||||
|
if m is None:
|
||||||
|
return fn
|
||||||
|
return m.group(1) + '.libs/' + m.group(2) + '.o'
|
||||||
|
|
||||||
|
def libtooltargetmustdie(fn):
|
||||||
|
m = self.lt_re.match(fn)
|
||||||
|
if m is None:
|
||||||
|
a, b = fn.rsplit('/', 1)
|
||||||
|
return '%s/.libs/%s' % (a, b)
|
||||||
|
return m.group(1) + '.libs/' + m.group(2) + '.so'
|
||||||
|
|
||||||
|
files = list(set([libtoolmustdie(fn) for fn in files]))
|
||||||
|
|
||||||
|
def parse_nm_output(text):
|
||||||
|
filename = None
|
||||||
|
path_rel_to = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
for line in text.split('\n'):
|
||||||
|
if line.strip() == '':
|
||||||
|
continue
|
||||||
|
m = self.from_re.match(line)
|
||||||
|
if m is not None:
|
||||||
|
filename = m.group(1)
|
||||||
|
continue
|
||||||
|
if line.startswith('Name'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
items = [i.strip() for i in line.split('|')]
|
||||||
|
loc = None
|
||||||
|
if '\t' in items[-1]:
|
||||||
|
items[-1], loc = items[-1].split('\t', 1)
|
||||||
|
fn, lno = loc.rsplit(':', 1)
|
||||||
|
fn = os.path.relpath(fn, path_rel_to)
|
||||||
|
loc = '%s:%s' % (fn, lno)
|
||||||
|
|
||||||
|
items[1] = int(items[1] if items[1] != '' else '0', 16)
|
||||||
|
items[4] = int(items[4] if items[4] != '' else '0', 16)
|
||||||
|
items.append(loc)
|
||||||
|
row = SymRow(target, filename, *items)
|
||||||
|
|
||||||
|
if row.section == '.group' or row.name == '_GLOBAL_OFFSET_TABLE_':
|
||||||
|
continue
|
||||||
|
if not row.is_global():
|
||||||
|
continue
|
||||||
|
|
||||||
|
yield row
|
||||||
|
|
||||||
|
visible_syms = set()
|
||||||
|
|
||||||
|
# the actual symbol report uses output from the individual object files
|
||||||
|
# (e.g. lib/.libs/foo.o), but we also read the linked binary (e.g.
|
||||||
|
# lib/.libs/libfrr.so) to determine which symbols are actually visible
|
||||||
|
# in the linked result (this covers ELF "hidden"/"internal" linkage)
|
||||||
|
|
||||||
|
libfile = libtooltargetmustdie(target)
|
||||||
|
nmlib = subprocess.Popen(['nm', '-l', '-g', '--defined-only', '-f', 'sysv', libfile], stdout = subprocess.PIPE)
|
||||||
|
out = nmlib.communicate()[0].decode('US-ASCII')
|
||||||
|
|
||||||
|
for row in parse_nm_output(out):
|
||||||
|
visible_syms.add(row.name)
|
||||||
|
|
||||||
|
nm = subprocess.Popen(['nm', '-l', '-f', 'sysv'] + files, stdout = subprocess.PIPE)
|
||||||
|
out = nm.communicate()[0].decode('US-ASCII')
|
||||||
|
|
||||||
|
for row in parse_nm_output(out):
|
||||||
|
row.visible = row.name in visible_syms
|
||||||
|
sym = self.setdefault(row.name, self.Symbol(row.name))
|
||||||
|
sym.process(row)
|
||||||
|
|
||||||
|
|
||||||
|
def write_html_report(syms):
|
||||||
|
try:
|
||||||
|
import jinja2
|
||||||
|
except ImportError:
|
||||||
|
sys.stderr.write('jinja2 could not be imported, not writing HTML report!\n')
|
||||||
|
return
|
||||||
|
|
||||||
|
self_path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
jenv = jinja2.Environment(loader=jinja2.FileSystemLoader(self_path))
|
||||||
|
template = jenv.get_template('symalyzer.html')
|
||||||
|
|
||||||
|
dirgroups = {}
|
||||||
|
for fn, reports in syms.report.items():
|
||||||
|
dirname, filename = fn.replace('.libs/', '').rsplit('/', 1)
|
||||||
|
dirgroups.setdefault(dirname, {})[fn] = reports
|
||||||
|
|
||||||
|
klasses = {
|
||||||
|
'T': 'code / plain old regular function (Text)',
|
||||||
|
'D': 'global variable, read-write, with nonzero initializer (Data)',
|
||||||
|
'B': 'global variable, read-write, with zero initializer (BSS)',
|
||||||
|
'C': 'global variable, read-write, with zero initializer (Common)',
|
||||||
|
'R': 'global variable, read-only (Rodata)',
|
||||||
|
}
|
||||||
|
|
||||||
|
with open('symalyzer_report.html.tmp', 'w') as fd:
|
||||||
|
fd.write(template.render(dirgroups = dirgroups, klasses = klasses))
|
||||||
|
os.rename('symalyzer_report.html.tmp', 'symalyzer_report.html')
|
||||||
|
|
||||||
|
if not os.path.exists('jquery-3.4.1.min.js'):
|
||||||
|
url = 'https://code.jquery.com/jquery-3.4.1.min.js'
|
||||||
|
sys.stderr.write(
|
||||||
|
'trying to grab a copy of jquery from %s\nif this fails, please get it manually (the HTML output is done.)\n' % (url))
|
||||||
|
import requests
|
||||||
|
r = requests.get('https://code.jquery.com/jquery-3.4.1.min.js')
|
||||||
|
if r.status_code != 200:
|
||||||
|
sys.stderr.write('failed -- please download jquery-3.4.1.min.js and put it next to the HTML report\n')
|
||||||
|
else:
|
||||||
|
with open('jquery-3.4.1.min.js.tmp', 'w') as fd:
|
||||||
|
fd.write(r.text)
|
||||||
|
os.rename('jquery-3.4.1.min.js.tmp', 'jquery-3.4.1.min.js.tmp')
|
||||||
|
sys.stderr.write('done.\n')
|
||||||
|
|
||||||
|
def automake_escape(s):
|
||||||
|
return s.replace('.', '_').replace('/', '_')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
mv = MakeVars()
|
||||||
|
|
||||||
|
if not (os.path.exists('config.version') and os.path.exists('lib/.libs/libfrr.so')):
|
||||||
|
sys.stderr.write('please execute this script in the root directory of an FRR build tree\n')
|
||||||
|
sys.stderr.write('./configure && make need to have completed successfully\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
amtargets = ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES']
|
||||||
|
targets = []
|
||||||
|
|
||||||
|
mv.getvars(amtargets)
|
||||||
|
for amtarget in amtargets:
|
||||||
|
targets.extend([item for item in mv[amtarget].strip().split() if item != 'tools/ssd'])
|
||||||
|
|
||||||
|
mv.getvars(['%s_LDADD' % automake_escape(t) for t in targets])
|
||||||
|
ldobjs = targets[:]
|
||||||
|
for t in targets:
|
||||||
|
ldadd = mv['%s_LDADD' % automake_escape(t)].strip().split()
|
||||||
|
for item in ldadd:
|
||||||
|
if item.startswith('-'):
|
||||||
|
continue
|
||||||
|
if item.endswith('.a'):
|
||||||
|
ldobjs.append(item)
|
||||||
|
|
||||||
|
mv.getvars(['%s_OBJECTS' % automake_escape(o) for o in ldobjs])
|
||||||
|
|
||||||
|
syms = Symbols()
|
||||||
|
|
||||||
|
for t in targets:
|
||||||
|
objs = mv['%s_OBJECTS' % automake_escape(t)].strip().split()
|
||||||
|
ldadd = mv['%s_LDADD' % automake_escape(t)].strip().split()
|
||||||
|
for item in ldadd:
|
||||||
|
if item.startswith('-'):
|
||||||
|
continue
|
||||||
|
if item.endswith('.a'):
|
||||||
|
objs.extend(mv['%s_OBJECTS' % automake_escape(item)].strip().split())
|
||||||
|
|
||||||
|
sys.stderr.write('processing %s...\n' % t)
|
||||||
|
sys.stderr.flush()
|
||||||
|
#print(t, '\n\t', objs)
|
||||||
|
syms.load(t, objs)
|
||||||
|
|
||||||
|
syms.evaluate()
|
||||||
|
|
||||||
|
for obj, reports in sorted(syms.report.items()):
|
||||||
|
print('%s:' % obj)
|
||||||
|
for report in reports:
|
||||||
|
print('\t%r' % report)
|
||||||
|
|
||||||
|
write_html_report(syms)
|
Loading…
Reference in New Issue
Block a user