libnl-3.2.29/0000755000175000017500000000000013031473756007721 500000000000000libnl-3.2.29/Makefile.am0000644000175000017500000000104613023014600011652 00000000000000# -*- Makefile -*- ACLOCAL_AMFLAGS = -I m4 SUBDIRS = include lib man python tests pkgconfig_DATA = libnl-3.0.pc \ libnl-route-3.0.pc \ libnl-genl-3.0.pc \ libnl-nf-3.0.pc \ libnl-xfrm-3.0.pc \ libnl-idiag-3.0.pc if ENABLE_CLI SUBDIRS += src pkgconfig_DATA += libnl-cli-3.0.pc endif pkgsysconfdir = ${sysconfdir}/libnl pkgsysconf_DATA = etc/pktloc etc/classid EXTRA_DIST = \ $(pkgsysconf_DATA) \ libnl-3.sym \ libnl-cli-3.sym \ libnl-genl-3.sym \ libnl-idiag-3.sym \ libnl-nf-3.sym \ libnl-route-3.sym \ libnl-xfrm-3.sym libnl-3.2.29/libnl-3.sym0000644000175000017500000001461713023014600011620 00000000000000libnl_3 { global: # these functions are in private header files and should have never # been exported. We might hide them later. nl_cache_parse; # these functions are in private header files and should have never # been exported. They are used by libnl internals __flags2str; __list_str2type; __list_type2str; __nl_read_num_str_file; __str2flags; __str2type; __trans_list_add; __trans_list_clear; __type2str; # internal symbols that are in public headers __nl_cache_mngt_require; # variables nl_debug; nl_debug_dp; nl_addr2str; nl_addr_alloc; nl_addr_alloc_attr; nl_addr_build; nl_addr_clone; nl_addr_cmp; nl_addr_cmp_prefix; nl_addr_fill_sockaddr; nl_addr_get; nl_addr_get_binary_addr; nl_addr_get_family; nl_addr_get_len; nl_addr_get_prefixlen; nl_addr_guess_family; nl_addr_info; nl_addr_iszero; nl_addr_parse; nl_addr_put; nl_addr_resolve; nl_addr_set_binary_addr; nl_addr_set_family; nl_addr_set_prefixlen; nl_addr_shared; nl_addr_valid; nl_af2str; nl_auto_complete; nl_cache_add; nl_cache_alloc; nl_cache_alloc_and_fill; nl_cache_alloc_name; nl_cache_clear; nl_cache_clone; nl_cache_dump; nl_cache_dump_filter; nl_cache_find; nl_cache_foreach; nl_cache_foreach_filter; nl_cache_free; nl_cache_get; nl_cache_get_first; nl_cache_get_last; nl_cache_get_next; nl_cache_get_ops; nl_cache_get_prev; nl_cache_include; nl_cache_is_empty; nl_cache_mark_all; nl_cache_mngr_add; nl_cache_mngr_add_cache; nl_cache_mngr_alloc; nl_cache_mngr_data_ready; nl_cache_mngr_free; nl_cache_mngr_get_fd; nl_cache_mngr_info; nl_cache_mngr_poll; nl_cache_mngt_provide; nl_cache_mngt_register; nl_cache_mngt_require; nl_cache_mngt_require_safe; nl_cache_mngt_unprovide; nl_cache_mngt_unregister; nl_cache_move; nl_cache_nitems; nl_cache_nitems_filter; nl_cache_ops_associate; nl_cache_ops_associate_safe; nl_cache_ops_foreach; nl_cache_ops_get; nl_cache_ops_lookup; nl_cache_ops_lookup_safe; nl_cache_ops_put; nl_cache_ops_set_flags; nl_cache_parse_and_add; nl_cache_pickup; nl_cache_put; nl_cache_refill; nl_cache_remove; nl_cache_resync; nl_cache_search; nl_cache_set_arg1; nl_cache_set_arg2; nl_cache_set_flags; nl_cache_subset; nl_cancel_down_bits; nl_cancel_down_bytes; nl_cancel_down_us; nl_cb_active_type; nl_cb_alloc; nl_cb_clone; nl_cb_err; nl_cb_get; nl_cb_overwrite_recv; nl_cb_overwrite_recvmsgs; nl_cb_overwrite_send; nl_cb_put; nl_cb_set; nl_cb_set_all; nl_close; nl_complete_msg; nl_connect; nl_data_alloc; nl_data_alloc_attr; nl_data_append; nl_data_clone; nl_data_cmp; nl_data_free; nl_data_get; nl_data_get_size; nl_dump; nl_dump_line; nl_ether_proto2str; nl_get_psched_hz; nl_get_user_hz; nl_geterror; nl_has_capability; nl_hash; nl_hash_any; nl_hash_table_add; nl_hash_table_alloc; nl_hash_table_del; nl_hash_table_free; nl_hash_table_lookup; nl_ip_proto2str; nl_join_groups; nl_llproto2str; nl_msec2str; nl_msg_dump; nl_msg_parse; nl_msgtype_lookup; nl_new_line; nl_nlfamily2str; nl_nlmsg_flags2str; nl_nlmsgtype2str; nl_object_alloc; nl_object_alloc_name; nl_object_attr_list; nl_object_attrs2str; nl_object_clone; nl_object_diff; nl_object_dump; nl_object_dump_buf; nl_object_free; nl_object_get; nl_object_get_cache; nl_object_get_id_attrs; nl_object_get_msgtype; nl_object_get_ops; nl_object_get_refcnt; nl_object_get_type; nl_object_identical; nl_object_is_marked; nl_object_keygen; nl_object_mark; nl_object_match_filter; nl_object_put; nl_object_shared; nl_object_unmark; nl_object_update; nl_perror; nl_pickup; nl_prob2int; nl_rate2str; nl_recv; nl_recvmsgs; nl_recvmsgs_default; nl_recvmsgs_report; nl_send; nl_send_auto; nl_send_auto_complete; nl_send_iovec; nl_send_simple; nl_send_sync; nl_sendmsg; nl_sendto; nl_size2int; nl_size2str; nl_socket_add_membership; nl_socket_add_memberships; nl_socket_alloc; nl_socket_alloc_cb; nl_socket_disable_auto_ack; nl_socket_disable_msg_peek; nl_socket_disable_seq_check; nl_socket_drop_membership; nl_socket_drop_memberships; nl_socket_enable_auto_ack; nl_socket_enable_msg_peek; nl_socket_free; nl_socket_get_cb; nl_socket_get_fd; nl_socket_get_local_port; nl_socket_get_msg_buf_size; nl_socket_get_peer_groups; nl_socket_get_peer_port; nl_socket_modify_cb; nl_socket_modify_err_cb; nl_socket_recv_pktinfo; nl_socket_set_buffer_size; nl_socket_set_cb; nl_socket_set_local_port; nl_socket_set_msg_buf_size; nl_socket_set_nonblocking; nl_socket_set_passcred; nl_socket_set_peer_groups; nl_socket_set_peer_port; nl_socket_use_seq; nl_str2af; nl_str2ether_proto; nl_str2ip_proto; nl_str2llproto; nl_str2msec; nl_str2nlfamily; nl_str2nlmsgtype; nl_syserr2nlerr; nl_ticks2us; nl_us2ticks; nl_ver_maj; nl_ver_mic; nl_ver_min; nl_ver_num; nl_wait_for_ack; nla_attr_size; nla_data; nla_find; nla_get_flag; nla_get_msecs; nla_get_string; nla_get_u16; nla_get_u32; nla_get_u64; nla_get_u8; nla_is_nested; nla_len; nla_memcmp; nla_memcpy; nla_nest_cancel; nla_nest_end; nla_nest_start; nla_next; nla_ok; nla_padlen; nla_parse; nla_parse_nested; nla_put; nla_put_addr; nla_put_data; nla_put_flag; nla_put_msecs; nla_put_nested; nla_put_string; nla_put_u16; nla_put_u32; nla_put_u64; nla_put_u8; nla_reserve; nla_strcmp; nla_strdup; nla_strlcpy; nla_total_size; nla_type; nla_validate; nlmsg_alloc; nlmsg_alloc_simple; nlmsg_alloc_size; nlmsg_append; nlmsg_attrdata; nlmsg_attrlen; nlmsg_convert; nlmsg_data; nlmsg_datalen; nlmsg_expand; nlmsg_find_attr; nlmsg_free; nlmsg_get; nlmsg_get_creds; nlmsg_get_dst; nlmsg_get_max_size; nlmsg_get_proto; nlmsg_get_src; nlmsg_hdr; nlmsg_inherit; nlmsg_next; nlmsg_ok; nlmsg_padlen; nlmsg_parse; nlmsg_put; nlmsg_reserve; nlmsg_set_creds; nlmsg_set_default_size; nlmsg_set_dst; nlmsg_set_proto; nlmsg_set_src; nlmsg_size; nlmsg_tail; nlmsg_total_size; nlmsg_valid_hdr; nlmsg_validate; # The following symbols were added during the development of 3.2.26. # Keep them in libnl_3 to avoid breaking users. nl_cache_pickup_checkdup; nl_pickup_keep_syserr; local: *; }; libnl_3_2_26 { global: nl_socket_set_fd; } libnl_3; libnl_3_2_27 { global: nla_get_s8; nla_put_s8; nla_get_s16; nla_put_s16; nla_get_s32; nla_put_s32; nla_get_s64; nla_put_s64; } libnl_3_2_26; libnl_3_2_28 { global: nl_object_diff64; } libnl_3_2_27; libnl_3_2_29 { global: nl_cache_include_v2; nl_cache_mngr_add_cache_v2; nl_strerror_l; } libnl_3_2_28; libnl-3.2.29/tests/0000755000175000017500000000000013031473756011063 500000000000000libnl-3.2.29/tests/check-all.c0000644000175000017500000000164013023014600012747 00000000000000/* * tests/check-all.c overall unit test program * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #include extern Suite *make_nl_addr_suite(void); extern Suite *make_nl_attr_suite(void); static Suite *main_suite(void) { Suite *suite = suite_create("main"); return suite; } int main(int argc, char *argv[]) { SRunner *runner; int nfailed; runner = srunner_create(main_suite()); /* Add testsuites below */ srunner_add_suite(runner, make_nl_addr_suite()); srunner_add_suite(runner, make_nl_attr_suite()); /* Do not add testsuites below this line */ srunner_run_all(runner, CK_ENV); nfailed = srunner_ntests_failed(runner); srunner_free(runner); return nfailed != 0; } libnl-3.2.29/tests/Makefile.am0000644000175000017500000000354213023014600013017 00000000000000# -*- Makefile -*- EXTRA_DIST = \ util.h if ENABLE_UNIT_TESTS AM_CPPFLAGS = \ -Wall \ -I${top_srcdir}/include/linux-private \ -I${top_srcdir}/include \ -I${top_builddir}/include \ -D_GNU_SOURCE \ -DSYSCONFDIR=\"$(sysconfdir)/libnl\" LDADD = \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ @CHECK_LIBS@ AM_CFLAGS = @CHECK_CFLAGS@ UNIT_TESTS = check-all check_PROGRAMS = \ test-create-bond \ test-create-vlan \ test-create-vxlan \ test-create-veth \ test-create-bridge \ test-create-ip6tnl \ test-create-ipgre \ test-create-ipgretap \ test-create-ipip \ test-create-ipvti \ test-create-macsec \ test-create-macvlan \ test-create-macvtap \ test-create-ipvlan \ test-create-vrf \ test-create-sit \ test-create-ifb \ test-delete-link \ test-socket-creation \ test-complex-HTB-with-hash-filters \ test-u32-filter-with-actions \ ${UNIT_TESTS} TESTS = \ ${UNIT_TESTS} if ENABLE_CLI LDADD += ${top_builddir}/src/lib/libnl-cli-3.la check_PROGRAMS += \ test-cache-mngr \ test-genl \ test-nf-cache-mngr endif test_cache_mngr_SOURCES = test-cache-mngr.c test_create_bond_SOURCES = test-create-bond.c test_create_vlan_SOURCES = test-create-vlan.c test_create_vxlan_SOURCES = test-create-vxlan.c test_create_veth_SOURCES = test-create-veth.c test_create_bridge_SOURCES = test-create-bridge.c test_create_ifb_SOURCES = test-create-ifb.c test_delete_link_SOURCES = test-delete-link.c test_genl_SOURCES = test-genl.c test_nf_cache_mngr_SOURCES = test-nf-cache-mngr.c test_socket_creation_SOURCES = test-socket-creation.c test_complex_HTB_with_hash_filters_SOURCES = test-complex-HTB-with-hash-filters.c test_u32_filter_with_actions_SOURCES = test-u32-filter-with-actions.c # Unit tests check_all_SOURCES = \ check-all.c \ check-addr.c \ check-attr.c endif libnl-3.2.29/tests/test-create-sit.c0000644000175000017500000000232713023014600014144 00000000000000#include #include int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "eno16777736"); if (!if_index) { fprintf(stderr, "Unable to lookup eno16777736"); return -1; } link = rtnl_link_sit_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "sit-tun"); rtnl_link_sit_set_link(link, if_index); inet_pton(AF_INET, "192.168.254.12", &addr.s_addr); rtnl_link_sit_set_local(link, addr.s_addr); inet_pton(AF_INET, "192.168.254.13", &addr.s_addr); rtnl_link_sit_set_remote(link, addr.s_addr); rtnl_link_sit_set_ttl(link, 64); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-macvtap.c0000644000175000017500000000216413023014600014777 00000000000000#include #include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; struct nl_addr* addr; int err, master_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(master_index = rtnl_link_name2i(link_cache, "eth0"))) { fprintf(stderr, "Unable to lookup eth0"); return -1; } link = rtnl_link_macvtap_alloc(); rtnl_link_set_link(link, master_index); addr = nl_addr_build(AF_LLC, ether_aton("00:11:22:33:44:55"), ETH_ALEN); rtnl_link_set_addr(link, addr); nl_addr_put(addr); rtnl_link_macvtap_set_mode(link, rtnl_link_macvtap_str2mode("bridge")); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-ipip.c0000644000175000017500000000233613023014600014306 00000000000000#include #include int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "eno16777736"); if (!if_index) { fprintf(stderr, "Unable to lookup eno16777736"); return -1; } link = rtnl_link_ipip_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "ipip-tun"); rtnl_link_ipip_set_link(link, if_index); inet_pton(AF_INET, "192.168.254.12", &addr.s_addr); rtnl_link_ipip_set_local(link, addr.s_addr); inet_pton(AF_INET, "192.168.254.13", &addr.s_addr); rtnl_link_ipip_set_remote(link, addr.s_addr); rtnl_link_ipip_set_ttl(link, 64); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-ip6tnl.c0000644000175000017500000000227313023014600014561 00000000000000#include #include int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in6_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "ens33"); if (!if_index) { fprintf(stderr, "Unable to lookup ens33"); return -1; } link = rtnl_link_ip6_tnl_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "ip6tnl-tun"); rtnl_link_ip6_tnl_set_link(link, if_index); inet_pton(AF_INET6, "2607:f0d0:1002:51::4", &addr); rtnl_link_ip6_tnl_set_local(link, &addr); inet_pton(AF_INET6, "2607:f0d0:1002:52::5", &addr); rtnl_link_ip6_tnl_set_remote(link, &addr); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-macvlan.c0000644000175000017500000000221113023014600014756 00000000000000#include #include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; struct nl_addr* addr; int err, master_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(master_index = rtnl_link_name2i(link_cache, "eth0"))) { fprintf(stderr, "Unable to lookup eth0"); return -1; } link = rtnl_link_macvlan_alloc(); rtnl_link_set_link(link, master_index); addr = nl_addr_build(AF_LLC, ether_aton("00:11:22:33:44:55"), ETH_ALEN); rtnl_link_set_addr(link, addr); nl_addr_put(addr); rtnl_link_macvlan_set_mode(link, rtnl_link_macvlan_str2mode("bridge")); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/check-addr.c0000644000175000017500000001301413023014600013107 00000000000000/* * tests/check-addr.c nl_addr unit tests * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #include #include START_TEST(addr_alloc) { struct nl_addr *addr; addr = nl_addr_alloc(16); fail_if(addr == NULL, "Allocation should not return NULL"); fail_if(nl_addr_iszero(addr) == 0, "New empty address should be all zeros"); fail_if(nl_addr_get_family(addr) != AF_UNSPEC, "New empty address should have family AF_UNSPEC"); fail_if(nl_addr_get_prefixlen(addr) != 0, "New empty address should have prefix length 0"); fail_if(nl_addr_shared(addr), "New empty address should not be shared"); fail_if(nl_addr_get(addr) != addr, "nl_addr_get() should return pointer to address"); fail_if(nl_addr_shared(addr) == 0, "Address should be shared after call to nl_addr_get()"); nl_addr_put(addr); fail_if(nl_addr_shared(addr), "Address should not be shared after call to nl_addr_put()"); fail_if(nl_addr_fill_sockaddr(addr, NULL, 0) == 0, "Socket address filling should fail for empty address"); nl_addr_put(addr); } END_TEST START_TEST(addr_binary_addr) { struct nl_addr *addr, *addr2; char baddr[4] = { 0x1, 0x2, 0x3, 0x4 }; char baddr2[6] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }; addr = nl_addr_alloc(4); fail_if(addr == NULL, "Allocation should not return NULL"); fail_if(nl_addr_set_binary_addr(addr, baddr, 4) < 0, "Valid binary address should be settable"); fail_if(nl_addr_get_prefixlen(addr) != 0, "Prefix length should be unchanged after nl_addr_set_binary_addr()"); fail_if(nl_addr_get_len(addr) != 4, "Address length should be 4"); fail_if(nl_addr_set_binary_addr(addr, baddr2, 6) == 0, "Should not be able to set binary address exceeding maximum length"); fail_if(nl_addr_get_len(addr) != 4, "Address length should still be 4"); fail_if(nl_addr_guess_family(addr) != AF_INET, "Binary address of length 4 should be guessed as AF_INET"); fail_if(memcmp(baddr, nl_addr_get_binary_addr(addr), 4) != 0, "Binary address mismatches"); addr2 = nl_addr_build(AF_UNSPEC, baddr, 4); fail_if(addr2 == NULL, "Building of address should not fail"); nl_addr_set_prefixlen(addr, 32); fail_if(nl_addr_get_prefixlen(addr) != 32, "Prefix length should be successful changed after nl_addr_set_prefixlen()"); fail_if(nl_addr_cmp(addr, addr2), "Addresses built from same binary address should match"); nl_addr_put(addr); nl_addr_put(addr2); } END_TEST START_TEST(addr_parse4) { struct nl_addr *addr4, *clone; struct sockaddr_in sin; socklen_t len = sizeof(sin); char *addr_str = "10.0.0.1/16"; char buf[128]; fail_if(nl_addr_parse(addr_str, AF_INET6, &addr4) == 0, "Should not be able to parse IPv4 address in IPv6 mode"); fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr4) != 0, "Should be able to parse \"%s\"", addr_str); fail_if(nl_addr_get_family(addr4) != AF_INET, "Address family should be AF_INET"); fail_if(nl_addr_get_prefixlen(addr4) != 16, "Prefix length should be 16"); fail_if(nl_addr_iszero(addr4), "Address should not be all zeroes"); clone = nl_addr_clone(addr4); fail_if(clone == NULL, "Cloned address should not be NULL"); fail_if(nl_addr_cmp(addr4, clone) != 0, "Cloned address should not mismatch original"); fail_if(nl_addr_fill_sockaddr(addr4, (struct sockaddr *) &sin, &len) != 0, "Should be able to fill socketaddr"); fail_if(strcmp(nl_addr2str(addr4, buf, sizeof(buf)), addr_str), "Address translated back to string does not match original"); nl_addr_put(addr4); nl_addr_put(clone); } END_TEST START_TEST(addr_parse6) { struct nl_addr *addr6, *clone; struct sockaddr_in6 sin; socklen_t len = sizeof(sin); char *addr_str = "2001:1:2::3/64"; char buf[128]; fail_if(nl_addr_parse(addr_str, AF_INET, &addr6) == 0, "Should not be able to parse IPv6 address in IPv4 mode"); fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr6) != 0, "Should be able to parse \"%s\"", addr_str); fail_if(nl_addr_get_family(addr6) != AF_INET6, "Address family should be AF_INET6"); fail_if(nl_addr_get_prefixlen(addr6) != 64, "Prefix length should be 64"); fail_if(nl_addr_iszero(addr6), "Address should not be all zeroes"); clone = nl_addr_clone(addr6); fail_if(clone == NULL, "Cloned address should not be NULL"); fail_if(nl_addr_cmp(addr6, clone) != 0, "Cloned address should not mismatch original"); fail_if(nl_addr_fill_sockaddr(addr6, (struct sockaddr *) &sin, &len) != 0, "Should be able to fill socketaddr"); fail_if(strcmp(nl_addr2str(addr6, buf, sizeof(buf)), addr_str), "Address translated back to string does not match original"); nl_addr_put(addr6); nl_addr_put(clone); } END_TEST START_TEST(addr_info) { struct nl_addr *addr; char *addr_str = "127.0.0.1"; struct addrinfo *result; fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr) != 0, "Parsing of valid address should not fail"); fail_if(nl_addr_info(addr, &result) != 0, "getaddrinfo() on loopback address should work"); freeaddrinfo(result); nl_addr_put(addr); } END_TEST Suite *make_nl_addr_suite(void) { Suite *suite = suite_create("Abstract addresses"); TCase *tc_addr = tcase_create("Core"); tcase_add_test(tc_addr, addr_alloc); tcase_add_test(tc_addr, addr_binary_addr); tcase_add_test(tc_addr, addr_parse4); tcase_add_test(tc_addr, addr_parse6); tcase_add_test(tc_addr, addr_info); suite_add_tcase(suite, tc_addr); return suite; } libnl-3.2.29/tests/test-create-vlan.c0000644000175000017500000000161513023014600014304 00000000000000#include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; int err, master_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(master_index = rtnl_link_name2i(link_cache, "eth0"))) { fprintf(stderr, "Unable to lookup eth0"); return -1; } link = rtnl_link_vlan_alloc(); rtnl_link_set_link(link, master_index); rtnl_link_vlan_set_id(link, 10); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-ipvlan.c0000644000175000017500000000177013023014600014637 00000000000000#include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; int err, master_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(master_index = rtnl_link_name2i(link_cache, "eth0"))) { fprintf(stderr, "Unable to lookup eth0"); return -1; } if (!(link = rtnl_link_ipvlan_alloc())) { fprintf(stderr, "Unable to allocate link"); return -1; } rtnl_link_set_link(link, master_index); rtnl_link_ipvlan_set_mode(link, rtnl_link_ipvlan_str2mode("l2")); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-veth.c0000644000175000017500000000156613023014600014317 00000000000000#include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_sock *sk; int err; struct rtnl_link *peer; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } #if 0 rtnl_link_veth_add(sk, "veth2", "veth3", getpid()); #else link = rtnl_link_veth_alloc(); if (!link) { nl_perror(err, "Unable to alloc link"); return err; } rtnl_link_set_name(link, "veth8"); peer = rtnl_link_veth_get_peer(link); rtnl_link_set_name(peer, "veth9"); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } printf("peer is %s\n", rtnl_link_get_name(peer)); rtnl_link_put(peer); rtnl_link_put(link); #endif nl_close(sk); return 0; } libnl-3.2.29/tests/test-complex-HTB-with-hash-filters.c0000644000175000017500000005011513023014600017524 00000000000000/* * test/test-complex-HTB-with-hash-filters.c Add HTB qdisc, HTB classes and creates some hash filters * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2011 Adrian Ban */ #include #include #include #include #include #include #include #include #include #include //#include "include/rtnl_u32.h" #include #include //#include "include/rtnl_u32_addon.h" #define TC_HANDLE(maj, min) (TC_H_MAJ((maj) << 16) | TC_H_MIN(min)) /* some functions are copied from iproute-tc tool */ int get_u32(__u32 *val, const char *arg, int base) { unsigned long res; char *ptr; if (!arg || !*arg) return -1; res = strtoul(arg, &ptr, base); if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL) return -1; *val = res; return 0; } int get_u32_handle(__u32 *handle, const char *str) { __u32 htid=0, hash=0, nodeid=0; char *tmp = strchr(str, ':'); if (tmp == NULL) { if (memcmp("0x", str, 2) == 0) return get_u32(handle, str, 16); return -1; } htid = strtoul(str, &tmp, 16); if (tmp == str && *str != ':' && *str != 0) return -1; if (htid>=0x1000) return -1; if (*tmp) { str = tmp+1; hash = strtoul(str, &tmp, 16); if (tmp == str && *str != ':' && *str != 0) return -1; if (hash>=0x100) return -1; if (*tmp) { str = tmp+1; nodeid = strtoul(str, &tmp, 16); if (tmp == str && *str != 0) return -1; if (nodeid>=0x1000) return -1; } } *handle = (htid<<20)|(hash<<12)|nodeid; return 0; } uint32_t get_u32_parse_handle(const char *cHandle) { uint32_t handle=0; if(get_u32_handle(&handle, cHandle)) { printf ("Illegal \"ht\"\n"); return -1; } if (handle && TC_U32_NODE(handle)) { printf("\"link\" must be a hash table.\n"); return -1; } return handle; } int get_tc_classid(__u32 *h, const char *str) { __u32 maj, min; char *p; maj = TC_H_ROOT; if (strcmp(str, "root") == 0) goto ok; maj = TC_H_UNSPEC; if (strcmp(str, "none") == 0) goto ok; maj = strtoul(str, &p, 16); if (p == str) { maj = 0; if (*p != ':') return -1; } if (*p == ':') { if (maj >= (1<<16)) return -1; maj <<= 16; str = p+1; min = strtoul(str, &p, 16); if (*p != 0) return -1; if (min >= (1<<16)) return -1; maj |= min; } else if (*p != 0) return -1; ok: *h = maj; return 0; } /* * Function that adds a new filter and attach it to a hash table * */ int u32_add_filter_on_ht(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, uint32_t keyval, uint32_t keymask, int keyoff, int keyoffmask, uint32_t htid, uint32_t classid ) { struct rtnl_cls *cls; int err; //printf("Key Val : 0x%x\n", keyval); //printf("Key Mask : 0x%x\n", keymask); cls=rtnl_cls_alloc(); if (!(cls)) { printf("Can not allocate classifier\n"); nl_socket_free(sock); exit(1); } rtnl_tc_set_link(TC_CAST(cls), rtnlLink); if ((err = rtnl_tc_set_kind(TC_CAST(cls), "u32"))) { printf("Can not set classifier as u32\n"); return 1; } rtnl_cls_set_prio(cls, prio); rtnl_cls_set_protocol(cls, ETH_P_IP); rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0)); rtnl_u32_set_hashtable(cls, htid); rtnl_u32_add_key_uint32(cls, keyval, keymask, keyoff, keyoffmask); /* 10.0.0.0/8 */ rtnl_u32_set_classid(cls, classid); rtnl_u32_set_cls_terminal(cls); if ((err = rtnl_cls_add(sock, cls, NLM_F_CREATE))) { printf("Can not add classifier: %s\n", nl_geterror(err)); return -1; } rtnl_cls_put(cls); return 0; } /* * Function that adds a new filter and attach it to a hash table * and set next hash table link with hash mask * */ int u32_add_filter_on_ht_with_hashmask(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, uint32_t keyval, uint32_t keymask, int keyoff, int keyoffmask, uint32_t htid, uint32_t htlink, uint32_t hmask, uint32_t hoffset ) { struct rtnl_cls *cls; int err; //printf("Key Val : 0x%x\n", keyval); //printf("Key Mask : 0x%x\n", keymask); cls=rtnl_cls_alloc(); if (!(cls)) { printf("Can not allocate classifier\n"); nl_socket_free(sock); exit(1); } rtnl_tc_set_link(TC_CAST(cls), rtnlLink); if ((err = rtnl_tc_set_kind(TC_CAST(cls), "u32"))) { printf("Can not set classifier as u32\n"); return 1; } rtnl_cls_set_prio(cls, prio); rtnl_cls_set_protocol(cls, ETH_P_IP); rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0)); if (htid) rtnl_u32_set_hashtable(cls, htid); rtnl_u32_add_key_uint32(cls, keyval, keymask, keyoff, keyoffmask); rtnl_u32_set_hashmask(cls, hmask, hoffset); rtnl_u32_set_link(cls, htlink); if ((err = rtnl_cls_add(sock, cls, NLM_F_CREATE))) { printf("Can not add classifier: %s\n", nl_geterror(err)); return -1; } rtnl_cls_put(cls); return 0; } /* * function that creates a new hash table */ int u32_add_ht(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, uint32_t htid, uint32_t divisor) { int err; struct rtnl_cls *cls; cls=rtnl_cls_alloc(); if (!(cls)) { printf("Can not allocate classifier\n"); nl_socket_free(sock); exit(1); } rtnl_tc_set_link(TC_CAST(cls), rtnlLink); if ((err = rtnl_tc_set_kind(TC_CAST(cls), "u32"))) { printf("Can not set classifier as u32\n"); return 1; } rtnl_cls_set_prio(cls, prio); rtnl_cls_set_protocol(cls, ETH_P_IP); rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0)); rtnl_u32_set_handle(cls, htid, 0x0, 0x0); //printf("htid: 0x%X\n", htid); rtnl_u32_set_divisor(cls, divisor); if ((err = rtnl_cls_add(sock, cls, NLM_F_CREATE))) { printf("Can not add classifier: %s\n", nl_geterror(err)); return -1; } rtnl_cls_put(cls); return 0; } /* * function that adds a new HTB qdisc and set the default class for unclassified traffic */ int qdisc_add_HTB(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t defaultClass) { struct rtnl_qdisc *qdisc; int err; /* Allocation of a qdisc object */ if (!(qdisc = rtnl_qdisc_alloc())) { printf("Can not allocate Qdisc\n"); return -1; } //rtnl_tc_set_ifindex(TC_CAST(qdisc), master_index); rtnl_tc_set_link(TC_CAST(qdisc), rtnlLink); rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT); //delete the qdisc //printf("Delete current qdisc\n"); rtnl_qdisc_delete(sock, qdisc); //rtnl_qdisc_put(qdisc); //add a HTB qdisc //printf("Add a new HTB qdisc\n"); rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(1,0)); if ((err = rtnl_tc_set_kind(TC_CAST(qdisc), "htb"))) { printf("Can not allocate HTB\n"); return -1; } /* Set default class for unclassified traffic */ //printf("Set default class for unclassified traffic\n"); rtnl_htb_set_defcls(qdisc, TC_HANDLE(1, defaultClass)); rtnl_htb_set_rate2quantum(qdisc, 1); /* Submit request to kernel and wait for response */ if ((err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE))) { printf("Can not allocate HTB Qdisc\n"); return -1; } /* Return the qdisc object to free memory resources */ rtnl_qdisc_put(qdisc); return 0; } /* * function that adds a new HTB class and set its parameters */ int class_add_HTB(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t parentMaj, uint32_t parentMin, uint32_t childMaj, uint32_t childMin, uint64_t rate, uint64_t ceil, uint32_t burst, uint32_t cburst, uint32_t prio ) { int err; struct rtnl_class *class; //struct rtnl_class *class = (struct rtnl_class *) tc; //create a HTB class //class = (struct rtnl_class *)rtnl_class_alloc(); if (!(class = rtnl_class_alloc())) { printf("Can not allocate class object\n"); return 1; } // rtnl_tc_set_link(TC_CAST(class), rtnlLink); //add a HTB qdisc //printf("Add a new HTB class with 0x%X:0x%X on parent 0x%X:0x%X\n", childMaj, childMin, parentMaj, parentMin); rtnl_tc_set_parent(TC_CAST(class), TC_HANDLE(parentMaj, parentMin)); rtnl_tc_set_handle(TC_CAST(class), TC_HANDLE(childMaj, childMin)); if ((err = rtnl_tc_set_kind(TC_CAST(class), "htb"))) { printf("Can not set HTB to class\n"); return 1; } //printf("set HTB class prio to %u\n", prio); rtnl_htb_set_prio((struct rtnl_class *)class, prio); if (rate) { //rate=rate/8; rtnl_htb_set_rate(class, rate); } if (ceil) { //ceil=ceil/8; rtnl_htb_set_ceil(class, ceil); } if (burst) { //printf ("Class HTB: set rate burst: %u\n", burst); rtnl_htb_set_rbuffer(class, burst); } if (cburst) { //printf ("Class HTB: set rate cburst: %u\n", cburst); rtnl_htb_set_cbuffer(class, cburst); } /* Submit request to kernel and wait for response */ if ((err = rtnl_class_add(sock, class, NLM_F_CREATE))) { printf("Can not allocate HTB Qdisc\n"); return 1; } rtnl_class_put(class); return 0; } /* * function that adds a HTB root class and set its parameters */ int class_add_HTB_root(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint64_t rate, uint64_t ceil, uint32_t burst, uint32_t cburst ) { int err; struct rtnl_class *class; //create a HTB class class = (struct rtnl_class *)rtnl_class_alloc(); //class = rtnl_class_alloc(); if (!class) { printf("Can not allocate class object\n"); return 1; } // rtnl_tc_set_link(TC_CAST(class), rtnlLink); rtnl_tc_set_parent(TC_CAST(class), TC_H_ROOT); //add a HTB class //printf("Add a new HTB ROOT class\n"); rtnl_tc_set_handle(TC_CAST(class), 1); if ((err = rtnl_tc_set_kind(TC_CAST(class), "htb"))) { printf("Can not set HTB to class\n"); return 1; } if (rate) { //rate=rate/8; rtnl_htb_set_rate(class, rate); } if (ceil) { //ceil=ceil/8; rtnl_htb_set_ceil(class, ceil); } if (burst) { rtnl_htb_set_rbuffer(class, burst); } if (cburst) { rtnl_htb_set_cbuffer(class, cburst); } /* Submit request to kernel and wait for response */ if ((err = rtnl_class_add(sock, class, NLM_F_CREATE))) { printf("Can not allocate HTB Qdisc\n"); return 1; } rtnl_class_put(class); return 0; } /* * function that adds a new SFQ qdisc as a leaf for a HTB class */ int qdisc_add_SFQ_leaf(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t parentMaj, uint32_t parentMin, int quantum, int limit, int perturb ) { int err; struct rtnl_qdisc *qdisc; if (!(qdisc = rtnl_qdisc_alloc())) { printf("Can not allocate qdisc object\n"); return 1; } rtnl_tc_set_link(TC_CAST(qdisc), rtnlLink); rtnl_tc_set_parent(TC_CAST(qdisc), TC_HANDLE(parentMaj, parentMin)); rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(parentMin,0)); if ((err = rtnl_tc_set_kind(TC_CAST(qdisc), "sfq"))) { printf("Can not set SQF class\n"); return 1; } if(quantum) { rtnl_sfq_set_quantum(qdisc, quantum); } else { rtnl_sfq_set_quantum(qdisc, 16000); // tc default value } if(limit) { rtnl_sfq_set_limit(qdisc, limit); // default is 127 } if(perturb) { rtnl_sfq_set_perturb(qdisc, perturb); // default never perturb the hash } /* Submit request to kernel and wait for response */ if ((err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE))) { printf("Can not allocate SFQ qdisc\n"); return -1; } /* Return the qdisc object to free memory resources */ rtnl_qdisc_put(qdisc); return 0; } int main() { struct nl_sock *sock; struct rtnl_link *link; //struct rtnl_qdisc *qdisc; //struct rtnl_class *class; //struct rtnl_cls *cls; uint32_t ht, htlink, htid, direction, classid; //uint32_t hash, hashmask, nodeid, divisor, handle; //struct rtnl_u32 *f_u32; char chashlink[16]=""; //uint64_t drops, qlen; //int master_index; int err; //uint64_t rate=0, ceil=0; struct nl_cache *link_cache; if (!(sock = nl_socket_alloc())) { printf("Unable to allocate netlink socket\n"); exit(1); } if ((err = nl_connect(sock, NETLINK_ROUTE)) < 0 ) { printf("Nu s-a putut conecta la NETLINK!\n"); nl_socket_free(sock); exit(1); } if ((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache)) < 0) { printf("Unable to allocate link cache: %s\n", nl_geterror(err)); nl_socket_free(sock); exit(1); } /* lookup interface index of eth0 */ if (!(link = rtnl_link_get_by_name(link_cache, "imq0"))) { /* error */ printf("Interface not found\n"); nl_socket_free(sock); exit(1); } err=qdisc_add_HTB(sock, link, 0xffff); //drops = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_DROPS); //printf("Add ROOT HTB class\n"); err=class_add_HTB_root(sock, link, 12500000, 12500000, 25000, 25000); err=class_add_HTB(sock, link, 1, 0, 1, 0xffff, 1250000, 12500000, 25000, 25000, 5); err=qdisc_add_SFQ_leaf(sock, link, 1, 0xffff, 16000, 0, 10); err=class_add_HTB(sock, link, 1, 1, 1, 0x5, 2000000, 2000000, 25000, 25000, 5); err=qdisc_add_SFQ_leaf(sock, link, 1, 0x5, 16000, 0, 10); err=class_add_HTB(sock, link, 1, 1, 1, 0x6, 1000000, 1000000, 25000, 25000, 5); err=qdisc_add_SFQ_leaf(sock, link, 1, 0x6, 16000, 0, 10); //err=class_add_HTB(sock, link, 1, 0, 1, 0x7, 1024000, 100000000, 5); //err=class_add_HTB(sock, link, 1, 0, 1, 0x8, 2048000, 100000000, 5); //err=class_add_HTB(sock, link, 1, 0, 1, 0x9, 4096000, 100000000, 5); //err=class_add_HTB(sock, link, 1, 0, 1, 0xa, 8192000, 100000000, 5); //printf("Add main hash table\n"); /* create u32 first hash filter table * */ /* formula calcul handle: * uint32_t handle = (htid << 20) | (hash << 12) | nodeid; */ /* * Upper limit of number of hash tables: 4096 (0xFFF) * Number of hashes in a table: 256 values (0xFF) * */ /* using 256 values for hash table * each entry in hash table match a byte from IP address specified later by a hash key */ uint32_t i; for (i = 1; i <= 0xf; i++) u32_add_ht(sock, link, 1, i, 256); /* * attach a u32 filter to the first hash * that redirects all traffic and make a hash key * from the fist byte of the IP address * */ //divisor=0x0; // unused here //handle = 0x0; // unused here //hash = 0x0; // unused here //htid = 0x0; // unused here //nodeid = 0x0; // unused here // direction = 12 -> source IP // direction = 16 -> destination IP direction = 16; /* * which hash table will use * in our case is hash table no 1 defined previous * * There are 2 posibilities to set the the hash table: * 1. Using function get_u32_handle and sent a string in * format 10: where 10 is number of the hash table * 2. Create your own value in format: 0xa00000 * */ strcpy(chashlink, "1:"); //printf("Hash Link: %s\n", chashlink); //chashlink=malloc(sizeof(char) * htlink = 0x0; // is used by get_u32_handle to return the correct value of hash table (link) if(get_u32_handle(&htlink, chashlink)) { printf ("Illegal \"link\""); nl_socket_free(sock); exit(1); } //printf ("hash link : 0x%X\n", htlink); //printf ("hash link test : %u\n", (htlink && TC_U32_NODE(htlink))); if (htlink && TC_U32_NODE(htlink)) { printf("\"link\" must be a hash table.\n"); nl_socket_free(sock); exit(1); } /* the hash mask will hit the hash table (link) no 1: in our case */ /* set the hash key mask */ //hashmask = 0xFF000000UL; // the mask that is used to match the hash in specific table, in our case for example 1:a with mean the first byte which is 10 in hash table 1 /* Here we add a hash filter which match the first byte (see the hashmask value) * of the source IP (offset 12 in the packet header) * You can use also offset 16 to match the destination IP */ /* * Also we need a filter to match our rule * This mean that we will put a 0.0.0.0/0 filter in our first rule * that match the offset 12 (source IP) * Also you can put offset 16 to match the destination IP */ u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0, 0x0, direction, 0, 0, htlink, 0xff000000, direction); /* * For each first byte that we need to match we will create a new hash table * For example: you have those clases: 10.0.0.0/24 and 172.16.0.0/23 * For byte 10 and byte 172 will create a separate hash table that will match the second * byte from each class. * */ // Create a new hash table with prio 1, id 2 and 256 entries // u32_CreateNewHashTable(sock, link, 1, 2, 256); // Create a new hash table with prio 1, id 3 and 256 entries // u32_CreateNewHashTable(sock, link, 1, 3, 256); // u32_CreateNewHashTable(sock, link, 1, 4, 256); // u32_CreateNewHashTable(sock, link, 1, 5, 256); /* * Now we will create other filter under (ATENTION) our first hash table (link) 1: * Previous rule redirects the trafic according the hash mask to hash table (link) no 1: * Here we will match the hash tables from 1:0 to 1:ff. Under each hash table we will attach * other rules that matches next byte from IP source/destination IP and we will repeat the * previous steps. * */ // /8 check // 10.0.0.0/8 ht=get_u32_parse_handle("1:a:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("2:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0a000000, 0xff000000, direction, 0, htid, htlink, 0x00ff0000, direction); // 172.0.0.0/8 ht=get_u32_parse_handle("1:ac:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("3:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0xac000000, 0xff000000, direction, 0, htid, htlink, 0x00ff0000, direction); // /16 check // 10.0.0.0/16 ht=get_u32_parse_handle("2:0:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("4:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0a000000, 0xffff0000, direction, 0, htid, htlink, 0x0000ff00, direction); // 172.17.0.0/16 ht=get_u32_parse_handle("3:11:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("5:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0xac110000, 0xffff0000, direction, 0, htid, htlink, 0x0000ff00, direction); // /24 check // 10.0.9.0/24 ht=get_u32_parse_handle("4:9:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("6:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0a000900, 0xffffff00, direction, 0, htid, htlink, 0x000000ff, direction); // 172.17.2.0/16 ht=get_u32_parse_handle("5:2:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("7:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0xac110200, 0xffffff00, direction, 0, htid, htlink, 0x000000ff, direction); // final filters // 10.0.9.20 ht=get_u32_parse_handle("6:14:"); htid = (ht&0xFFFFF000); err = get_tc_classid(&classid, "1:5"); u32_add_filter_on_ht(sock, link, 1, 0x0a000914, 0xffffffff, direction, 0, htid, classid); // 172.17.2.120 ht=get_u32_parse_handle("7:78:"); htid = (ht&0xFFFFF000); err = get_tc_classid(&classid, "1:6"); u32_add_filter_on_ht(sock, link, 1, 0xac110278, 0xffffffff, direction, 0, htid, classid); nl_socket_free(sock); return 0; } libnl-3.2.29/tests/test-nf-cache-mngr.c0000644000175000017500000000221513023014600014505 00000000000000#include static void change_cb(struct nl_cache *cache, struct nl_object *obj, int action, void *data) { struct nfnl_ct *ct = (struct nfnl_ct *) obj; static struct nl_addr *hack = NULL; if (!hack) nl_addr_parse("194.88.212.233", AF_INET, &hack); if (!nl_addr_cmp(hack, nfnl_ct_get_src(ct, 1)) || !nl_addr_cmp(hack, nfnl_ct_get_dst(ct, 1))) { struct nl_dump_params dp = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; printf("UPDATE "); nl_object_dump(obj, &dp); } } int main(int argc, char *argv[]) { struct nl_cache_mngr *mngr; struct nl_sock *sock; struct nl_cache *ct; int err; sock = nl_cli_alloc_socket(); err = nl_cache_mngr_alloc(sock, NETLINK_NETFILTER, NL_AUTO_PROVIDE, &mngr); if (err < 0) { nl_perror(err, "nl_cache_mngr_alloc"); return -1; } err = nl_cache_mngr_add(mngr, "netfilter/ct", &change_cb, NULL, &ct); if (err < 0) { nl_perror(err, "nl_cache_mngr_add(netfilter/ct)"); return -1; } for (;;) { int err = nl_cache_mngr_poll(mngr, 5000); if (err < 0) { nl_perror(err, "nl_cache_mngr_poll()"); return -1; } } nl_cache_mngr_free(mngr); return 0; } libnl-3.2.29/tests/test-socket-creation.c0000644000175000017500000000114513023014600015173 00000000000000#include #include int main(int argc, char *argv[]) { struct nl_sock *h[1025]; int i; h[0] = nl_socket_alloc(); printf("Created handle with port 0x%x\n", nl_socket_get_local_port(h[0])); nl_socket_free(h[0]); h[0] = nl_socket_alloc(); printf("Created handle with port 0x%x\n", nl_socket_get_local_port(h[0])); nl_socket_free(h[0]); for (i = 0; i < 1025; i++) { h[i] = nl_socket_alloc(); if (h[i] == NULL) nl_perror(ENOMEM, "Unable to allocate socket"); else printf("Created handle with port 0x%x\n", nl_socket_get_local_port(h[i])); } return 0; } libnl-3.2.29/tests/test-cache-mngr.c0000644000175000017500000000246513023014600014113 00000000000000#include #include #include #include #include static int quit = 0; static struct nl_dump_params dp = { .dp_type = NL_DUMP_LINE, }; static void change_cb(struct nl_cache *cache, struct nl_object *obj, int action, void *data) { if (action == NL_ACT_NEW) printf("NEW "); else if (action == NL_ACT_DEL) printf("DEL "); else if (action == NL_ACT_CHANGE) printf("CHANGE "); nl_object_dump(obj, &dp); } static void sigint(int arg) { quit = 1; } int main(int argc, char *argv[]) { struct nl_cache_mngr *mngr; struct nl_cache *cache; int err, i; dp.dp_fd = stdout; signal(SIGINT, sigint); err = nl_cache_mngr_alloc(NULL, NETLINK_ROUTE, NL_AUTO_PROVIDE, &mngr); if (err < 0) nl_cli_fatal(err, "Unable to allocate cache manager: %s", nl_geterror(err)); for (i = 1; i < argc; i++) { err = nl_cache_mngr_add(mngr, argv[i], &change_cb, NULL, &cache); if (err < 0) nl_cli_fatal(err, "Unable to add cache %s: %s", argv[i], nl_geterror(err)); } while (!quit) { int err = nl_cache_mngr_poll(mngr, 1000); if (err < 0 && err != -NLE_INTR) nl_cli_fatal(err, "Polling failed: %s", nl_geterror(err)); nl_cache_mngr_info(mngr, &dp); } nl_cache_mngr_free(mngr); return 0; } libnl-3.2.29/tests/test-create-vrf.c0000644000175000017500000000237713023014600014147 00000000000000#include #include #include int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link, *link2; struct nl_sock *sk; uint32_t tb_id; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if (!(link = rtnl_link_vrf_alloc())) { fprintf(stderr, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "vrf-red"); if ((err = rtnl_link_vrf_set_tableid(link, 10)) < 0) { nl_perror(err, "Unable to set VRF table id"); return err; } if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(link2 = rtnl_link_get_by_name(link_cache, "vrf-red"))) { fprintf(stderr, "Unable to lookup vrf-red"); return -1; } if ((err = rtnl_link_vrf_get_tableid(link2, &tb_id)) < 0) { nl_perror(err, "Unable to get VRF table id"); return err; } if (tb_id != 10) { fprintf(stderr, "Mismatch with VRF table id\n"); } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-delete-link.c0000644000175000017500000000100613023014600014272 00000000000000#include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_sock *sk; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } link = rtnl_link_alloc(); rtnl_link_set_name(link, "my_bond"); if ((err = rtnl_link_delete(sk, link)) < 0) { nl_perror(err, "Unable to delete link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-bond.c0000644000175000017500000000107313023014600014264 00000000000000#include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_sock *sk; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } link = rtnl_link_bond_alloc(); rtnl_link_set_name(link, "my_bond"); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-genl.c0000644000175000017500000000621013023014600013024 00000000000000#include #include static struct nla_policy attr_policy[TASKSTATS_TYPE_MAX+1] = { [TASKSTATS_TYPE_PID] = { .type = NLA_U32 }, [TASKSTATS_TYPE_TGID] = { .type = NLA_U32 }, [TASKSTATS_TYPE_STATS] = { .minlen = sizeof(struct taskstats) }, [TASKSTATS_TYPE_AGGR_PID] = { .type = NLA_NESTED }, [TASKSTATS_TYPE_AGGR_TGID] = { .type = NLA_NESTED }, }; static int parse_cmd_new(struct nl_cache_ops *unused, struct genl_cmd *cmd, struct genl_info *info, void *arg) { struct nlattr *attrs[TASKSTATS_TYPE_MAX+1]; struct nlattr *nested; int err; if (info->attrs[TASKSTATS_TYPE_AGGR_PID]) nested = info->attrs[TASKSTATS_TYPE_AGGR_PID]; else if (info->attrs[TASKSTATS_TYPE_AGGR_TGID]) nested = info->attrs[TASKSTATS_TYPE_AGGR_TGID]; else { fprintf(stderr, "Invalid taskstats message: Unable to find " "nested attribute/\n"); return NL_SKIP; } err = nla_parse_nested(attrs, TASKSTATS_TYPE_MAX, nested, attr_policy); if (err < 0) { nl_perror(err, "Error while parsing generic netlink message"); return err; } if (attrs[TASKSTATS_TYPE_STATS]) { struct taskstats *stats = nla_data(attrs[TASKSTATS_TYPE_STATS]); printf("%s pid %u uid %u gid %u parent %u\n", stats->ac_comm, stats->ac_pid, stats->ac_uid, stats->ac_gid, stats->ac_ppid); } return 0; } static int parse_cb(struct nl_msg *msg, void *arg) { return genl_handle_msg(msg, NULL); } static struct genl_cmd cmds[] = { { .c_id = TASKSTATS_CMD_NEW, .c_name = "taskstats_new()", .c_maxattr = TASKSTATS_TYPE_MAX, .c_attr_policy = attr_policy, .c_msg_parser = &parse_cmd_new, }, }; #define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) static struct genl_ops ops = { .o_name = TASKSTATS_GENL_NAME, .o_cmds = cmds, .o_ncmds = ARRAY_SIZE(cmds), }; int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_msg *msg; void *hdr; int err; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_GENERIC); if ((err = genl_register_family(&ops)) < 0) nl_cli_fatal(err, "Unable to register Generic Netlink family"); if ((err = genl_ops_resolve(sock, &ops)) < 0) nl_cli_fatal(err, "Unable to resolve family name"); if (genl_ctrl_resolve(sock, "nlctrl") != GENL_ID_CTRL) nl_cli_fatal(NLE_INVAL, "Resolving of \"nlctrl\" failed"); msg = nlmsg_alloc(); if (msg == NULL) nl_cli_fatal(NLE_NOMEM, "Unable to allocate netlink message"); hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ops.o_id, 0, 0, TASKSTATS_CMD_GET, TASKSTATS_GENL_VERSION); if (hdr == NULL) nl_cli_fatal(ENOMEM, "Unable to write genl header"); if ((err = nla_put_u32(msg, TASKSTATS_CMD_ATTR_PID, 1)) < 0) nl_cli_fatal(err, "Unable to add attribute: %s", nl_geterror(err)); if ((err = nl_send_auto_complete(sock, msg)) < 0) nl_cli_fatal(err, "Unable to send message: %s", nl_geterror(err)); nlmsg_free(msg); if ((err = nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, parse_cb, NULL)) < 0) nl_cli_fatal(err, "Unable to modify valid message callback"); if ((err = nl_recvmsgs_default(sock)) < 0) nl_cli_fatal(err, "Unable to receive message: %s", nl_geterror(err)); nl_close(sock); nl_socket_free(sock); return 0; } libnl-3.2.29/tests/test-create-vxlan.c0000644000175000017500000000176013023014600014475 00000000000000#include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_addr *addr; struct nl_sock *sk; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } link = rtnl_link_vxlan_alloc(); rtnl_link_set_name(link, "vxlan128"); if ((err = rtnl_link_vxlan_set_id(link, 128)) < 0) { nl_perror(err, "Unable to set VXLAN network identifier"); return err; } if ((err = nl_addr_parse("239.0.0.1", AF_INET, &addr)) < 0) { nl_perror(err, "Unable to parse IP address"); return err; } if ((err = rtnl_link_vxlan_set_group(link, addr)) < 0) { nl_perror(err, "Unable to set multicast IP address"); return err; } nl_addr_put(addr); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-macsec.c0000644000175000017500000000202613023014600014574 00000000000000#include #include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; int err, master_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(master_index = rtnl_link_name2i(link_cache, "eth0"))) { fprintf(stderr, "Unable to lookup eth0"); return -1; } link = rtnl_link_macsec_alloc(); rtnl_link_set_link(link, master_index); rtnl_link_macsec_set_port(link, 10); rtnl_link_macsec_set_encrypt(link, 1); rtnl_link_macsec_set_replay_protect(link, 1); rtnl_link_macsec_set_window(link, 200); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-create-ipvti.c0000644000175000017500000000226513023014600014501 00000000000000#include #include int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "ens33"); if (!if_index) { fprintf(stderr, "Unable to lookup ens33"); return -1; } link = rtnl_link_ipvti_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "ipvti-tun"); rtnl_link_ipvti_set_link(link, if_index); inet_pton(AF_INET, "192.168.254.12", &addr.s_addr); rtnl_link_ipvti_set_local(link, addr.s_addr); inet_pton(AF_INET, "192.168.254.13", &addr.s_addr); rtnl_link_ipvti_set_remote(link, addr.s_addr); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/Makefile.in0000644000175000017500000016356613031473644013065 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_UNIT_TESTS_TRUE@check_PROGRAMS = test-create-bond$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-vlan$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-vxlan$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-veth$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-bridge$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ip6tnl$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ipgre$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ipgretap$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ipip$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ipvti$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-macsec$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-macvlan$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-macvtap$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ipvlan$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-vrf$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-sit$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ifb$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-delete-link$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-socket-creation$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-complex-HTB-with-hash-filters$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ test-u32-filter-with-actions$(EXEEXT) \ @ENABLE_UNIT_TESTS_TRUE@ $(am__EXEEXT_1) $(am__EXEEXT_2) @ENABLE_UNIT_TESTS_TRUE@TESTS = $(am__EXEEXT_1) @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@am__append_1 = ${top_builddir}/src/lib/libnl-cli-3.la @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@am__append_2 = \ @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@ test-cache-mngr \ @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@ test-genl \ @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@ test-nf-cache-mngr subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @ENABLE_UNIT_TESTS_TRUE@am__EXEEXT_1 = check-all$(EXEEXT) @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@am__EXEEXT_2 = test-cache-mngr$(EXEEXT) \ @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@ test-genl$(EXEEXT) \ @ENABLE_CLI_TRUE@@ENABLE_UNIT_TESTS_TRUE@ test-nf-cache-mngr$(EXEEXT) am__check_all_SOURCES_DIST = check-all.c check-addr.c check-attr.c @ENABLE_UNIT_TESTS_TRUE@am_check_all_OBJECTS = check-all.$(OBJEXT) \ @ENABLE_UNIT_TESTS_TRUE@ check-addr.$(OBJEXT) \ @ENABLE_UNIT_TESTS_TRUE@ check-attr.$(OBJEXT) check_all_OBJECTS = $(am_check_all_OBJECTS) check_all_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@check_all_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__test_cache_mngr_SOURCES_DIST = test-cache-mngr.c @ENABLE_UNIT_TESTS_TRUE@am_test_cache_mngr_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-cache-mngr.$(OBJEXT) test_cache_mngr_OBJECTS = $(am_test_cache_mngr_OBJECTS) test_cache_mngr_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_cache_mngr_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_complex_HTB_with_hash_filters_SOURCES_DIST = \ test-complex-HTB-with-hash-filters.c @ENABLE_UNIT_TESTS_TRUE@am_test_complex_HTB_with_hash_filters_OBJECTS = test-complex-HTB-with-hash-filters.$(OBJEXT) test_complex_HTB_with_hash_filters_OBJECTS = \ $(am_test_complex_HTB_with_hash_filters_OBJECTS) test_complex_HTB_with_hash_filters_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_complex_HTB_with_hash_filters_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_create_bond_SOURCES_DIST = test-create-bond.c @ENABLE_UNIT_TESTS_TRUE@am_test_create_bond_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-create-bond.$(OBJEXT) test_create_bond_OBJECTS = $(am_test_create_bond_OBJECTS) test_create_bond_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_bond_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_create_bridge_SOURCES_DIST = test-create-bridge.c @ENABLE_UNIT_TESTS_TRUE@am_test_create_bridge_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-create-bridge.$(OBJEXT) test_create_bridge_OBJECTS = $(am_test_create_bridge_OBJECTS) test_create_bridge_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_bridge_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_create_ifb_SOURCES_DIST = test-create-ifb.c @ENABLE_UNIT_TESTS_TRUE@am_test_create_ifb_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-create-ifb.$(OBJEXT) test_create_ifb_OBJECTS = $(am_test_create_ifb_OBJECTS) test_create_ifb_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_ifb_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_ip6tnl_SOURCES = test-create-ip6tnl.c test_create_ip6tnl_OBJECTS = test-create-ip6tnl.$(OBJEXT) test_create_ip6tnl_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_ip6tnl_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_ipgre_SOURCES = test-create-ipgre.c test_create_ipgre_OBJECTS = test-create-ipgre.$(OBJEXT) test_create_ipgre_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_ipgre_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_ipgretap_SOURCES = test-create-ipgretap.c test_create_ipgretap_OBJECTS = test-create-ipgretap.$(OBJEXT) test_create_ipgretap_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_ipgretap_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_ipip_SOURCES = test-create-ipip.c test_create_ipip_OBJECTS = test-create-ipip.$(OBJEXT) test_create_ipip_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_ipip_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_ipvlan_SOURCES = test-create-ipvlan.c test_create_ipvlan_OBJECTS = test-create-ipvlan.$(OBJEXT) test_create_ipvlan_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_ipvlan_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_ipvti_SOURCES = test-create-ipvti.c test_create_ipvti_OBJECTS = test-create-ipvti.$(OBJEXT) test_create_ipvti_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_ipvti_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_macsec_SOURCES = test-create-macsec.c test_create_macsec_OBJECTS = test-create-macsec.$(OBJEXT) test_create_macsec_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_macsec_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_macvlan_SOURCES = test-create-macvlan.c test_create_macvlan_OBJECTS = test-create-macvlan.$(OBJEXT) test_create_macvlan_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_macvlan_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_macvtap_SOURCES = test-create-macvtap.c test_create_macvtap_OBJECTS = test-create-macvtap.$(OBJEXT) test_create_macvtap_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_macvtap_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_sit_SOURCES = test-create-sit.c test_create_sit_OBJECTS = test-create-sit.$(OBJEXT) test_create_sit_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_sit_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_create_veth_SOURCES_DIST = test-create-veth.c @ENABLE_UNIT_TESTS_TRUE@am_test_create_veth_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-create-veth.$(OBJEXT) test_create_veth_OBJECTS = $(am_test_create_veth_OBJECTS) test_create_veth_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_veth_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_create_vlan_SOURCES_DIST = test-create-vlan.c @ENABLE_UNIT_TESTS_TRUE@am_test_create_vlan_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-create-vlan.$(OBJEXT) test_create_vlan_OBJECTS = $(am_test_create_vlan_OBJECTS) test_create_vlan_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_vlan_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) test_create_vrf_SOURCES = test-create-vrf.c test_create_vrf_OBJECTS = test-create-vrf.$(OBJEXT) test_create_vrf_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_vrf_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_create_vxlan_SOURCES_DIST = test-create-vxlan.c @ENABLE_UNIT_TESTS_TRUE@am_test_create_vxlan_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-create-vxlan.$(OBJEXT) test_create_vxlan_OBJECTS = $(am_test_create_vxlan_OBJECTS) test_create_vxlan_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_create_vxlan_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_delete_link_SOURCES_DIST = test-delete-link.c @ENABLE_UNIT_TESTS_TRUE@am_test_delete_link_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-delete-link.$(OBJEXT) test_delete_link_OBJECTS = $(am_test_delete_link_OBJECTS) test_delete_link_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_delete_link_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_genl_SOURCES_DIST = test-genl.c @ENABLE_UNIT_TESTS_TRUE@am_test_genl_OBJECTS = test-genl.$(OBJEXT) test_genl_OBJECTS = $(am_test_genl_OBJECTS) test_genl_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_genl_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_nf_cache_mngr_SOURCES_DIST = test-nf-cache-mngr.c @ENABLE_UNIT_TESTS_TRUE@am_test_nf_cache_mngr_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-nf-cache-mngr.$(OBJEXT) test_nf_cache_mngr_OBJECTS = $(am_test_nf_cache_mngr_OBJECTS) test_nf_cache_mngr_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_nf_cache_mngr_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_socket_creation_SOURCES_DIST = test-socket-creation.c @ENABLE_UNIT_TESTS_TRUE@am_test_socket_creation_OBJECTS = \ @ENABLE_UNIT_TESTS_TRUE@ test-socket-creation.$(OBJEXT) test_socket_creation_OBJECTS = $(am_test_socket_creation_OBJECTS) test_socket_creation_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_socket_creation_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) am__test_u32_filter_with_actions_SOURCES_DIST = \ test-u32-filter-with-actions.c @ENABLE_UNIT_TESTS_TRUE@am_test_u32_filter_with_actions_OBJECTS = test-u32-filter-with-actions.$(OBJEXT) test_u32_filter_with_actions_OBJECTS = \ $(am_test_u32_filter_with_actions_OBJECTS) test_u32_filter_with_actions_LDADD = $(LDADD) @ENABLE_UNIT_TESTS_TRUE@test_u32_filter_with_actions_DEPENDENCIES = \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ $(am__append_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/lib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(check_all_SOURCES) $(test_cache_mngr_SOURCES) \ $(test_complex_HTB_with_hash_filters_SOURCES) \ $(test_create_bond_SOURCES) $(test_create_bridge_SOURCES) \ $(test_create_ifb_SOURCES) test-create-ip6tnl.c \ test-create-ipgre.c test-create-ipgretap.c test-create-ipip.c \ test-create-ipvlan.c test-create-ipvti.c test-create-macsec.c \ test-create-macvlan.c test-create-macvtap.c test-create-sit.c \ $(test_create_veth_SOURCES) $(test_create_vlan_SOURCES) \ test-create-vrf.c $(test_create_vxlan_SOURCES) \ $(test_delete_link_SOURCES) $(test_genl_SOURCES) \ $(test_nf_cache_mngr_SOURCES) $(test_socket_creation_SOURCES) \ $(test_u32_filter_with_actions_SOURCES) DIST_SOURCES = $(am__check_all_SOURCES_DIST) \ $(am__test_cache_mngr_SOURCES_DIST) \ $(am__test_complex_HTB_with_hash_filters_SOURCES_DIST) \ $(am__test_create_bond_SOURCES_DIST) \ $(am__test_create_bridge_SOURCES_DIST) \ $(am__test_create_ifb_SOURCES_DIST) test-create-ip6tnl.c \ test-create-ipgre.c test-create-ipgretap.c test-create-ipip.c \ test-create-ipvlan.c test-create-ipvti.c test-create-macsec.c \ test-create-macvlan.c test-create-macvtap.c test-create-sit.c \ $(am__test_create_veth_SOURCES_DIST) \ $(am__test_create_vlan_SOURCES_DIST) test-create-vrf.c \ $(am__test_create_vxlan_SOURCES_DIST) \ $(am__test_delete_link_SOURCES_DIST) \ $(am__test_genl_SOURCES_DIST) \ $(am__test_nf_cache_mngr_SOURCES_DIST) \ $(am__test_socket_creation_SOURCES_DIST) \ $(am__test_u32_filter_with_actions_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp \ $(top_srcdir)/build-aux/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ util.h @ENABLE_UNIT_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_UNIT_TESTS_TRUE@ -Wall \ @ENABLE_UNIT_TESTS_TRUE@ -I${top_srcdir}/include/linux-private \ @ENABLE_UNIT_TESTS_TRUE@ -I${top_srcdir}/include \ @ENABLE_UNIT_TESTS_TRUE@ -I${top_builddir}/include \ @ENABLE_UNIT_TESTS_TRUE@ -D_GNU_SOURCE \ @ENABLE_UNIT_TESTS_TRUE@ -DSYSCONFDIR=\"$(sysconfdir)/libnl\" @ENABLE_UNIT_TESTS_TRUE@LDADD = ${top_builddir}/lib/libnl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-nf-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-genl-3.la \ @ENABLE_UNIT_TESTS_TRUE@ ${top_builddir}/lib/libnl-route-3.la \ @ENABLE_UNIT_TESTS_TRUE@ @CHECK_LIBS@ $(am__append_1) @ENABLE_UNIT_TESTS_TRUE@AM_CFLAGS = @CHECK_CFLAGS@ @ENABLE_UNIT_TESTS_TRUE@UNIT_TESTS = check-all @ENABLE_UNIT_TESTS_TRUE@test_cache_mngr_SOURCES = test-cache-mngr.c @ENABLE_UNIT_TESTS_TRUE@test_create_bond_SOURCES = test-create-bond.c @ENABLE_UNIT_TESTS_TRUE@test_create_vlan_SOURCES = test-create-vlan.c @ENABLE_UNIT_TESTS_TRUE@test_create_vxlan_SOURCES = test-create-vxlan.c @ENABLE_UNIT_TESTS_TRUE@test_create_veth_SOURCES = test-create-veth.c @ENABLE_UNIT_TESTS_TRUE@test_create_bridge_SOURCES = test-create-bridge.c @ENABLE_UNIT_TESTS_TRUE@test_create_ifb_SOURCES = test-create-ifb.c @ENABLE_UNIT_TESTS_TRUE@test_delete_link_SOURCES = test-delete-link.c @ENABLE_UNIT_TESTS_TRUE@test_genl_SOURCES = test-genl.c @ENABLE_UNIT_TESTS_TRUE@test_nf_cache_mngr_SOURCES = test-nf-cache-mngr.c @ENABLE_UNIT_TESTS_TRUE@test_socket_creation_SOURCES = test-socket-creation.c @ENABLE_UNIT_TESTS_TRUE@test_complex_HTB_with_hash_filters_SOURCES = test-complex-HTB-with-hash-filters.c @ENABLE_UNIT_TESTS_TRUE@test_u32_filter_with_actions_SOURCES = test-u32-filter-with-actions.c # Unit tests @ENABLE_UNIT_TESTS_TRUE@check_all_SOURCES = \ @ENABLE_UNIT_TESTS_TRUE@ check-all.c \ @ENABLE_UNIT_TESTS_TRUE@ check-addr.c \ @ENABLE_UNIT_TESTS_TRUE@ check-attr.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list check-all$(EXEEXT): $(check_all_OBJECTS) $(check_all_DEPENDENCIES) $(EXTRA_check_all_DEPENDENCIES) @rm -f check-all$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_all_OBJECTS) $(check_all_LDADD) $(LIBS) test-cache-mngr$(EXEEXT): $(test_cache_mngr_OBJECTS) $(test_cache_mngr_DEPENDENCIES) $(EXTRA_test_cache_mngr_DEPENDENCIES) @rm -f test-cache-mngr$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_cache_mngr_OBJECTS) $(test_cache_mngr_LDADD) $(LIBS) test-complex-HTB-with-hash-filters$(EXEEXT): $(test_complex_HTB_with_hash_filters_OBJECTS) $(test_complex_HTB_with_hash_filters_DEPENDENCIES) $(EXTRA_test_complex_HTB_with_hash_filters_DEPENDENCIES) @rm -f test-complex-HTB-with-hash-filters$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_complex_HTB_with_hash_filters_OBJECTS) $(test_complex_HTB_with_hash_filters_LDADD) $(LIBS) test-create-bond$(EXEEXT): $(test_create_bond_OBJECTS) $(test_create_bond_DEPENDENCIES) $(EXTRA_test_create_bond_DEPENDENCIES) @rm -f test-create-bond$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_bond_OBJECTS) $(test_create_bond_LDADD) $(LIBS) test-create-bridge$(EXEEXT): $(test_create_bridge_OBJECTS) $(test_create_bridge_DEPENDENCIES) $(EXTRA_test_create_bridge_DEPENDENCIES) @rm -f test-create-bridge$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_bridge_OBJECTS) $(test_create_bridge_LDADD) $(LIBS) test-create-ifb$(EXEEXT): $(test_create_ifb_OBJECTS) $(test_create_ifb_DEPENDENCIES) $(EXTRA_test_create_ifb_DEPENDENCIES) @rm -f test-create-ifb$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_ifb_OBJECTS) $(test_create_ifb_LDADD) $(LIBS) test-create-ip6tnl$(EXEEXT): $(test_create_ip6tnl_OBJECTS) $(test_create_ip6tnl_DEPENDENCIES) $(EXTRA_test_create_ip6tnl_DEPENDENCIES) @rm -f test-create-ip6tnl$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_ip6tnl_OBJECTS) $(test_create_ip6tnl_LDADD) $(LIBS) test-create-ipgre$(EXEEXT): $(test_create_ipgre_OBJECTS) $(test_create_ipgre_DEPENDENCIES) $(EXTRA_test_create_ipgre_DEPENDENCIES) @rm -f test-create-ipgre$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_ipgre_OBJECTS) $(test_create_ipgre_LDADD) $(LIBS) test-create-ipgretap$(EXEEXT): $(test_create_ipgretap_OBJECTS) $(test_create_ipgretap_DEPENDENCIES) $(EXTRA_test_create_ipgretap_DEPENDENCIES) @rm -f test-create-ipgretap$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_ipgretap_OBJECTS) $(test_create_ipgretap_LDADD) $(LIBS) test-create-ipip$(EXEEXT): $(test_create_ipip_OBJECTS) $(test_create_ipip_DEPENDENCIES) $(EXTRA_test_create_ipip_DEPENDENCIES) @rm -f test-create-ipip$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_ipip_OBJECTS) $(test_create_ipip_LDADD) $(LIBS) test-create-ipvlan$(EXEEXT): $(test_create_ipvlan_OBJECTS) $(test_create_ipvlan_DEPENDENCIES) $(EXTRA_test_create_ipvlan_DEPENDENCIES) @rm -f test-create-ipvlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_ipvlan_OBJECTS) $(test_create_ipvlan_LDADD) $(LIBS) test-create-ipvti$(EXEEXT): $(test_create_ipvti_OBJECTS) $(test_create_ipvti_DEPENDENCIES) $(EXTRA_test_create_ipvti_DEPENDENCIES) @rm -f test-create-ipvti$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_ipvti_OBJECTS) $(test_create_ipvti_LDADD) $(LIBS) test-create-macsec$(EXEEXT): $(test_create_macsec_OBJECTS) $(test_create_macsec_DEPENDENCIES) $(EXTRA_test_create_macsec_DEPENDENCIES) @rm -f test-create-macsec$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_macsec_OBJECTS) $(test_create_macsec_LDADD) $(LIBS) test-create-macvlan$(EXEEXT): $(test_create_macvlan_OBJECTS) $(test_create_macvlan_DEPENDENCIES) $(EXTRA_test_create_macvlan_DEPENDENCIES) @rm -f test-create-macvlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_macvlan_OBJECTS) $(test_create_macvlan_LDADD) $(LIBS) test-create-macvtap$(EXEEXT): $(test_create_macvtap_OBJECTS) $(test_create_macvtap_DEPENDENCIES) $(EXTRA_test_create_macvtap_DEPENDENCIES) @rm -f test-create-macvtap$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_macvtap_OBJECTS) $(test_create_macvtap_LDADD) $(LIBS) test-create-sit$(EXEEXT): $(test_create_sit_OBJECTS) $(test_create_sit_DEPENDENCIES) $(EXTRA_test_create_sit_DEPENDENCIES) @rm -f test-create-sit$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_sit_OBJECTS) $(test_create_sit_LDADD) $(LIBS) test-create-veth$(EXEEXT): $(test_create_veth_OBJECTS) $(test_create_veth_DEPENDENCIES) $(EXTRA_test_create_veth_DEPENDENCIES) @rm -f test-create-veth$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_veth_OBJECTS) $(test_create_veth_LDADD) $(LIBS) test-create-vlan$(EXEEXT): $(test_create_vlan_OBJECTS) $(test_create_vlan_DEPENDENCIES) $(EXTRA_test_create_vlan_DEPENDENCIES) @rm -f test-create-vlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_vlan_OBJECTS) $(test_create_vlan_LDADD) $(LIBS) test-create-vrf$(EXEEXT): $(test_create_vrf_OBJECTS) $(test_create_vrf_DEPENDENCIES) $(EXTRA_test_create_vrf_DEPENDENCIES) @rm -f test-create-vrf$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_vrf_OBJECTS) $(test_create_vrf_LDADD) $(LIBS) test-create-vxlan$(EXEEXT): $(test_create_vxlan_OBJECTS) $(test_create_vxlan_DEPENDENCIES) $(EXTRA_test_create_vxlan_DEPENDENCIES) @rm -f test-create-vxlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_create_vxlan_OBJECTS) $(test_create_vxlan_LDADD) $(LIBS) test-delete-link$(EXEEXT): $(test_delete_link_OBJECTS) $(test_delete_link_DEPENDENCIES) $(EXTRA_test_delete_link_DEPENDENCIES) @rm -f test-delete-link$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_delete_link_OBJECTS) $(test_delete_link_LDADD) $(LIBS) test-genl$(EXEEXT): $(test_genl_OBJECTS) $(test_genl_DEPENDENCIES) $(EXTRA_test_genl_DEPENDENCIES) @rm -f test-genl$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_genl_OBJECTS) $(test_genl_LDADD) $(LIBS) test-nf-cache-mngr$(EXEEXT): $(test_nf_cache_mngr_OBJECTS) $(test_nf_cache_mngr_DEPENDENCIES) $(EXTRA_test_nf_cache_mngr_DEPENDENCIES) @rm -f test-nf-cache-mngr$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_nf_cache_mngr_OBJECTS) $(test_nf_cache_mngr_LDADD) $(LIBS) test-socket-creation$(EXEEXT): $(test_socket_creation_OBJECTS) $(test_socket_creation_DEPENDENCIES) $(EXTRA_test_socket_creation_DEPENDENCIES) @rm -f test-socket-creation$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_socket_creation_OBJECTS) $(test_socket_creation_LDADD) $(LIBS) test-u32-filter-with-actions$(EXEEXT): $(test_u32_filter_with_actions_OBJECTS) $(test_u32_filter_with_actions_DEPENDENCIES) $(EXTRA_test_u32_filter_with_actions_DEPENDENCIES) @rm -f test-u32-filter-with-actions$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_u32_filter_with_actions_OBJECTS) $(test_u32_filter_with_actions_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-addr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-attr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-cache-mngr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-complex-HTB-with-hash-filters.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-bond.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-bridge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-ifb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-ip6tnl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-ipgre.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-ipgretap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-ipip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-ipvlan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-ipvti.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-macsec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-macvlan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-macvtap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-sit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-veth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-vlan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-vrf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-create-vxlan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-delete-link.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-genl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nf-cache-mngr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-socket-creation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-u32-filter-with-actions.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? check-all.log: check-all$(EXEEXT) @p='check-all$(EXEEXT)'; \ b='check-all'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/tests/test-create-bridge.c0000644000175000017500000000354413023014600014603 00000000000000#include #include #include #define TEST_BRIDGE_NAME "testbridge" #define TEST_INTERFACE_NAME "testtap1" int create_bridge(struct nl_sock *sk, struct nl_cache *link_cache, const char *name) { struct rtnl_link *link; int err; link = rtnl_link_alloc(); if ((err = rtnl_link_set_type(link, "bridge")) < 0) { rtnl_link_put(link); return err; } rtnl_link_set_name(link, name); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { return err; } rtnl_link_put(link); return 0; } int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if ((err = create_bridge(sk, link_cache, TEST_BRIDGE_NAME)) < 0) { nl_perror(err, "Unable to allocate testbridge"); return err; } nl_cache_refill(sk, link_cache); link = rtnl_link_get_by_name(link_cache, TEST_BRIDGE_NAME); struct rtnl_link *ltap = rtnl_link_get_by_name(link_cache, TEST_INTERFACE_NAME); if (!ltap) { fprintf(stderr, "You should create a tap interface before lunch this test (# tunctl -t %s)\n", TEST_INTERFACE_NAME); return -1; } if ((err = rtnl_link_enslave(sk, link, ltap)) < 0) { nl_perror(err, "Unable to enslave interface to his bridge\n"); return err; } if(rtnl_link_is_bridge(link) == 0) { fprintf(stderr, "Link is not a bridge\n"); return -2; } if(rtnl_link_get_master(ltap) <= 0) { fprintf(stderr, "Interface is not attached to a bridge\n"); return -3; } rtnl_link_put(ltap); rtnl_link_put(link); nl_cache_free(link_cache); nl_socket_free(sk); return 0; } libnl-3.2.29/tests/test-create-ipgretap.c0000644000175000017500000000233113023014600015153 00000000000000#include #include int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "enp0s5"); if (!if_index) { fprintf(stderr, "Unable to lookup enp0s5"); return -1; } link = rtnl_link_ipgretap_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "ipgre-tap"); rtnl_link_ipgre_set_link(link, if_index); inet_pton(AF_INET, "10.211.55.10", &addr.s_addr); rtnl_link_ipgre_set_local(link, addr.s_addr); inet_pton(AF_INET, "10.133.6.33", &addr.s_addr); rtnl_link_ipgre_set_remote(link, addr.s_addr); rtnl_link_ipgre_set_ttl(link, 64); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/test-u32-filter-with-actions.c0000644000175000017500000002610513023014600016407 00000000000000/* * test/tests-u32-with-actions.c Add ingress qdisc, create some hash filters, and add redirect action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Stolen from tests/test-complex-HTB-with-hash-filters.c * * Copyright (c) 2013 Cong Wang */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define TC_HANDLE(maj, min) (TC_H_MAJ((maj) << 16) | TC_H_MIN(min)) /* some functions are copied from iproute-tc tool */ static int get_u32(__u32 *val, const char *arg, int base) { unsigned long res; char *ptr; if (!arg || !*arg) return -1; res = strtoul(arg, &ptr, base); if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL) return -1; *val = res; return 0; } static int get_u32_handle(__u32 *handle, const char *str) { __u32 htid=0, hash=0, nodeid=0; char *tmp = strchr(str, ':'); if (tmp == NULL) { if (memcmp("0x", str, 2) == 0) return get_u32(handle, str, 16); return -1; } htid = strtoul(str, &tmp, 16); if (tmp == str && *str != ':' && *str != 0) return -1; if (htid>=0x1000) return -1; if (*tmp) { str = tmp+1; hash = strtoul(str, &tmp, 16); if (tmp == str && *str != ':' && *str != 0) return -1; if (hash>=0x100) return -1; if (*tmp) { str = tmp+1; nodeid = strtoul(str, &tmp, 16); if (tmp == str && *str != 0) return -1; if (nodeid>=0x1000) return -1; } } *handle = (htid<<20)|(hash<<12)|nodeid; return 0; } static uint32_t get_u32_parse_handle(const char *cHandle) { uint32_t handle=0; if(get_u32_handle(&handle, cHandle)) { printf ("Illegal \"ht\"\n"); return -1; } if (handle && TC_U32_NODE(handle)) { printf("\"link\" must be a hash table.\n"); return -1; } return handle; } /* * Function that adds a new filter and attach it to a hash table * and set next hash table link with hash mask * */ static int u32_add_filter_on_ht_with_hashmask(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, uint32_t keyval, uint32_t keymask, int keyoff, int keyoffmask, uint32_t htid, uint32_t htlink, uint32_t hmask, uint32_t hoffset, struct rtnl_act *act, struct rtnl_act *act2) { struct rtnl_cls *cls; int err; cls=rtnl_cls_alloc(); if (!(cls)) { printf("Can not allocate classifier\n"); nl_socket_free(sock); exit(1); } rtnl_tc_set_link(TC_CAST(cls), rtnlLink); if ((err = rtnl_tc_set_kind(TC_CAST(cls), "u32"))) { printf("Can not set classifier as u32\n"); return 1; } rtnl_cls_set_prio(cls, prio); rtnl_cls_set_protocol(cls, ETH_P_IP); rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(0xffff, 0)); if (htid) rtnl_u32_set_hashtable(cls, htid); rtnl_u32_add_key_uint32(cls, keyval, keymask, keyoff, keyoffmask); rtnl_u32_set_hashmask(cls, hmask, hoffset); rtnl_u32_set_link(cls, htlink); rtnl_u32_add_action(cls, act); rtnl_u32_add_action(cls, act2); if ((err = rtnl_cls_add(sock, cls, NLM_F_CREATE))) { printf("Can not add classifier: %s\n", nl_geterror(err)); return -1; } rtnl_cls_put(cls); return 0; } /* * function that creates a new hash table */ static int u32_add_ht(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, uint32_t htid, uint32_t divisor) { int err; struct rtnl_cls *cls; cls=rtnl_cls_alloc(); if (!(cls)) { printf("Can not allocate classifier\n"); nl_socket_free(sock); exit(1); } rtnl_tc_set_link(TC_CAST(cls), rtnlLink); if ((err = rtnl_tc_set_kind(TC_CAST(cls), "u32"))) { printf("Can not set classifier as u32\n"); return 1; } rtnl_cls_set_prio(cls, prio); rtnl_cls_set_protocol(cls, ETH_P_IP); rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(0xffff, 0)); rtnl_u32_set_handle(cls, htid, 0x0, 0x0); //printf("htid: 0x%X\n", htid); rtnl_u32_set_divisor(cls, divisor); if ((err = rtnl_cls_add(sock, cls, NLM_F_CREATE))) { printf("Can not add classifier: %s\n", nl_geterror(err)); return -1; } rtnl_cls_put(cls); return 0; } /* * function that adds a new ingress qdisc and set the default class for unclassified traffic */ static int qdisc_add_ingress(struct nl_sock *sock, struct rtnl_link *rtnlLink) { struct rtnl_qdisc *qdisc; int err; /* Allocation of a qdisc object */ if (!(qdisc = rtnl_qdisc_alloc())) { printf("Can not allocate Qdisc\n"); return -1; } //rtnl_tc_set_ifindex(TC_CAST(qdisc), master_index); rtnl_tc_set_link(TC_CAST(qdisc), rtnlLink); rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT); //printf("Delete current qdisc\n"); rtnl_qdisc_delete(sock, qdisc); //rtnl_qdisc_put(qdisc); rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(0xffff, 0)); if ((err = rtnl_tc_set_kind(TC_CAST(qdisc), "ingress"))) { printf("Can not allocate ingress\n"); return -1; } /* Submit request to kernel and wait for response */ if ((err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE))) { printf("Can not allocate ingress Qdisc\n"); return -1; } /* Return the qdisc object to free memory resources */ rtnl_qdisc_put(qdisc); return 0; } int main(void) { struct nl_sock *sock; struct rtnl_link *link; uint32_t ht, htlink, htid, direction; char chashlink[16]=""; int err; struct nl_cache *link_cache; struct rtnl_act *act, *act2; if (!(sock = nl_socket_alloc())) { printf("Unable to allocate netlink socket\n"); exit(1); } if ((err = nl_connect(sock, NETLINK_ROUTE)) < 0 ) { printf("Nu s-a putut conecta la NETLINK!\n"); nl_socket_free(sock); exit(1); } if ((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache)) < 0) { printf("Unable to allocate link cache: %s\n", nl_geterror(err)); nl_socket_free(sock); exit(1); } /* lookup interface index of eth0 */ if (!(link = rtnl_link_get_by_name(link_cache, "eth0"))) { /* error */ printf("Interface not found\n"); nl_socket_free(sock); exit(1); } err=qdisc_add_ingress(sock, link); //printf("Add main hash table\n"); /* create u32 first hash filter table * */ /* formula calcul handle: * uint32_t handle = (htid << 20) | (hash << 12) | nodeid; */ /* * Upper limit of number of hash tables: 4096 (0xFFF) * Number of hashes in a table: 256 values (0xFF) * */ /* using 256 values for hash table * each entry in hash table match a byte from IP address specified later by a hash key */ uint32_t i; for (i = 1; i <= 0xf; i++) u32_add_ht(sock, link, 1, i, 256); /* * attach a u32 filter to the first hash * that redirects all traffic and make a hash key * from the fist byte of the IP address * */ //divisor=0x0; // unused here //handle = 0x0; // unused here //hash = 0x0; // unused here //htid = 0x0; // unused here //nodeid = 0x0; // unused here // direction = 12 -> source IP // direction = 16 -> destination IP direction = 16; /* * which hash table will use * in our case is hash table no 1 defined previous * * There are 2 posibilities to set the the hash table: * 1. Using function get_u32_handle and sent a string in * format 10: where 10 is number of the hash table * 2. Create your own value in format: 0xa00000 * */ strcpy(chashlink, "1:"); //printf("Hash Link: %s\n", chashlink); //chashlink=malloc(sizeof(char) * htlink = 0x0; // is used by get_u32_handle to return the correct value of hash table (link) if(get_u32_handle(&htlink, chashlink)) { printf ("Illegal \"link\""); nl_socket_free(sock); exit(1); } //printf ("hash link : 0x%X\n", htlink); //printf ("hash link test : %u\n", (htlink && TC_U32_NODE(htlink))); if (htlink && TC_U32_NODE(htlink)) { printf("\"link\" must be a hash table.\n"); nl_socket_free(sock); exit(1); } /* the hash mask will hit the hash table (link) no 1: in our case */ /* set the hash key mask */ //hashmask = 0xFF000000UL; // the mask that is used to match the hash in specific table, in our case for example 1:a with mean the first byte which is 10 in hash table 1 /* Here we add a hash filter which match the first byte (see the hashmask value) * of the source IP (offset 12 in the packet header) * You can use also offset 16 to match the destination IP */ /* * Also we need a filter to match our rule * This mean that we will put a 0.0.0.0/0 filter in our first rule * that match the offset 12 (source IP) * Also you can put offset 16 to match the destination IP */ u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0, 0x0, direction, 0, 0, htlink, 0xff000000, direction, NULL, NULL); /* * For each first byte that we need to match we will create a new hash table * For example: you have those clases: 10.0.0.0/24 and 172.16.0.0/23 * For byte 10 and byte 172 will create a separate hash table that will match the second * byte from each class. * */ /* * Now we will create other filter under (ATENTION) our first hash table (link) 1: * Previous rule redirects the trafic according the hash mask to hash table (link) no 1: * Here we will match the hash tables from 1:0 to 1:ff. Under each hash table we will attach * other rules that matches next byte from IP source/destination IP and we will repeat the * previous steps. * */ act = rtnl_act_alloc(); if (!act) { printf("rtnl_act_alloc() returns %p\n", act); return -1; } rtnl_tc_set_kind(TC_CAST(act), "skbedit"); rtnl_skbedit_set_queue_mapping(act, 4); rtnl_skbedit_set_action(act, TC_ACT_PIPE); act2 = rtnl_act_alloc(); if (!act2) { printf("rtnl_act_alloc() returns %p\n", act2); return -1; } rtnl_tc_set_kind(TC_CAST(act2), "mirred"); rtnl_mirred_set_action(act2, TCA_EGRESS_REDIR); rtnl_mirred_set_policy(act2, TC_ACT_STOLEN); rtnl_mirred_set_ifindex(act2, rtnl_link_name2i(link_cache, "eth1")); // /8 check // 10.0.0.0/8 ht=get_u32_parse_handle("1:a:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("2:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0a000000, 0xff000000, direction, 0, htid, htlink, 0x00ff0000, direction, act, act2); rtnl_act_put(act); nl_socket_free(sock); return 0; } libnl-3.2.29/tests/check-attr.c0000644000175000017500000000506213023014600013153 00000000000000/* * tests/check-attr.c nla_attr unit tests * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #include "util.h" #include #include START_TEST(attr_size) { fail_if(nla_attr_size(0) != NLA_HDRLEN, "Length of empty attribute should match header size"); fail_if(nla_attr_size(1) != NLA_HDRLEN + 1, "Length of 1 bytes payload should be NLA_HDRLEN + 1"); fail_if(nla_attr_size(2) != NLA_HDRLEN + 2, "Length of 2 bytes payload should be NLA_HDRLEN + 2"); fail_if(nla_attr_size(3) != NLA_HDRLEN + 3, "Length of 3 bytes payload should be NLA_HDRLEN + 3"); fail_if(nla_attr_size(4) != NLA_HDRLEN + 4, "Length of 4 bytes payload should be NLA_HDRLEN + 4"); fail_if(nla_total_size(1) != NLA_HDRLEN + 4, "Total size of 1 bytes payload should result in 8 bytes"); fail_if(nla_total_size(2) != NLA_HDRLEN + 4, "Total size of 2 bytes payload should result in 8 bytes"); fail_if(nla_total_size(3) != NLA_HDRLEN + 4, "Total size of 3 bytes payload should result in 8 bytes"); fail_if(nla_total_size(4) != NLA_HDRLEN + 4, "Total size of 4 bytes payload should result in 8 bytes"); fail_if(nla_padlen(1) != 3, "2 bytes of payload should result in 3 padding bytes"); fail_if(nla_padlen(2) != 2, "2 bytes of payload should result in 2 padding bytes"); fail_if(nla_padlen(3) != 1, "3 bytes of payload should result in 1 padding bytes"); fail_if(nla_padlen(4) != 0, "4 bytes of payload should result in 0 padding bytes"); fail_if(nla_padlen(5) != 3, "5 bytes of payload should result in 3 padding bytes"); } END_TEST START_TEST(msg_construct) { struct nl_msg *msg; struct nlmsghdr *nlh; struct nlattr *a; int i, rem; msg = nlmsg_alloc(); fail_if(!msg, "Unable to allocate netlink message"); for (i = 1; i < 256; i++) { fail_if(nla_put_u32(msg, i, i+1) != 0, "Unable to add attribute %d", i); } nlh = nlmsg_hdr(msg); i = 1; nlmsg_for_each_attr(a, nlh, 0, rem) { fail_if(nla_type(a) != i, "Expected attribute %d", i); i++; fail_if(nla_get_u32(a) != i, "Expected attribute value %d", i); } nlmsg_free(msg); } END_TEST Suite *make_nl_attr_suite(void) { Suite *suite = suite_create("Netlink attributes"); TCase *nl_attr = tcase_create("Core"); tcase_add_test(nl_attr, attr_size); tcase_add_test(nl_attr, msg_construct); suite_add_tcase(suite, nl_attr); return suite; } libnl-3.2.29/tests/test-create-ipgre.c0000644000175000017500000000234513023014600014453 00000000000000#include #include int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "eno16777736"); if (!if_index) { fprintf(stderr, "Unable to lookup eno16777736"); return -1; } link = rtnl_link_ipgre_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "ipgre-tun"); rtnl_link_ipgre_set_link(link, if_index); inet_pton(AF_INET, "192.168.254.12", &addr.s_addr); rtnl_link_ipgre_set_local(link, addr.s_addr); inet_pton(AF_INET, "192.168.254.13", &addr.s_addr); rtnl_link_ipgre_set_remote(link, addr.s_addr); rtnl_link_ipgre_set_ttl(link, 64); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/tests/util.h0000644000175000017500000000023313023014600012103 00000000000000#include #define nl_fail_if(condition, error, message) \ fail_if((condition), "nlerr=%d (%s): %s", \ (error), nl_geterror(error), (message)) libnl-3.2.29/tests/test-create-ifb.c0000644000175000017500000000105513023014600014102 00000000000000#include #include int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_sock *sk; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } link = rtnl_link_alloc(); rtnl_link_set_type(link, "ifb"); rtnl_link_set_name(link, "ifb1"); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; } libnl-3.2.29/configure0000755000175000017500000165056413031473643011564 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for libnl 3.2.29. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libnl' PACKAGE_TARNAME='libnl' PACKAGE_VERSION='3.2.29' PACKAGE_STRING='libnl 3.2.29' PACKAGE_BUGREPORT='' PACKAGE_URL='http://www.infradead.org/~tgr/libnl/' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" enable_option_checking=no ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS subdirs ENABLE_DEBUG_FALSE ENABLE_DEBUG_TRUE DISABLE_PTHREADS_FALSE DISABLE_PTHREADS_TRUE ENABLE_CLI_INSTALL_SBIN_FALSE ENABLE_CLI_INSTALL_SBIN_TRUE ENABLE_CLI_INSTALL_BIN_FALSE ENABLE_CLI_INSTALL_BIN_TRUE ENABLE_CLI_FALSE ENABLE_CLI_TRUE pkgconfigdir ENABLE_UNIT_TESTS_FALSE ENABLE_UNIT_TESTS_TRUE CHECK_LIBS CHECK_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG YACC FLEX CPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL LT_AGE LT_REVISION LT_CURRENT LIBNL_VERSION MIC_VERSION MIN_VERSION MAJ_VERSION am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC ac_ct_AR AR AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock with_pkgconfigdir enable_cli enable_pthreads enable_debug ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR CHECK_CFLAGS CHECK_LIBS' ac_subdirs_all='doc' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libnl 3.2.29 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libnl] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libnl 3.2.29:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-cli=yes|no|no-inst|bin|sbin Whether to build command line interface utils. Defaults to 'yes' which is a synonym for 'bin'. 'no-inst' means only build, not installing. 'bin'/'sbin' means installing to bin/sbin directory --disable-pthreads Disable pthreads support --disable-debug Do not include debugging statements Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-pkgconfigdir=PATH Path to the pkgconfig directory [[LIBDIR/pkgconfig]] Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory LT_SYS_LIBRARY_PATH User-defined run-time library search path. CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path CHECK_CFLAGS C compiler flags for CHECK, overriding pkg-config CHECK_LIBS linker flags for CHECK, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. libnl home page: . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libnl configure 3.2.29 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libnl $as_me 3.2.29, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers lib/defs.h" ac_aux_dir= for ac_dir in build-aux "$srcdir"/build-aux; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libnl' VERSION='3.2.29' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac MAJ_VERSION=3 MIN_VERSION=2 MIC_VERSION=29 LIBNL_GIT_SHA=c560a37f193dd6d1ae9c4db94eafa8a69f843419 LIBNL_VERSION=3.2.29 LT_CURRENT=224 LT_REVISION=0 LT_AGE=24 ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: for ac_prog in 'flex' do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_FLEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$FLEX"; then ac_cv_prog_FLEX="$FLEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_FLEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FLEX=$ac_cv_prog_FLEX if test -n "$FLEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLEX" >&5 $as_echo "$FLEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$FLEX" && break done for ac_prog in 'bison -y' do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CHECK" >&5 $as_echo_n "checking for CHECK... " >&6; } if test -n "$CHECK_CFLAGS"; then pkg_cv_CHECK_CFLAGS="$CHECK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"check >= 0.9.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "check >= 0.9.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CHECK_CFLAGS=`$PKG_CONFIG --cflags "check >= 0.9.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$CHECK_LIBS"; then pkg_cv_CHECK_LIBS="$CHECK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"check >= 0.9.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "check >= 0.9.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CHECK_LIBS=`$PKG_CONFIG --libs "check >= 0.9.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then CHECK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "check >= 0.9.0" 2>&1` else CHECK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "check >= 0.9.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$CHECK_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Disabling building of unit tests" >&5 $as_echo "$as_me: WARNING: *** Disabling building of unit tests" >&2;} enable_unit_tests="no" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Disabling building of unit tests" >&5 $as_echo "$as_me: WARNING: *** Disabling building of unit tests" >&2;} enable_unit_tests="no" else CHECK_CFLAGS=$pkg_cv_CHECK_CFLAGS CHECK_LIBS=$pkg_cv_CHECK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_unit_tests="yes" fi if test "$enable_unit_tests" = "yes"; then ENABLE_UNIT_TESTS_TRUE= ENABLE_UNIT_TESTS_FALSE='#' else ENABLE_UNIT_TESTS_TRUE='#' ENABLE_UNIT_TESTS_FALSE= fi # Check whether --with-pkgconfigdir was given. if test "${with_pkgconfigdir+set}" = set; then : withval=$with_pkgconfigdir; pkgconfigdir="$withval" else pkgconfigdir='${libdir}/pkgconfig' fi # Check whether --enable-cli was given. if test "${enable_cli+set}" = set; then : enableval=$enable_cli; enable_cli="$enableval" else enable_cli="yes" fi if test "$enable_cli" != "no" && test "$enable_cli" != "no-inst" && test "$enable_cli" != "sbin"; then enable_cli="bin" fi if test "$enable_cli" != "no"; then ENABLE_CLI_TRUE= ENABLE_CLI_FALSE='#' else ENABLE_CLI_TRUE='#' ENABLE_CLI_FALSE= fi if test "$enable_cli" = "bin"; then ENABLE_CLI_INSTALL_BIN_TRUE= ENABLE_CLI_INSTALL_BIN_FALSE='#' else ENABLE_CLI_INSTALL_BIN_TRUE='#' ENABLE_CLI_INSTALL_BIN_FALSE= fi if test "$enable_cli" = "sbin"; then ENABLE_CLI_INSTALL_SBIN_TRUE= ENABLE_CLI_INSTALL_SBIN_FALSE='#' else ENABLE_CLI_INSTALL_SBIN_TRUE='#' ENABLE_CLI_INSTALL_SBIN_FALSE= fi # Check whether --enable-pthreads was given. if test "${enable_pthreads+set}" = set; then : enableval=$enable_pthreads; enable_pthreads="$enableval" else enable_pthreads="yes" fi if test "$enable_pthreads" = "no"; then DISABLE_PTHREADS_TRUE= DISABLE_PTHREADS_FALSE='#' else DISABLE_PTHREADS_TRUE='#' DISABLE_PTHREADS_FALSE= fi # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; enable_debug="$enableval" else enable_debug="yes" fi if test "$enable_debug" = "no" ; then ENABLE_DEBUG_TRUE= ENABLE_DEBUG_FALSE='#' else ENABLE_DEBUG_TRUE='#' ENABLE_DEBUG_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 $as_echo_n "checking for pow in -lm... " >&6; } if ${ac_cv_lib_m_pow+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pow (); int main () { return pow (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_pow=yes else ac_cv_lib_m_pow=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 $as_echo "$ac_cv_lib_m_pow" >&6; } if test "x$ac_cv_lib_m_pow" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" else as_fn_error $? "libm is required" "$LINENO" 5 fi if test "x$enable_pthreads" = "xno"; then $as_echo "#define DISABLE_PTHREADS 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_lock in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_lock in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_lock+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_lock (); int main () { return pthread_mutex_lock (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_lock=yes else ac_cv_lib_pthread_pthread_mutex_lock=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_lock" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_lock" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_lock" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else as_fn_error $? "libpthread is required" "$LINENO" 5 fi fi if test "x$enable_debug" = "xyes"; then $as_echo "#define NL_DEBUG 1" >>confdefs.h fi subdirs="$subdirs doc" ac_config_files="$ac_config_files Makefile libnl-3.0.pc libnl-route-3.0.pc libnl-genl-3.0.pc libnl-nf-3.0.pc libnl-cli-3.0.pc libnl-xfrm-3.0.pc libnl-idiag-3.0.pc lib/Makefile include/Makefile src/Makefile src/lib/Makefile tests/Makefile man/Makefile python/Makefile python/setup.py python/doc/Makefile python/examples/Makefile python/netlink/Makefile python/netlink/genl/Makefile python/netlink/route/Makefile python/tests/Makefile include/netlink/version.h" ac_errcount=0 if test -z "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: bison not found. Please install before continuing." >&5 $as_echo "$as_me: WARNING: bison not found. Please install before continuing." >&2;} ac_errcount=$((ac_errcount + 1)) fi if test -z "$FLEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: flex not found. Please install before continuing." >&5 $as_echo "$as_me: WARNING: flex not found. Please install before continuing." >&2;} ac_errcount=$((ac_errcount + 1)) fi if test $ac_errcount -gt 0; then as_fn_error $? "Required packages are missing. Please install them and rerun ./configure" "$LINENO" 5 fi cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_UNIT_TESTS_TRUE}" && test -z "${ENABLE_UNIT_TESTS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_UNIT_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_CLI_TRUE}" && test -z "${ENABLE_CLI_FALSE}"; then as_fn_error $? "conditional \"ENABLE_CLI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_CLI_INSTALL_BIN_TRUE}" && test -z "${ENABLE_CLI_INSTALL_BIN_FALSE}"; then as_fn_error $? "conditional \"ENABLE_CLI_INSTALL_BIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_CLI_INSTALL_SBIN_TRUE}" && test -z "${ENABLE_CLI_INSTALL_SBIN_FALSE}"; then as_fn_error $? "conditional \"ENABLE_CLI_INSTALL_SBIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DISABLE_PTHREADS_TRUE}" && test -z "${DISABLE_PTHREADS_FALSE}"; then as_fn_error $? "conditional \"DISABLE_PTHREADS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_DEBUG_TRUE}" && test -z "${ENABLE_DEBUG_FALSE}"; then as_fn_error $? "conditional \"ENABLE_DEBUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libnl $as_me 3.2.29, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider. libnl home page: ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libnl config.status 3.2.29 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "lib/defs.h") CONFIG_HEADERS="$CONFIG_HEADERS lib/defs.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libnl-3.0.pc") CONFIG_FILES="$CONFIG_FILES libnl-3.0.pc" ;; "libnl-route-3.0.pc") CONFIG_FILES="$CONFIG_FILES libnl-route-3.0.pc" ;; "libnl-genl-3.0.pc") CONFIG_FILES="$CONFIG_FILES libnl-genl-3.0.pc" ;; "libnl-nf-3.0.pc") CONFIG_FILES="$CONFIG_FILES libnl-nf-3.0.pc" ;; "libnl-cli-3.0.pc") CONFIG_FILES="$CONFIG_FILES libnl-cli-3.0.pc" ;; "libnl-xfrm-3.0.pc") CONFIG_FILES="$CONFIG_FILES libnl-xfrm-3.0.pc" ;; "libnl-idiag-3.0.pc") CONFIG_FILES="$CONFIG_FILES libnl-idiag-3.0.pc" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "python/Makefile") CONFIG_FILES="$CONFIG_FILES python/Makefile" ;; "python/setup.py") CONFIG_FILES="$CONFIG_FILES python/setup.py" ;; "python/doc/Makefile") CONFIG_FILES="$CONFIG_FILES python/doc/Makefile" ;; "python/examples/Makefile") CONFIG_FILES="$CONFIG_FILES python/examples/Makefile" ;; "python/netlink/Makefile") CONFIG_FILES="$CONFIG_FILES python/netlink/Makefile" ;; "python/netlink/genl/Makefile") CONFIG_FILES="$CONFIG_FILES python/netlink/genl/Makefile" ;; "python/netlink/route/Makefile") CONFIG_FILES="$CONFIG_FILES python/netlink/route/Makefile" ;; "python/tests/Makefile") CONFIG_FILES="$CONFIG_FILES python/tests/Makefile" ;; "include/netlink/version.h") CONFIG_FILES="$CONFIG_FILES include/netlink/version.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi # # CONFIG_SUBDIRS section. # if test "$no_recursion" != yes; then # Remove --cache-file, --srcdir, and --disable-option-checking arguments # so they do not pile up. ac_sub_configure_args= ac_prev= eval "set x $ac_configure_args" shift for ac_arg do if test -n "$ac_prev"; then ac_prev= continue fi case $ac_arg in -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ | --c=*) ;; --config-cache | -C) ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ;; --disable-option-checking) ;; *) case $ac_arg in *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_sub_configure_args " '$ac_arg'" ;; esac done # Always prepend --prefix to ensure using the same prefix # in subdir configurations. ac_arg="--prefix=$prefix" case $ac_arg in *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" # Pass --silent if test "$silent" = yes; then ac_sub_configure_args="--silent $ac_sub_configure_args" fi # Always prepend --disable-option-checking to silence warnings, since # different subdirs can have different --enable and --with options. ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue # Do not complain, so a configure script can configure whichever # parts of a large source tree are present. test -d "$srcdir/$ac_dir" || continue ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 $as_echo "$ac_msg" >&6 as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" # Check for guested configure; otherwise get Cygnus style configure. if test -f "$ac_srcdir/configure.gnu"; then ac_sub_configure=$ac_srcdir/configure.gnu elif test -f "$ac_srcdir/configure"; then ac_sub_configure=$ac_srcdir/configure elif test -f "$ac_srcdir/configure.in"; then # This should be Cygnus configure. ac_sub_configure=$ac_aux_dir/configure else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} ac_sub_configure= fi # The recursion is here. if test -n "$ac_sub_configure"; then # Make the cache file name correct relative to the subdirectory. case $cache_file in [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; *) # Relative name. ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 $as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} # The eval makes quoting arguments work. eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 fi cd "$ac_popdir" done fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi echo "-------------------------------------------------------------------------------" echo " NOTE" echo "" echo " There have been some changes starting with 3.2 regarding where and how libnl" echo " is being installed on the system in order to allow multiple libnl versions" echo " to be installed in parallel:" echo "" echo " - Headers will be installed in ${includedir}/libnl${MAJ_VERSION}, therefore" echo " you will need to add \"-I/usr/include/libnl${MAJ_VERSION}\" to CFLAGS" echo "" echo " - The library basename was renamed to libnl-${MAJ_VERSION}, i.e. the SO names become" echo " libnl-${MAJ_VERSION}.so., libnl-route-${MAJ_VERSION}.so, etc." echo "" echo " - libtool versioning was assumed, to ease detection of compatible library" echo " versions." echo "" echo " If you are using pkg-config for detecting and linking against the library " echo " things will continue magically as if nothing every happened. If you are " echo " linking manually you need to adapt your Makefiles or switch to using " echo " pkg-config files." echo "" echo "-------------------------------------------------------------------------------" libnl-3.2.29/libnl-nf-3.0.pc.in0000644000175000017500000000042113023014600012542 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnl-nf Description: Netfilter Netlink Library Version: @PACKAGE_VERSION@ Requires: libnl-route-3.0 Libs: -L${libdir} -lnl-nf-@MAJ_VERSION@ Cflags: -I${includedir}/libnl@MAJ_VERSION@ libnl-3.2.29/libnl-cli-3.sym0000644000175000017500000000531013023014600012353 00000000000000libnl_3 { global: nl_cli_addr_alloc; nl_cli_addr_parse; nl_cli_addr_parse_broadcast; nl_cli_addr_parse_dev; nl_cli_addr_parse_family; nl_cli_addr_parse_label; nl_cli_addr_parse_local; nl_cli_addr_parse_peer; nl_cli_addr_parse_preferred; nl_cli_addr_parse_scope; nl_cli_addr_parse_valid; nl_cli_alloc_cache; nl_cli_alloc_socket; nl_cli_class_alloc; nl_cli_class_alloc_cache; nl_cli_cls_alloc; nl_cli_cls_alloc_cache; nl_cli_cls_parse_ematch; nl_cli_cls_parse_proto; nl_cli_confirm; nl_cli_connect; nl_cli_ct_alloc; nl_cli_ct_alloc_cache; nl_cli_ct_parse_dst; nl_cli_ct_parse_dst_port; nl_cli_ct_parse_family; nl_cli_ct_parse_id; nl_cli_ct_parse_mark; nl_cli_ct_parse_protocol; nl_cli_ct_parse_src; nl_cli_ct_parse_src_port; nl_cli_ct_parse_status; nl_cli_ct_parse_tcp_state; nl_cli_ct_parse_timeout; nl_cli_ct_parse_use; nl_cli_ct_parse_zone; nl_cli_exp_alloc; nl_cli_exp_alloc_cache; nl_cli_exp_parse_class; nl_cli_exp_parse_dst; nl_cli_exp_parse_dst_port; nl_cli_exp_parse_family; nl_cli_exp_parse_flags; nl_cli_exp_parse_fn; nl_cli_exp_parse_helper_name; nl_cli_exp_parse_icmp_code; nl_cli_exp_parse_icmp_id; nl_cli_exp_parse_icmp_type; nl_cli_exp_parse_id; nl_cli_exp_parse_l4protonum; nl_cli_exp_parse_nat_dir; nl_cli_exp_parse_src; nl_cli_exp_parse_src_port; nl_cli_exp_parse_timeout; nl_cli_exp_parse_zone; nl_cli_fatal; nl_cli_link_alloc; nl_cli_link_alloc_cache; nl_cli_link_alloc_cache_family; nl_cli_link_parse_family; nl_cli_link_parse_ifalias; nl_cli_link_parse_ifindex; nl_cli_link_parse_mtu; nl_cli_link_parse_name; nl_cli_link_parse_txqlen; nl_cli_link_parse_weight; nl_cli_load_module; nl_cli_neigh_alloc; nl_cli_neigh_parse_dev; nl_cli_neigh_parse_dst; nl_cli_neigh_parse_family; nl_cli_neigh_parse_lladdr; nl_cli_neigh_parse_state; nl_cli_parse_dumptype; nl_cli_parse_u32; nl_cli_print_version; nl_cli_qdisc_alloc; nl_cli_route_alloc; nl_cli_route_alloc_cache; nl_cli_route_parse_dst; nl_cli_route_parse_family; nl_cli_route_parse_iif; nl_cli_route_parse_metric; nl_cli_route_parse_nexthop; nl_cli_route_parse_pref_src; nl_cli_route_parse_prio; nl_cli_route_parse_protocol; nl_cli_route_parse_scope; nl_cli_route_parse_src; nl_cli_route_parse_table; nl_cli_route_parse_type; nl_cli_rule_alloc; nl_cli_rule_alloc_cache; nl_cli_rule_parse_family; nl_cli_tc_lookup; nl_cli_tc_parse_dev; nl_cli_tc_parse_handle; nl_cli_tc_parse_kind; nl_cli_tc_parse_linktype; nl_cli_tc_parse_mpu; nl_cli_tc_parse_mtu; nl_cli_tc_parse_overhead; nl_cli_tc_parse_parent; nl_cli_tc_register; nl_cli_tc_unregister; local: *; }; libnl_3_2_28 { global: nl_cli_alloc_cache_flags; nl_cli_link_alloc_cache_flags; nl_cli_link_alloc_cache_family_flags; } libnl_3; libnl-3.2.29/libnl-route-3.sym0000644000175000017500000006360613023014600012756 00000000000000libnl_3 { global: # these functions are in private header files and should have never # been exported. We might hide them later. rtnl_link_af_alloc; rtnl_link_af_data; rtnl_link_af_data_compare; rtnl_link_af_ops_lookup; rtnl_link_af_ops_put; rtnl_link_af_register; rtnl_link_af_unregister; rtnl_link_info_ops_lookup; rtnl_link_info_ops_put; rtnl_link_register_info; rtnl_link_unregister_info; rtnl_tc_build_rate_table; rtnl_tc_clone; rtnl_tc_compare; rtnl_tc_data; rtnl_tc_data_check; rtnl_tc_dump_details; rtnl_tc_dump_line; rtnl_tc_dump_stats; rtnl_tc_free_data; rtnl_tc_msg_build; rtnl_tc_msg_parse; rtnl_tc_register; rtnl_tc_type_register; rtnl_tc_type_unregister; rtnl_tc_unregister; # these functions are in private header files and should have never # been exported. They are used by libnl internals rtnl_tc_get_ops; rtnl_tc_lookup_ops; # internal symbols that are in public headers rtln_link_policy; # ops structure route_obj_ops; flnl_lookup; flnl_lookup_build_request; flnl_request_alloc; flnl_request_get_addr; flnl_request_get_fwmark; flnl_request_get_scope; flnl_request_get_table; flnl_request_get_tos; flnl_request_set_addr; flnl_request_set_fwmark; flnl_request_set_scope; flnl_request_set_table; flnl_request_set_tos; flnl_result_alloc; flnl_result_alloc_cache; flnl_result_get_error; flnl_result_get_nexthop_sel; flnl_result_get_prefixlen; flnl_result_get_scope; flnl_result_get_table_id; flnl_result_get_type; flnl_result_put; nl_ovl_strategy2str; nl_police2str; nl_rtgen_request; nl_rtntype2str; nl_str2ovl_strategy; nl_str2police; nl_str2rtntype; rtnl_act_add; rtnl_act_alloc; rtnl_act_append; rtnl_act_build_add_request; rtnl_act_build_change_request; rtnl_act_build_delete_request; rtnl_act_change; rtnl_act_delete; rtnl_act_fill; rtnl_act_get; rtnl_act_parse; rtnl_act_put; rtnl_act_put_all; rtnl_act_remove; rtnl_addr_add; rtnl_addr_alloc; rtnl_addr_alloc_cache; rtnl_addr_build_add_request; rtnl_addr_build_delete_request; rtnl_addr_delete; rtnl_addr_flags2str; rtnl_addr_get; rtnl_addr_get_anycast; rtnl_addr_get_broadcast; rtnl_addr_get_create_time; rtnl_addr_get_family; rtnl_addr_get_flags; rtnl_addr_get_ifindex; rtnl_addr_get_label; rtnl_addr_get_last_update_time; rtnl_addr_get_link; rtnl_addr_get_local; rtnl_addr_get_multicast; rtnl_addr_get_peer; rtnl_addr_get_preferred_lifetime; rtnl_addr_get_prefixlen; rtnl_addr_get_scope; rtnl_addr_get_valid_lifetime; rtnl_addr_put; rtnl_addr_set_anycast; rtnl_addr_set_broadcast; rtnl_addr_set_family; rtnl_addr_set_flags; rtnl_addr_set_ifindex; rtnl_addr_set_label; rtnl_addr_set_link; rtnl_addr_set_local; rtnl_addr_set_multicast; rtnl_addr_set_peer; rtnl_addr_set_preferred_lifetime; rtnl_addr_set_prefixlen; rtnl_addr_set_scope; rtnl_addr_set_valid_lifetime; rtnl_addr_str2flags; rtnl_addr_unset_flags; rtnl_basic_add_action; rtnl_basic_del_action; rtnl_basic_get_ematch; rtnl_basic_get_target; rtnl_basic_set_ematch; rtnl_basic_set_target; rtnl_cgroup_get_ematch; rtnl_cgroup_set_ematch; rtnl_class_add; rtnl_class_alloc; rtnl_class_alloc_cache; rtnl_class_build_add_request; rtnl_class_build_delete_request; rtnl_class_delete; rtnl_class_dsmark_get_bitmask; rtnl_class_dsmark_get_value; rtnl_class_dsmark_set_bitmask; rtnl_class_dsmark_set_value; rtnl_class_foreach_child; rtnl_class_foreach_cls; rtnl_class_get; rtnl_class_leaf_qdisc; rtnl_class_put; rtnl_classid_generate; rtnl_cls_add; rtnl_cls_alloc; rtnl_cls_alloc_cache; rtnl_cls_build_add_request; rtnl_cls_build_change_request; rtnl_cls_build_delete_request; rtnl_cls_change; rtnl_cls_delete; rtnl_cls_get_prio; rtnl_cls_get_protocol; rtnl_cls_put; rtnl_cls_set_prio; rtnl_cls_set_protocol; rtnl_ematch_add_child; rtnl_ematch_alloc; rtnl_ematch_cmp_get; rtnl_ematch_cmp_set; rtnl_ematch_data; rtnl_ematch_fill_attr; rtnl_ematch_free; rtnl_ematch_get_flags; rtnl_ematch_lookup_ops; rtnl_ematch_lookup_ops_by_name; rtnl_ematch_meta_set_lvalue; rtnl_ematch_meta_set_operand; rtnl_ematch_meta_set_rvalue; rtnl_ematch_nbyte_get_layer; rtnl_ematch_nbyte_get_len; rtnl_ematch_nbyte_get_offset; rtnl_ematch_nbyte_get_pattern; rtnl_ematch_nbyte_set_offset; rtnl_ematch_nbyte_set_pattern; rtnl_ematch_offset2txt; rtnl_ematch_opnd2txt; rtnl_ematch_parse_attr; rtnl_ematch_parse_expr; rtnl_ematch_register; rtnl_ematch_set_flags; rtnl_ematch_set_kind; rtnl_ematch_set_name; rtnl_ematch_set_ops; rtnl_ematch_text_get_algo; rtnl_ematch_text_get_from_layer; rtnl_ematch_text_get_from_offset; rtnl_ematch_text_get_len; rtnl_ematch_text_get_pattern; rtnl_ematch_text_get_to_layer; rtnl_ematch_text_get_to_offset; rtnl_ematch_text_set_algo; rtnl_ematch_text_set_from; rtnl_ematch_text_set_pattern; rtnl_ematch_text_set_to; rtnl_ematch_tree_add; rtnl_ematch_tree_alloc; rtnl_ematch_tree_dump; rtnl_ematch_tree_free; rtnl_ematch_unlink; rtnl_ematch_unset_flags; rtnl_fw_set_classid; rtnl_fw_set_mask; rtnl_htb_get_cbuffer; rtnl_htb_get_ceil; rtnl_htb_get_defcls; rtnl_htb_get_level; rtnl_htb_get_prio; rtnl_htb_get_quantum; rtnl_htb_get_rate2quantum; rtnl_htb_get_rate; rtnl_htb_get_rbuffer; rtnl_htb_set_cbuffer; rtnl_htb_set_ceil; rtnl_htb_set_defcls; rtnl_htb_set_level; rtnl_htb_set_prio; rtnl_htb_set_quantum; rtnl_htb_set_rate2quantum; rtnl_htb_set_rate; rtnl_htb_set_rbuffer; rtnl_link_add; rtnl_link_alloc; rtnl_link_alloc_cache; rtnl_link_bond_add; rtnl_link_bond_alloc; rtnl_link_bond_enslave; rtnl_link_bond_enslave_ifindex; rtnl_link_bond_release; rtnl_link_bond_release_ifindex; rtnl_link_bridge_add; rtnl_link_bridge_alloc; rtnl_link_bridge_flags2str; rtnl_link_bridge_get_cost; rtnl_link_bridge_get_flags; rtnl_link_bridge_get_port_state; rtnl_link_bridge_get_priority; rtnl_link_bridge_has_ext_info; rtnl_link_bridge_set_cost; rtnl_link_bridge_set_flags; rtnl_link_bridge_set_port_state; rtnl_link_bridge_set_priority; rtnl_link_bridge_str2flags; rtnl_link_bridge_unset_flags; rtnl_link_build_add_request; rtnl_link_build_change_request; rtnl_link_build_delete_request; rtnl_link_build_get_request; rtnl_link_can_berr; rtnl_link_can_berr_rx; rtnl_link_can_berr_tx; rtnl_link_can_ctrlmode2str; rtnl_link_can_freq; rtnl_link_can_get_bitrate; rtnl_link_can_get_bittiming; rtnl_link_can_get_bt_const; rtnl_link_can_get_ctrlmode; rtnl_link_can_get_restart_ms; rtnl_link_can_get_sample_point; rtnl_link_can_restart; rtnl_link_can_set_bitrate; rtnl_link_can_set_bittiming; rtnl_link_can_set_ctrlmode; rtnl_link_can_set_restart_ms; rtnl_link_can_set_sample_point; rtnl_link_can_state; rtnl_link_can_str2ctrlmode; rtnl_link_can_unset_ctrlmode; rtnl_link_carrier2str; rtnl_link_change; rtnl_link_delete; rtnl_link_enslave; rtnl_link_enslave_ifindex; rtnl_link_fill_info; rtnl_link_flags2str; rtnl_link_get; rtnl_link_get_addr; rtnl_link_get_arptype; rtnl_link_get_broadcast; rtnl_link_get_by_name; rtnl_link_get_carrier; rtnl_link_get_family; rtnl_link_get_flags; rtnl_link_get_group; rtnl_link_get_ifalias; rtnl_link_get_ifindex; rtnl_link_get_info_type; rtnl_link_get_kernel; rtnl_link_get_link; rtnl_link_get_linkmode; rtnl_link_get_master; rtnl_link_get_mtu; rtnl_link_get_name; rtnl_link_get_ns_fd; rtnl_link_get_ns_pid; rtnl_link_get_num_rx_queues; rtnl_link_get_num_tx_queues; rtnl_link_get_num_vf; rtnl_link_get_operstate; rtnl_link_get_phys_port_id; rtnl_link_get_pmtudisc; rtnl_link_get_promiscuity; rtnl_link_get_qdisc; rtnl_link_get_stat; rtnl_link_get_txqlen; rtnl_link_get_type; rtnl_link_get_weight; rtnl_link_i2name; rtnl_link_inet_devconf2str; rtnl_link_inet_get_conf; rtnl_link_inet_set_conf; rtnl_link_inet_str2devconf; rtnl_link_info_parse; rtnl_link_ip6_tnl_add; rtnl_link_ip6_tnl_alloc; rtnl_link_ip6_tnl_get_encaplimit; rtnl_link_ip6_tnl_get_flags; rtnl_link_ip6_tnl_get_flowinfo; rtnl_link_ip6_tnl_get_link; rtnl_link_ip6_tnl_get_local; rtnl_link_ip6_tnl_get_proto; rtnl_link_ip6_tnl_get_remote; rtnl_link_ip6_tnl_get_tos; rtnl_link_ip6_tnl_get_ttl; rtnl_link_ip6_tnl_set_encaplimit; rtnl_link_ip6_tnl_set_flags; rtnl_link_ip6_tnl_set_flowinfo; rtnl_link_ip6_tnl_set_link; rtnl_link_ip6_tnl_set_local; rtnl_link_ip6_tnl_set_proto; rtnl_link_ip6_tnl_set_remote; rtnl_link_ip6_tnl_set_tos; rtnl_link_ip6_tnl_set_ttl; rtnl_link_ipgre_add; rtnl_link_ipgre_alloc; rtnl_link_ipgre_get_iflags; rtnl_link_ipgre_get_ikey; rtnl_link_ipgre_get_link; rtnl_link_ipgre_get_local; rtnl_link_ipgre_get_oflags; rtnl_link_ipgre_get_okey; rtnl_link_ipgre_get_remote; rtnl_link_ipgre_get_tos; rtnl_link_ipgre_get_ttl; rtnl_link_ipgre_set_iflags; rtnl_link_ipgre_set_ikey; rtnl_link_ipgre_set_link; rtnl_link_ipgre_set_local; rtnl_link_ipgre_set_oflags; rtnl_link_ipgre_set_okey; rtnl_link_ipgre_set_pmtudisc; rtnl_link_ipgre_set_remote; rtnl_link_ipgre_set_tos; rtnl_link_ipgre_set_ttl; rtnl_link_ipip_add; rtnl_link_ipip_alloc; rtnl_link_ipip_get_link; rtnl_link_ipip_get_local; rtnl_link_ipip_get_pmtudisc; rtnl_link_ipip_get_remote; rtnl_link_ipip_get_tos; rtnl_link_ipip_get_ttl; rtnl_link_ipip_set_link; rtnl_link_ipip_set_local; rtnl_link_ipip_set_pmtudisc; rtnl_link_ipip_set_remote; rtnl_link_ipip_set_tos; rtnl_link_ipip_set_ttl; rtnl_link_ipvti_add; rtnl_link_ipvti_alloc; rtnl_link_ipvti_get_ikey; rtnl_link_ipvti_get_link; rtnl_link_ipvti_get_local; rtnl_link_ipvti_get_okey; rtnl_link_ipvti_get_remote; rtnl_link_ipvti_set_ikey; rtnl_link_ipvti_set_link; rtnl_link_ipvti_set_local; rtnl_link_ipvti_set_okey; rtnl_link_ipvti_set_remote; rtnl_link_is_bridge; rtnl_link_is_can; rtnl_link_is_ip6_tnl; rtnl_link_is_ipgre; rtnl_link_is_ipip; rtnl_link_is_ipvti; rtnl_link_is_macvlan; rtnl_link_is_sit; rtnl_link_is_veth; rtnl_link_is_vlan; rtnl_link_is_vxlan; rtnl_link_macvlan_alloc; rtnl_link_macvlan_flags2str; rtnl_link_macvlan_get_flags; rtnl_link_macvlan_get_mode; rtnl_link_macvlan_mode2str; rtnl_link_macvlan_set_flags; rtnl_link_macvlan_set_mode; rtnl_link_macvlan_str2flags; rtnl_link_macvlan_str2mode; rtnl_link_macvlan_unset_flags; rtnl_link_mode2str; rtnl_link_name2i; rtnl_link_operstate2str; rtnl_link_put; rtnl_link_release; rtnl_link_release_ifindex; rtnl_link_set_addr; rtnl_link_set_arptype; rtnl_link_set_broadcast; rtnl_link_set_carrier; rtnl_link_set_family; rtnl_link_set_flags; rtnl_link_set_group; rtnl_link_set_ifalias; rtnl_link_set_ifindex; rtnl_link_set_info_type; rtnl_link_set_link; rtnl_link_set_linkmode; rtnl_link_set_master; rtnl_link_set_mtu; rtnl_link_set_name; rtnl_link_set_ns_fd; rtnl_link_set_ns_pid; rtnl_link_set_num_rx_queues; rtnl_link_set_num_tx_queues; rtnl_link_set_operstate; rtnl_link_set_promiscuity; rtnl_link_set_qdisc; rtnl_link_set_stat; rtnl_link_set_txqlen; rtnl_link_set_type; rtnl_link_set_weight; rtnl_link_sit_add; rtnl_link_sit_alloc; rtnl_link_sit_get_flags; rtnl_link_sit_get_link; rtnl_link_sit_get_local; rtnl_link_sit_get_pmtudisc; rtnl_link_sit_get_proto; rtnl_link_sit_get_remote; rtnl_link_sit_get_tos; rtnl_link_sit_get_ttl; rtnl_link_sit_set_flags; rtnl_link_sit_set_link; rtnl_link_sit_set_local; rtnl_link_sit_set_pmtudisc; rtnl_link_sit_set_proto; rtnl_link_sit_set_remote; rtnl_link_sit_set_tos; rtnl_link_sit_set_ttl; rtnl_link_stat2str; rtnl_link_str2carrier; rtnl_link_str2flags; rtnl_link_str2mode; rtnl_link_str2operstate; rtnl_link_str2stat; rtnl_link_unset_flags; rtnl_link_veth_add; rtnl_link_veth_alloc; rtnl_link_veth_get_peer; rtnl_link_veth_release; rtnl_link_vlan_alloc; rtnl_link_vlan_flags2str; rtnl_link_vlan_get_egress_map; rtnl_link_vlan_get_flags; rtnl_link_vlan_get_id; rtnl_link_vlan_get_ingress_map; rtnl_link_vlan_get_protocol; rtnl_link_vlan_set_egress_map; rtnl_link_vlan_set_flags; rtnl_link_vlan_set_id; rtnl_link_vlan_set_ingress_map; rtnl_link_vlan_set_protocol; rtnl_link_vlan_str2flags; rtnl_link_vlan_unset_flags; rtnl_link_vxlan_alloc; rtnl_link_vxlan_disable_l2miss; rtnl_link_vxlan_disable_l3miss; rtnl_link_vxlan_disable_learning; rtnl_link_vxlan_disable_proxy; rtnl_link_vxlan_disable_rsc; rtnl_link_vxlan_enable_l2miss; rtnl_link_vxlan_enable_l3miss; rtnl_link_vxlan_enable_learning; rtnl_link_vxlan_enable_proxy; rtnl_link_vxlan_enable_rsc; rtnl_link_vxlan_get_ageing; rtnl_link_vxlan_get_group; rtnl_link_vxlan_get_id; rtnl_link_vxlan_get_l2miss; rtnl_link_vxlan_get_l3miss; rtnl_link_vxlan_get_learning; rtnl_link_vxlan_get_limit; rtnl_link_vxlan_get_link; rtnl_link_vxlan_get_local; rtnl_link_vxlan_get_port_range; rtnl_link_vxlan_get_proxy; rtnl_link_vxlan_get_rsc; rtnl_link_vxlan_get_tos; rtnl_link_vxlan_get_ttl; rtnl_link_vxlan_set_ageing; rtnl_link_vxlan_set_group; rtnl_link_vxlan_set_id; rtnl_link_vxlan_set_l2miss; rtnl_link_vxlan_set_l3miss; rtnl_link_vxlan_set_learning; rtnl_link_vxlan_set_limit; rtnl_link_vxlan_set_link; rtnl_link_vxlan_set_local; rtnl_link_vxlan_set_port_range; rtnl_link_vxlan_set_proxy; rtnl_link_vxlan_set_rsc; rtnl_link_vxlan_set_tos; rtnl_link_vxlan_set_ttl; rtnl_meta_value_alloc_id; rtnl_meta_value_alloc_int; rtnl_meta_value_alloc_var; rtnl_meta_value_put; rtnl_mirred_get_action; rtnl_mirred_get_ifindex; rtnl_mirred_get_policy; rtnl_mirred_set_action; rtnl_mirred_set_ifindex; rtnl_mirred_set_policy; rtnl_neigh_add; rtnl_neigh_alloc; rtnl_neigh_alloc_cache; rtnl_neigh_build_add_request; rtnl_neigh_build_delete_request; rtnl_neigh_delete; rtnl_neigh_flags2str; rtnl_neigh_get; rtnl_neigh_get_dst; rtnl_neigh_get_family; rtnl_neigh_get_flags; rtnl_neigh_get_ifindex; rtnl_neigh_get_lladdr; rtnl_neigh_get_state; rtnl_neigh_get_type; rtnl_neigh_parse; rtnl_neigh_put; rtnl_neigh_set_dst; rtnl_neigh_set_family; rtnl_neigh_set_flags; rtnl_neigh_set_ifindex; rtnl_neigh_set_lladdr; rtnl_neigh_set_state; rtnl_neigh_set_type; rtnl_neigh_state2str; rtnl_neigh_str2flag; rtnl_neigh_str2state; rtnl_neigh_unset_flags; rtnl_neigh_unset_state; rtnl_neightbl_alloc; rtnl_neightbl_alloc_cache; rtnl_neightbl_build_change_request; rtnl_neightbl_change; rtnl_neightbl_get; rtnl_neightbl_put; rtnl_neightbl_set_anycast_delay; rtnl_neightbl_set_app_probes; rtnl_neightbl_set_base_reachable_time; rtnl_neightbl_set_delay_probe_time; rtnl_neightbl_set_dev; rtnl_neightbl_set_family; rtnl_neightbl_set_gc_interval; rtnl_neightbl_set_gc_stale_time; rtnl_neightbl_set_gc_tresh1; rtnl_neightbl_set_gc_tresh2; rtnl_neightbl_set_gc_tresh3; rtnl_neightbl_set_locktime; rtnl_neightbl_set_mcast_probes; rtnl_neightbl_set_name; rtnl_neightbl_set_proxy_delay; rtnl_neightbl_set_proxy_queue_len; rtnl_neightbl_set_queue_len; rtnl_neightbl_set_retrans_time; rtnl_neightbl_set_ucast_probes; rtnl_netem_get_corruption_correlation; rtnl_netem_get_corruption_probability; rtnl_netem_get_delay; rtnl_netem_get_delay_correlation; rtnl_netem_get_delay_distribution; rtnl_netem_get_delay_distribution_size; rtnl_netem_get_duplicate; rtnl_netem_get_duplicate_correlation; rtnl_netem_get_gap; rtnl_netem_get_jitter; rtnl_netem_get_limit; rtnl_netem_get_loss; rtnl_netem_get_loss_correlation; rtnl_netem_get_reorder_correlation; rtnl_netem_get_reorder_probability; rtnl_netem_set_corruption_correlation; rtnl_netem_set_corruption_probability; rtnl_netem_set_delay; rtnl_netem_set_delay_correlation; rtnl_netem_set_delay_distribution; rtnl_netem_set_duplicate; rtnl_netem_set_duplicate_correlation; rtnl_netem_set_gap; rtnl_netem_set_jitter; rtnl_netem_set_limit; rtnl_netem_set_loss; rtnl_netem_set_loss_correlation; rtnl_netem_set_reorder_correlation; rtnl_netem_set_reorder_probability; rtnl_pktloc_add; rtnl_pktloc_alloc; rtnl_pktloc_foreach; rtnl_pktloc_lookup; rtnl_pktloc_put; rtnl_prio2str; rtnl_qdisc_add; rtnl_qdisc_alloc; rtnl_qdisc_alloc_cache; rtnl_qdisc_build_add_request; rtnl_qdisc_build_change_request; rtnl_qdisc_build_delete_request; rtnl_qdisc_build_update_request; rtnl_qdisc_change; rtnl_qdisc_delete; rtnl_qdisc_dsmark_get_default_index; rtnl_qdisc_dsmark_get_indices; rtnl_qdisc_dsmark_get_set_tc_index; rtnl_qdisc_dsmark_set_default_index; rtnl_qdisc_dsmark_set_indices; rtnl_qdisc_dsmark_set_set_tc_index; rtnl_qdisc_fifo_get_limit; rtnl_qdisc_fifo_set_limit; rtnl_qdisc_foreach_child; rtnl_qdisc_foreach_cls; rtnl_qdisc_fq_codel_get_ecn; rtnl_qdisc_fq_codel_get_flows; rtnl_qdisc_fq_codel_get_interval; rtnl_qdisc_fq_codel_get_limit; rtnl_qdisc_fq_codel_get_quantum; rtnl_qdisc_fq_codel_get_target; rtnl_qdisc_fq_codel_set_ecn; rtnl_qdisc_fq_codel_set_flows; rtnl_qdisc_fq_codel_set_interval; rtnl_qdisc_fq_codel_set_limit; rtnl_qdisc_fq_codel_set_quantum; rtnl_qdisc_fq_codel_set_target; rtnl_qdisc_get; rtnl_qdisc_get_by_parent; rtnl_qdisc_plug_buffer; rtnl_qdisc_plug_release_indefinite; rtnl_qdisc_plug_release_one; rtnl_qdisc_plug_set_limit; rtnl_qdisc_prio_get_bands; rtnl_qdisc_prio_get_priomap; rtnl_qdisc_prio_set_bands; rtnl_qdisc_prio_set_priomap; rtnl_qdisc_put; rtnl_qdisc_tbf_get_limit; rtnl_qdisc_tbf_get_peakrate; rtnl_qdisc_tbf_get_peakrate_bucket; rtnl_qdisc_tbf_get_peakrate_cell; rtnl_qdisc_tbf_get_rate; rtnl_qdisc_tbf_get_rate_bucket; rtnl_qdisc_tbf_get_rate_cell; rtnl_qdisc_tbf_set_limit; rtnl_qdisc_tbf_set_limit_by_latency; rtnl_qdisc_tbf_set_peakrate; rtnl_qdisc_tbf_set_rate; rtnl_qdisc_update; rtnl_realms2str; rtnl_red_get_limit; rtnl_red_set_limit; rtnl_route_add; rtnl_route_add_nexthop; rtnl_route_alloc; rtnl_route_alloc_cache; rtnl_route_build_add_request; rtnl_route_build_del_request; rtnl_route_build_msg; rtnl_route_delete; rtnl_route_foreach_nexthop; rtnl_route_get; rtnl_route_get_dst; rtnl_route_get_family; rtnl_route_get_flags; rtnl_route_get_iif; rtnl_route_get_metric; rtnl_route_get_nexthops; rtnl_route_get_nnexthops; rtnl_route_get_pref_src; rtnl_route_get_priority; rtnl_route_get_protocol; rtnl_route_get_scope; rtnl_route_get_src; rtnl_route_get_table; rtnl_route_get_tos; rtnl_route_get_type; rtnl_route_guess_scope; rtnl_route_metric2str; rtnl_route_nexthop_n; rtnl_route_nh_alloc; rtnl_route_nh_clone; rtnl_route_nh_compare; rtnl_route_nh_dump; rtnl_route_nh_flags2str; rtnl_route_nh_free; rtnl_route_nh_get_flags; rtnl_route_nh_get_gateway; rtnl_route_nh_get_ifindex; rtnl_route_nh_get_realms; rtnl_route_nh_get_weight; rtnl_route_nh_set_flags; rtnl_route_nh_set_gateway; rtnl_route_nh_set_ifindex; rtnl_route_nh_set_realms; rtnl_route_nh_set_weight; rtnl_route_nh_str2flags; rtnl_route_nh_unset_flags; rtnl_route_parse; rtnl_route_proto2str; rtnl_route_put; rtnl_route_read_protocol_names; rtnl_route_read_table_names; rtnl_route_remove_nexthop; rtnl_route_set_dst; rtnl_route_set_family; rtnl_route_set_flags; rtnl_route_set_iif; rtnl_route_set_metric; rtnl_route_set_pref_src; rtnl_route_set_priority; rtnl_route_set_protocol; rtnl_route_set_scope; rtnl_route_set_src; rtnl_route_set_table; rtnl_route_set_tos; rtnl_route_set_type; rtnl_route_str2metric; rtnl_route_str2proto; rtnl_route_str2table; rtnl_route_table2str; rtnl_route_unset_flags; rtnl_route_unset_metric; rtnl_rule_add; rtnl_rule_alloc; rtnl_rule_alloc_cache; rtnl_rule_build_add_request; rtnl_rule_build_delete_request; rtnl_rule_delete; rtnl_rule_get_action; rtnl_rule_get_dsfield; rtnl_rule_get_dst; rtnl_rule_get_family; rtnl_rule_get_goto; rtnl_rule_get_iif; rtnl_rule_get_mark; rtnl_rule_get_mask; rtnl_rule_get_oif; rtnl_rule_get_prio; rtnl_rule_get_realms; rtnl_rule_get_src; rtnl_rule_get_table; rtnl_rule_put; rtnl_rule_set_action; rtnl_rule_set_dsfield; rtnl_rule_set_dst; rtnl_rule_set_family; rtnl_rule_set_goto; rtnl_rule_set_iif; rtnl_rule_set_mark; rtnl_rule_set_mask; rtnl_rule_set_oif; rtnl_rule_set_prio; rtnl_rule_set_realms; rtnl_rule_set_src; rtnl_rule_set_table; rtnl_scope2str; rtnl_sfq_get_divisor; rtnl_sfq_get_limit; rtnl_sfq_get_perturb; rtnl_sfq_get_quantum; rtnl_sfq_set_limit; rtnl_sfq_set_perturb; rtnl_sfq_set_quantum; rtnl_str2prio; rtnl_str2scope; rtnl_tc_calc_bufsize; rtnl_tc_calc_cell_log; rtnl_tc_calc_txtime; rtnl_tc_get_handle; rtnl_tc_get_ifindex; rtnl_tc_get_kind; rtnl_tc_get_link; rtnl_tc_get_linktype; rtnl_tc_get_mpu; rtnl_tc_get_mtu; rtnl_tc_get_overhead; rtnl_tc_get_parent; rtnl_tc_get_stat; rtnl_tc_handle2str; rtnl_tc_read_classid_file; rtnl_tc_set_handle; rtnl_tc_set_ifindex; rtnl_tc_set_kind; rtnl_tc_set_link; rtnl_tc_set_linktype; rtnl_tc_set_mpu; rtnl_tc_set_mtu; rtnl_tc_set_overhead; rtnl_tc_set_parent; rtnl_tc_str2handle; rtnl_u32_add_action; rtnl_u32_add_key; rtnl_u32_add_key_in6_addr; rtnl_u32_add_key_in_addr; rtnl_u32_add_key_uint16; rtnl_u32_add_key_uint32; rtnl_u32_add_key_uint8; rtnl_u32_del_action; rtnl_u32_get_key; rtnl_u32_set_classid; rtnl_u32_set_cls_terminal; rtnl_u32_set_divisor; rtnl_u32_set_flags; rtnl_u32_set_handle; rtnl_u32_set_hashmask; rtnl_u32_set_hashtable; rtnl_u32_set_link; # The following symbols were added during the development of 3.2.26. # Keep them in libnl_3 to avoid breaking users. rtnl_class_hfsc_get_fsc; rtnl_class_hfsc_get_rsc; rtnl_class_hfsc_get_usc; rtnl_class_hfsc_set_fsc; rtnl_class_hfsc_set_rsc; rtnl_class_hfsc_set_usc; rtnl_link_inet6_addrgenmode2str; rtnl_link_inet6_get_addr_gen_mode; rtnl_link_inet6_get_token; rtnl_link_inet6_set_addr_gen_mode; rtnl_link_inet6_set_token; rtnl_link_inet6_str2addrgenmode; rtnl_qdisc_hfsc_get_defcls; rtnl_qdisc_hfsc_set_defcls; rtnl_u32_add_mark; rtnl_u32_del_mark; local: *; }; libnl_3_2_26 { global: rtnl_neigh_get_vlan; rtnl_neigh_set_vlan; rtnl_skbedit_get_action; rtnl_skbedit_get_mark; rtnl_skbedit_get_priority; rtnl_skbedit_get_queue_mapping; rtnl_skbedit_set_action; rtnl_skbedit_set_mark; rtnl_skbedit_set_priority; rtnl_skbedit_set_queue_mapping; rtnl_tc_stat2str; rtnl_tc_str2stat; rtnl_u32_get_classid; } libnl_3; libnl_3_2_27 { global: rtnl_link_get_link_netnsid; rtnl_link_ipvlan_alloc; rtnl_link_is_ipvlan; rtnl_link_ipvlan_mode2str; rtnl_link_ipvlan_str2mode; rtnl_link_ipvlan_set_mode; rtnl_link_ipvlan_get_mode; rtnl_link_set_link_netnsid; } libnl_3_2_26; libnl_3_2_28 { global: rtnl_link_alloc_cache_flags; rtnl_link_bridge_get_port_vlan; rtnl_link_bridge_has_vlan; rtnl_link_bridge_pvid; rtnl_link_is_macvtap; rtnl_link_is_vrf; rtnl_link_ipgretap_add; rtnl_link_ipgretap_alloc; rtnl_link_macsec_alloc; rtnl_link_macsec_set_sci; rtnl_link_macsec_get_sci; rtnl_link_macsec_set_port; rtnl_link_macsec_get_port; rtnl_link_macsec_set_cipher_suite; rtnl_link_macsec_get_cipher_suite; rtnl_link_macsec_set_icv_len; rtnl_link_macsec_get_icv_len; rtnl_link_macsec_set_protect; rtnl_link_macsec_get_protect; rtnl_link_macsec_set_encrypt; rtnl_link_macsec_get_encrypt; rtnl_link_macsec_set_encoding_sa; rtnl_link_macsec_get_encoding_sa; rtnl_link_macsec_set_validation_type; rtnl_link_macsec_get_validation_type; rtnl_link_macsec_set_replay_protect; rtnl_link_macsec_get_replay_protect; rtnl_link_macsec_set_window; rtnl_link_macsec_get_window; rtnl_link_macsec_set_send_sci; rtnl_link_macsec_get_send_sci; rtnl_link_macsec_set_end_station; rtnl_link_macsec_get_end_station; rtnl_link_macsec_set_scb; rtnl_link_macsec_get_scb; rtnl_link_macvtap_alloc; rtnl_link_macvtap_flags2str; rtnl_link_macvtap_get_flags; rtnl_link_macvtap_get_mode; rtnl_link_macvtap_mode2str; rtnl_link_macvtap_set_flags; rtnl_link_macvtap_set_mode; rtnl_link_macvtap_str2flags; rtnl_link_macvtap_str2mode; rtnl_link_macvtap_unset_flags; rtnl_link_sit_get_ip6rd_prefix; rtnl_link_sit_get_ip6rd_prefixlen; rtnl_link_sit_get_ip6rd_relay_prefix; rtnl_link_sit_get_ip6rd_relay_prefixlen; rtnl_link_sit_set_ip6rd_prefix; rtnl_link_sit_set_ip6rd_prefixlen; rtnl_link_sit_set_ip6rd_relay_prefix; rtnl_link_sit_set_ip6rd_relay_prefixlen; rtnl_link_vrf_alloc; rtnl_link_vrf_get_tableid; rtnl_link_vrf_set_tableid; rtnl_neigh_alloc_cache_flags; rtnl_neigh_ll_get; } libnl_3_2_27; libnl_3_2_29 { global: rtnl_gact_set_action; rtnl_gact_get_action; rtnl_link_bridge_portstate2str; rtnl_link_bridge_str2portstate; rtnl_link_bridge_set_self; rtnl_link_bridge_get_hwmode; rtnl_link_bridge_set_hwmode; rtnl_link_bridge_hwmode2str; rtnl_link_bridge_str2hwmode; rtnl_link_get_carrier_changes; rtnl_link_get_gso_max_segs; rtnl_link_get_gso_max_size; rtnl_link_get_phys_port_name; rtnl_link_get_phys_switch_id; rtnl_link_ipgre_get_pmtudisc; rtnl_link_is_ipgretap; rtnl_link_macvlan_add_macaddr; rtnl_link_macvlan_count_macaddr; rtnl_link_macvlan_del_macaddr; rtnl_link_macvlan_get_macaddr; rtnl_link_macvlan_get_macmode; rtnl_link_macvlan_macmode2str; rtnl_link_macvlan_set_macmode; rtnl_link_macvlan_str2macmode; rtnl_link_ppp_alloc; rtnl_link_ppp_set_fd; rtnl_link_ppp_get_fd; rtnl_link_vxlan_get_collect_metadata; rtnl_link_vxlan_get_flags; rtnl_link_vxlan_get_label; rtnl_link_vxlan_get_port; rtnl_link_vxlan_get_remcsum_rx; rtnl_link_vxlan_get_remcsum_tx; rtnl_link_vxlan_get_udp_csum; rtnl_link_vxlan_get_udp_zero_csum6_rx; rtnl_link_vxlan_get_udp_zero_csum6_tx; rtnl_link_vxlan_set_collect_metadata; rtnl_link_vxlan_set_flags; rtnl_link_vxlan_set_label; rtnl_link_vxlan_set_port; rtnl_link_vxlan_set_remcsum_rx; rtnl_link_vxlan_set_remcsum_tx; rtnl_link_vxlan_set_udp_csum; rtnl_link_vxlan_set_udp_zero_csum6_rx; rtnl_link_vxlan_set_udp_zero_csum6_tx; rtnl_link_has_vf_list; rtnl_link_set_vf_list; rtnl_link_unset_vf_list; rtnl_link_vf_add; rtnl_link_vf_alloc; rtnl_link_vf_free; rtnl_link_vf_get; rtnl_link_vf_put; rtnl_link_vf_get_addr; rtnl_link_vf_set_addr; rtnl_link_vf_set_ib_node_guid; rtnl_link_vf_set_ib_port_guid; rtnl_link_vf_get_index; rtnl_link_vf_set_index; rtnl_link_vf_get_linkstate; rtnl_link_vf_set_linkstate; rtnl_link_vf_get_rate; rtnl_link_vf_set_rate; rtnl_link_vf_get_rss_query_en; rtnl_link_vf_set_rss_query_en; rtnl_link_vf_get_spoofchk; rtnl_link_vf_set_spoofchk; rtnl_link_vf_get_stat; rtnl_link_vf_get_trust; rtnl_link_vf_set_trust; rtnl_link_vf_get_vlans; rtnl_link_vf_set_vlans; rtnl_link_vf_vlan_alloc; rtnl_link_vf_vlan_free; rtnl_link_vf_vlan_put; rtnl_link_vf_linkstate2str; rtnl_link_vf_str2linkstate; rtnl_link_vf_vlanproto2str; rtnl_link_vf_str2vlanproto; rtnl_link_vf_str2guid; rtnl_u32_set_selector; } libnl_3_2_28; libnl-3.2.29/ChangeLog0000644000175000017500000003310013023014600011364 00000000000000ChangeLog discontinued, git history can be found here: http://git.infradead.org/users/tgr/libnl.git Summary of Changes from 1.0-pre6 to 1.0-pre7 ================================================ Thomas Graf o Generic netlink support o Route Addition/Deletion o Added nl_cache_subset() o Have nl_object_clone() make real clones without sharing any data. o Remove old nl_object_alloc() not based on a object operations to avoid bugs due to missing init. o Added nl-list-caches utility o Removed nlmsg_build_no_hdr(), duplicate o Reworked message interface o Fixed nlmsg_put() and genlmsg_put() to correctly reserve tail room for user specific headers. o Added nl_cache_move() o Renamed nl_cache_delete() to nl_cache_remove() (no API break) o Fixed reference counting while objects stay in caches. o Object marking o Moved attribute mask for objects into generic structure o nl-list-caches: List available dump procedures o Use PAGE_SIZE as initial buffer size when reading from netlink socket o Double buffer size when recv() returns MSG_TRUNC o Replaced filter object operation with new compare operation capable of listing differences between two objects o Added nl_object_identical() to check if two objects are identical from a uniqueness point of view o Added nl_object_diff() returning a bitmask of differences in attributes o Added nl_object_attr_list() generating a list of attribute name the object has assigned o Cache updates based on event notifications, code based on Patrick McHardy's patches o Cache Manager o Added NL_AUTO_PID, NL_AUTO_SEQ for convenience o Disable MSG_PEEK by default and provide nl_socket_enable_msg_peek() o Fixed nl_recvmsgs() to return 0 when interrupted via NL_STOP or NL_SKIP o Fixed nl_recvmsgs() to stop reading after parsing if not in the middle of a multipart message. o Fixed nl_recvmsgs() to not stop after receving an ACK o Fixed nl_recvmsgs() to not blindly discard remaining messages if a NLMSG_DONE message is received. Petr Gotthard Siemens AG Oesterreich o Fix u32 to properly handle multiple keys o rtnl_htb_set_(r|c)buffer() o Fixed MTU handling in HTB class, problem pointed out by Edouard Thuleau Zilvinas Valinskas o Fix wrong msg_namelen in nl_recv() o Fix memory leak in flnl_request_put() Helmut Schaa o Fix for using libnl from within C++ Patrick McHardy o *_alloc_cache(): Only refill cache if handle is provided James Oakley o Fix rtnl_link_set_arptype() typo Philip Craig o Change address family type from char to int o Fix the error handling when the build fails. o add nl_cache_mngr_get_fd() o add netfilter support o add netfilter conntrack support o add netfilter log support Summary of Changes from 1.0-pre5 to 1.0-pre6 ================================================ Christopher Aillon o Use $(libdir) instead of $(prefix)/lib for 64bit awesomeness. Thomas Graf o Extend nl_msg to include source address, destination address and the protocol being used. o Make nl_send*() take a nl_msg instead of a nlmsghdr (API BREAK) o Change callbacks to take a nl_msg instead of source address and nlmsghdr (API BREAK) o caches must specify the protocol they're hooked up from now on if they intend to be associated with message types. o cache_mngt_associate now takes the protocol besides the message type to allow for multiple protocols to be supported (API BREAK) o overwrite destination address in nl_send() when specified in the message itself, allows for unbound addressing. o Support for netlink based fib_lookup() o Documentation fixes o Fix double nlmsg_free() in nl_recvmsgs() while receiving a multipart message and the read was interrupted. o Change cache operations to store names for message types. o Provide interface to convert message type to character string. o Add dp_dump_msgtype to prefix each dumped element with a pretty printed message type. o netlink fib lookup support o nl_recvmsgs() debugging o use nl_cachemngt_type2name() when pretty printing netlink header o Routing protocol translations. o Routing metric translations. o Revised route dumping o Nexthop flag translations. o Add support for IFF_DORMANT Petr Gotthard Siemens AG Oesterreich o Fix access to obj after freeing it o Fix u32 selector access after realloc() o Fix missing out-of-memory error handling in various places o Enhance nl-monitor to have group selection selectable and demonstrate usage of select() o Don't ignore IFF_RUNNING any longer o fw classifier support Patrick McHardy o Fix conflicting types for __u64 o Fix printf format string warnings o Fix object cloning o Deal with structure padding in nl_object_clone o Fix nl_addr leak o Set ce_msgtype in all parsed objects o Fix addr flag filter o Fix RTNLGRP definitions (was based on broken kernel version) o Export nl_get_errno() o Add function to get/set peer pid o Add IFF_LOWER_UP o Add/export some missing accessor functions o print /0 prefix in nl_addr2str() o Fix invalid free in nl_addr_parse for AF_UNSPEC addresses o Use __str2flags instead of __str2type in rtnl_link_str2flags() o Make sure object and filter types match in nl_object_match() o Add support for credential passing over netlink sockets (API BREAK) o Add support for custom dump callbacks o Add NL_DUMP_ENV format Michael Biebl "Alex V. Myltsev" o Makefile fixes Summary of Changes from 1.0-pre4 to 1.0-pre5 ================================================ Thomas Graf o Use minimized local copies for , , and to avoid compile troubles with applications including Reported by Christopher Aillon. Summary of Changes from 1.0-pre3 to 1.0-pre4 ================================================ Thomas Graf o Fix wrong rtnl_addr_set_prefixlen() external declaration, reported by Dan Williams. o Fix nl_addr_parse() to not change the original string for prefixes. o Do not build documentation per default, but have the user issue 'make gendoc' o Assume neighbours to be permanent, set NUD_PERMANENT if not specified otherwise. Summary of Changes from 1.0-pre2 to 1.0-pre3 ================================================ Thomas Graf o Fix SFQ parser to allocate qdisc options. o Fix rule statistics dumping to not call itself. o Complete Netem qdisc interface. o Add rtnl_*_put() and rtnl_*_free() to increase readability. o Cleanup of nl-* tools o Fix inclusion guards of route/neightbl.h o Fix nl_connect() to only modify rx/tx socket buffers if not already modified by the user. o Fix wrong nl_handle_alloc() prototype. o Fix typo in route/addr.c causing label to be marked as local address. o Use ~0UL as default prefix length instead of 0. o Fix neighbour message parser to correctly store core. attributes and provide them again. o Fix neighbour message parser to correctly guess address family. to make it compatible with nl_addr_parse() and ether llc addresses. o Add rtnl_route_table2str(), rtnl_route_str2table(). o Add nl_cache_nitems_filter() to find out if a filter produces any matches. o Remove rtnl_rule_set_(dst|src)_str() (obsolete). o Remove scope and protocol field of routing rule. o Complete routing rules module. o Move realms translations from route to rtnl module. Summary of Changes from 1.0-pre1 to 1.0-pre2 ================================================ Thomas Graf o More API documentation o Added flags argument to rtnl_addr_(add|build_add_request)(). o Added rtnl_addr_(set|get)_multicast(). o Moved scope translations routines from route/route.c to route/rtnl.c, required by other modules as well. o Removed old rtattr bits from rtnetlink-kernel.h o Customized libnl.css for doxygen documentation o Removed non-reentrant translation routines, only bloating the code and too risky. o Fixed wrong version number from 1.0-pre1. o Reenabled unfinished policer module. o Reworked TBF module, automatic caluclation of transmit times, limit setable via latency, automatic cell size calculation, options TLV generation. (untested) o Renamed nl_xmittime() to rtnl_tc_calc_txtime(). o Renamde nl_build_rtable() to rtnl_tc_build_rate_table() Petr Gotthard , Siemens AG Oesterreich o Fix symlinks to libnl library files to be moveable o Fix extern struct prototypes meant to be static. o Add empty install target to src/Makefile Simon Stelling o Use LIBDIR instead of $(prefix)/lib for users to alllow librariers into $(prefix)/lib64. Summary of Changes from 0.5.0 to 1.0-pre1 ================================================ Thomas Graf o Uncountable number of changes, rewrite of certain modules, several major API breakages Petr Gotthard , Siemens AG Oesterreich o added class_build, rtnl_class_build_add_request, rtnl_class_add o added HTB (Hierachical Token Bucket) class support o added nl_xmittime, nl_build_rtable o added nl_data_append to realloc a nl_data structure o added rtnl_rcopy_ratespec as reverse to rtnl_copy_ratespec o fixed byte order conversion of rtnl_filter.protocol o SuSE and Fedora Linux compile fixes o fixed u32 classifier support o added rtnl_u32_set_handle, rtnl_u32_set_classid, rtnl_u32_set_flags and several rtnl_u32_add_key_... operations to u32 classifier Summary of Changes from 0.4.4 to 0.5.0 ================================================ Thomas Graf o API documentation o nl_cache_filter to manually filter on a object o partial routing support o routing rules support o Propely set address family when setting addresses o debug flag and some rare messages, more to come o make error mesage verboseness configureable o tc fixes to wait for ack o cleanup and adaption of address code to latest internal API o various cleanups o dozens of API breakages (better now than later) Daniel Hottinger o arch 64bit printf length modifier fixes Baruch Even , Mediatrix Telecom, inc. o address support Summary of changes from 0.4.3 to 0.4.4 ================================================ Thomas Graf : o overall cleanups for better code quality o replace dump_(brief|full|with_stats) ops with dump[NL_DUMP_MAX] array to allow further additions without breaking the ABI. o add of send_ack callback, called whenever when oppenent asks for an ACK. o make nl_parse_rtattr initialize the tb buffer like in the kernel, caller must no longer take care of it. o remove nl_addrnattr (obsolete) o fixed nl_msg_append_raw to correctly calculate length for raw data not aligned to NLMSG_ALIGN o fix memory leak in nl_recv in case of errors o correctly check sequence numbers if more than one message was sent out before the answer is being received. o add workaround for buggy netlink applications not properly setting NLM_F_MULTI. Summary of changes from 0.4.2 to 0.4.3 ================================================ Thomas Graf : o use parser_param in nl_cache_parse o EGP: dump nfilters attribute o allow retrieving of filters attached to classes via FILTER_CACHE_PARENT(C) cache argument o filter message building API Summary of changes from 0.4.1 to 0.4.2 ================================================ Baruch Even : o memory leak fix in nl_parse_rtattr o reset padding to 0 when appending raw data to a nl_msg o avoid overwriting nlmsg ptr when buffer extending fails o typo fixes o create symlinks libnl.so.0 and libnl.so Thomas Graf : o EGP classifier support o avoid null pointer in printf call o added nl_cache_parse to put nl_msg's into a cache o added rtnl_filter_build to build a nl_msg filter message o correctly install header files o nl_msg_payload/nl_msg_payloadlen to access nl_msg payload o nl_parse_nested macro to simplify nested TLV parsing o NL_ERROR_ASSERT compile flag to assert(0) on errors o rta alignment fix in nl_msg_append_tlv o added nl_msg_parse_rtattr as shortcut for nl_parse_rtattr for nl_msg API o added nl_parse_nested for nested TLVs o added RTA_ARRAY_ELEMS macro to calculate array length for array TLVs o added nl_wait_for_ack to wait for the next ack o added rtnl_link_build_change_request(...) o added rtnl_neigh_build_*_request o converted neighbour code to use nl_wait_for_ack o cb_recvmsgs_ow callback to overwrite internal calls to nl_recvmsgs_def o cb_seq_check callback to overwrite default sequence checking o added nl_parser_param as argument for message parsers including a callback to be called upon successful parsing of a message. Removes the requirement of having all parsed messages to be added to a cache. o added cb_recv_ow and nl_send_ow callbacks to overwrite internal calls to nl_recv and nl_send. Jamal Hadi Salim o Linux 2.4 compile fixes libnl-3.2.29/libnl-3.0.pc.in0000644000175000017500000000037713023014600012153 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnl Description: Convenience library for netlink sockets Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lnl-@MAJ_VERSION@ Cflags: -I${includedir}/libnl@MAJ_VERSION@ libnl-3.2.29/libnl-genl-3.sym0000644000175000017500000000177413023014600012543 00000000000000libnl_3 { global: # these functions are in private header files and should have never # been exported. We might hide them later. genl_resolve_id; genl_connect; genl_ctrl_alloc_cache; genl_ctrl_resolve; genl_ctrl_resolve_grp; genl_ctrl_search; genl_ctrl_search_by_name; genl_family_add_grp; genl_family_add_op; genl_family_alloc; genl_family_get_hdrsize; genl_family_get_id; genl_family_get_maxattr; genl_family_get_name; genl_family_get_version; genl_family_ops; genl_family_put; genl_family_set_hdrsize; genl_family_set_id; genl_family_set_maxattr; genl_family_set_name; genl_family_set_version; genl_handle_msg; genl_mngt_resolve; genl_op2name; genl_ops_resolve; genl_register; genl_register_family; genl_send_simple; genl_unregister; genl_unregister_family; genlmsg_attrdata; genlmsg_attrlen; genlmsg_data; genlmsg_hdr; genlmsg_len; genlmsg_parse; genlmsg_put; genlmsg_user_data; genlmsg_user_datalen; genlmsg_user_hdr; genlmsg_valid_hdr; genlmsg_validate; local: *; }; libnl-3.2.29/libnl-idiag-3.0.pc.in0000644000175000017500000000043113023014600013215 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnl-idiag Description: Netlink Inet Diag Family Library Version: @PACKAGE_VERSION@ Requires: libnl-3.0 Libs: -L${libdir} -lnl-idiag-@MAJ_VERSION@ Cflags: -I${includedir}/libnl@MAJ_VERSION@ libnl-3.2.29/aclocal.m40000644000175000017500000015240113031473642011476 00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) libnl-3.2.29/libnl-idiag-3.sym0000644000175000017500000000472313023014600012670 00000000000000libnl_3 { global: # ops structure idiagnl_meminfo_obj_ops; idiagnl_msg_obj_ops; idiagnl_req_obj_ops; idiagnl_vegasinfo_obj_ops; idiagnl_attrs2str; idiagnl_connect; idiagnl_exts2str; idiagnl_meminfo_alloc; idiagnl_meminfo_get; idiagnl_meminfo_get_fmem; idiagnl_meminfo_get_rmem; idiagnl_meminfo_get_tmem; idiagnl_meminfo_get_wmem; idiagnl_meminfo_put; idiagnl_meminfo_set_fmem; idiagnl_meminfo_set_rmem; idiagnl_meminfo_set_tmem; idiagnl_meminfo_set_wmem; idiagnl_msg_alloc; idiagnl_msg_alloc_cache; idiagnl_msg_get; idiagnl_msg_get_cong; idiagnl_msg_get_dport; idiagnl_msg_get_dst; idiagnl_msg_get_expires; idiagnl_msg_get_family; idiagnl_msg_get_ifindex; idiagnl_msg_get_inode; idiagnl_msg_get_meminfo; idiagnl_msg_get_retrans; idiagnl_msg_get_rqueue; idiagnl_msg_get_shutdown; idiagnl_msg_get_sport; idiagnl_msg_get_src; idiagnl_msg_get_state; idiagnl_msg_get_tclass; idiagnl_msg_get_tcpinfo; idiagnl_msg_get_timer; idiagnl_msg_get_tos; idiagnl_msg_get_uid; idiagnl_msg_get_vegasinfo; idiagnl_msg_get_wqueue; idiagnl_msg_parse; idiagnl_msg_put; idiagnl_msg_set_cong; idiagnl_msg_set_dport; idiagnl_msg_set_dst; idiagnl_msg_set_expires; idiagnl_msg_set_family; idiagnl_msg_set_ifindex; idiagnl_msg_set_inode; idiagnl_msg_set_meminfo; idiagnl_msg_set_retrans; idiagnl_msg_set_rqueue; idiagnl_msg_set_shutdown; idiagnl_msg_set_sport; idiagnl_msg_set_src; idiagnl_msg_set_state; idiagnl_msg_set_tclass; idiagnl_msg_set_tcpinfo; idiagnl_msg_set_timer; idiagnl_msg_set_tos; idiagnl_msg_set_uid; idiagnl_msg_set_vegasinfo; idiagnl_msg_set_wqueue; idiagnl_req_alloc; idiagnl_req_get; idiagnl_req_get_dbs; idiagnl_req_get_dst; idiagnl_req_get_ext; idiagnl_req_get_family; idiagnl_req_get_ifindex; idiagnl_req_get_src; idiagnl_req_get_states; idiagnl_req_parse; idiagnl_req_put; idiagnl_req_set_dbs; idiagnl_req_set_dst; idiagnl_req_set_ext; idiagnl_req_set_family; idiagnl_req_set_ifindex; idiagnl_req_set_src; idiagnl_req_set_states; idiagnl_send_simple; idiagnl_shutdown2str; idiagnl_state2str; idiagnl_str2state; idiagnl_str2timer; idiagnl_tcpopts2str; idiagnl_tcpstate2str; idiagnl_timer2str; idiagnl_vegasinfo_alloc; idiagnl_vegasinfo_get; idiagnl_vegasinfo_get_enabled; idiagnl_vegasinfo_get_minrtt; idiagnl_vegasinfo_get_rtt; idiagnl_vegasinfo_get_rttcnt; idiagnl_vegasinfo_put; idiagnl_vegasinfo_set_enabled; idiagnl_vegasinfo_set_minrtt; idiagnl_vegasinfo_set_rtt; idiagnl_vegasinfo_set_rttcnt; local: *; }; libnl-3.2.29/python/0000755000175000017500000000000013031473756011242 500000000000000libnl-3.2.29/python/Makefile.am0000644000175000017500000000007113023014600013170 00000000000000# -*- Makefile -*- SUBDIRS = doc examples netlink tests libnl-3.2.29/python/tests/0000755000175000017500000000000013031473756012404 500000000000000libnl-3.2.29/python/tests/Makefile.am0000644000175000017500000000007313023014600014334 00000000000000 # -*- Makefile -*- EXTRA_DIST = \ test-create-bridge.py libnl-3.2.29/python/tests/test-create-bridge.py0000644000175000017500000000105113023014600016321 00000000000000import netlink.core as netlink import netlink.route.capi as capi import netlink.route.link as link sock = netlink.lookup_socket(netlink.NETLINK_ROUTE) cache = link.LinkCache() cache.refill(sock) testtap1 = cache['testtap1'] print testtap1 lbr = link.Link() lbr.type = 'bridge' lbr.name = 'testbridge' print lbr lbr.add() cache.refill(sock) lbr = cache['testbridge'] print lbr lbr.enslave(testtap1) cache.refill(sock) testtap1 = cache['testtap1'] print capi.rtnl_link_is_bridge(lbr._rtnl_link) print capi.rtnl_link_get_master(testtap1._rtnl_link) libnl-3.2.29/python/tests/Makefile.in0000644000175000017500000003015213031473644014366 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = python/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ test-create-bridge.py all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign python/tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/python/doc/0000755000175000017500000000000013031473756012007 500000000000000libnl-3.2.29/python/doc/Makefile.am0000644000175000017500000000014413023014600013736 00000000000000# -*- Makefile -*- EXTRA_DIST = \ conf.py \ core.rst \ index.rst \ route_addr.rst \ route.rst libnl-3.2.29/python/doc/conf.py0000644000175000017500000001574513023014600013216 00000000000000# -*- coding: utf-8 -*- # # libnl-python documentation build configuration file, created by # sphinx-quickstart on Mon May 9 10:58:58 2011. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'libnl-python' copyright = u'2011, Thomas Graf ' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '1.0' # The full version, including alpha/beta/rc tags. release = '1.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'libnl-pythondoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'libnl-python.tex', u'libnl-python Documentation', u'Thomas Graf \\textless{}tgraf@suug.ch\\textgreater{}', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'libnl-python', u'libnl-python Documentation', [u'Thomas Graf '], 1) ] libnl-3.2.29/python/doc/route.rst0000644000175000017500000000006613023014600013575 00000000000000********************** Routing ********************** libnl-3.2.29/python/doc/core.rst0000644000175000017500000001241413023014600013367 00000000000000******************* Netlink Core Module ******************* .. py:module:: netlink.core Examples:: import netlink.core as netlink =============== Object =============== .. py:class:: Object Base class for all classes representing a cacheable object Example:: obj = netlink.Object("route/link", "link") .. py:method:: clone Clone the object and return a duplicate (used for COW) .. py:method:: dump([params=None]) Call the libnl internal dump mechanism to dump the object according to the parameters specified. .. py:method:: apply(attr, val) Applies a attribute=value pair and modifies the object accordingly. Example:: obj.apply("mtu", 1200) # Sets attribute mtu to 1200 (link obj) :raises: KeyError if attribute is unknown :raises: ImmutableError if attribute is not mutable .. py:attribute:: mark True if the object is marked, otherwise False. .. py:attribute:: shared True if the object is used by multiple parties, otherwise False. .. py:attribute:: refcnt Number of users sharing a reference to the object :rtype: int .. py:attribute:: attrs List of attributes :rtype: list of strings =============== Cache =============== .. py:class:: Cache Base class for all cache implementations. A cache is a collection of cacheable objects which is typically used by netlink protocols which handle any kind of object, e.g. network links, network addresses, neighbours, ... .. py:method:: subset(filter) Returns a new cache containing the subset which matches the provided filter. :raises: ValueError if no filter is specified :rtype: :py:class:`Cache` .. py:method:: dump([params=None, filter=None]) Calls the libnl internal dump mechanism to dump the cache according to the parameters and filter specified. .. py:method:: clear() Remove and possibly destroy all objects in the cache .. py:method:: refill([socket=None]) -> :py:class:`Cache` Clears and refills the cache with the content which is provided by the kernel, e.g. for a link cache this would mean refilling the cache with all configured network links. .. py:method:: provide() Caches which have been "provided" are made available to other users (of the same application context) which "require" it. F.e. a link cache is generally provided to allow others to translate interface indexes to link names .. py:method:: unprovide() No longer make the cache available to others. If the cache has been handed out already, that reference will still be valid. =============== AbstractAddress =============== .. py:class:: AbstractAddress Abstract representation of an address. This class is not to be mistaken with :py:class:`route.Address` which represents a configured network address. This class represents the actual address in a family independent way:: addr = netlink.AbstractAddress('127.0.0.1/8') print addr # => '127.0.0.1/8' print addr.prefixlen # => '8' print addr.family # => 'inet' print len(addr) # => '4' (32bit ipv4 address) a = netlink.AbstractAddress('10.0.0.1/24') b = netlink.AbstractAddress('10.0.0.2/24') print a == b # => False .. py:attribute:: prefixlen Length of prefix in number of bits. :rtype: int .. py:attribute:: family The family type of the address. Setting the address family can be done with a string or a :py:class:`AddressFamily` object. :rtype: :py:class:`AddressFamily` .. py:attribute:: shared True if address is in use by multiple callers, otherwise False :rtype: bool =============== AddressFamily =============== .. py:class:: AddressFamily Address family representation:: af = netlink.AddressFamily('inet6') # raises: # - ValueError if family name is not known # - TypeError if invalid type is specified for family print af # => 'inet6' (string representation) print int(af) # => 10 (numeric representation) print repr(af) # => AddressFamily('inet6') =============== Exceptions =============== .. py:exception:: NetlinkError Generic exception raised by netlink modules. .. py:exception:: KernelError Raised if an error occured while communicating with the kernel. Contains the error code returning which is automatically included in the error message. .. py:exception:: ImmutableError Raised if an attribute is modified which is marked immutable. =============== Socket =============== .. py:class:: Socket Netlink socket. Note: It is not required to manually create and connect netlink sockets when using caches. The caches will automatically lookup or create a socket as needed. .. py:attribute:: local_port Local port (address) of netlink socket .. py:attribute:: peer_port Peer port (remote address) of netlink socket. If set, all messages will be sent to that peer. .. py:method:: connect(proto) Connect the netlink socket using the specified netlink protocol:: sock.connect(netlink.NETLINK_ROUTE) .. py:method:: disconnect() Disconnect the socket .. py:method:: set_bufsize(rx, tx) Sets the size of the socket buffer libnl-3.2.29/python/doc/index.rst0000644000175000017500000000072713023014600013552 00000000000000.. libnl-python documentation master file, created by sphinx-quickstart on Mon May 9 10:58:58 2011. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to libnl-python's documentation! ======================================== Contents: .. toctree:: :maxdepth: 2 core route route_addr Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` libnl-3.2.29/python/doc/Makefile.in0000644000175000017500000003021613031473644013772 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = python/doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ conf.py \ core.rst \ index.rst \ route_addr.rst \ route.rst all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python/doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign python/doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/python/doc/route_addr.rst0000644000175000017500000000175413023014600014574 00000000000000================= Network Addresses ================= The **Address** module provides access to the network address configuration of the kernel. It provides an interface to fetch all configured addresses, add new addresses and to delete existing addresses. Fetching the list of network addresses is achieved by creating a new address cache:: import netlink.route.address as Address addr_cache = Address.AddressCache() addr_cache.refill() for addr in addr_cache: print addr .. py:module:: netlink.route.addr AddressCache ------------ .. py:class:: AddressCache Represents a cache containing all or a subset of network addresses. .. py:method:: lookup(ifindex, local) Lookup the address which matches ifindex and local address :raises: KeyError if address is not found. Address ------- .. py:class:: Address Representation of a configured network address. .. py:attribute:: ifindex Interface index :rtype: int libnl-3.2.29/python/setup.py.in0000644000175000017500000000266113023014600013262 00000000000000#!/usr/bin/env python from distutils.core import setup, Extension opts = ['-O', '-nodefaultctor'] include = ['@top_builddir@/include', '@top_srcdir@/include'] library_dirs = ['@top_builddir@/lib/.libs'] netlink_capi = Extension('netlink/_capi', sources = ['@srcdir@/netlink/capi.i'], include_dirs = include, swig_opts = opts, library_dirs = library_dirs, libraries = ['nl-3'], ) route_capi = Extension('netlink/route/_capi', sources = ['@srcdir@/netlink/route/capi.i'], include_dirs = include, swig_opts = opts, library_dirs = library_dirs, libraries = ['nl-3', 'nl-route-3'], ) genl_capi = Extension('netlink/genl/_capi', sources = ['@srcdir@/netlink/genl/capi.i'], include_dirs = include, swig_opts = opts, library_dirs = library_dirs, libraries = ['nl-3', 'nl-genl-3'], ) setup(name = 'netlink', version = '1.0', description = 'Python wrapper for netlink protocols', author = 'Thomas Graf', author_email = 'tgraf@suug.ch', url = 'http://www.infradead.org/~tgr/libnl/', license = 'LGPL 2', platforms = 'linux2', long_description = 'Experimental python bindings for libnl', ext_modules = [netlink_capi, route_capi, genl_capi], package_dir = {'': '@srcdir@'}, packages = ['netlink', 'netlink.genl', 'netlink.route', 'netlink.route.links', 'netlink.route.qdisc'], ) libnl-3.2.29/python/README0000644000175000017500000000052113023014600012014 00000000000000 *************************************************************************** NOTE: The python wrapper is experimental and may or may not work. *************************************************************************** For the brave: (requires an installed libnl) - $ python ./setup.py build - $ sudo python ./setup.py install libnl-3.2.29/python/netlink/0000755000175000017500000000000013031473756012706 500000000000000libnl-3.2.29/python/netlink/Makefile.am0000644000175000017500000000017413023014600014640 00000000000000# -*- Makefile -*- SUBDIRS = route genl EXTRA_DIST = \ capi.i \ fixes.h \ __init__.py \ core.py \ util.py \ utils.h libnl-3.2.29/python/netlink/__init__.py0000644000175000017500000000000013023014600014701 00000000000000libnl-3.2.29/python/netlink/util.py0000644000175000017500000000725113023014600014136 00000000000000# # Utilities # # Copyright (c) 2011 Thomas Graf # """utility module for netlink """ from __future__ import absolute_import from . import core as netlink from . import capi as capi from string import Formatter import types __version__ = '1.0' #rename into colored_output def _color(t, c): return '{esc}[{color}m{text}{esc}[0m'.format(esc=b'\x1b'.decode(), color=c, text=t) def black(t): return _color(t, 30) def red(t): return _color(t, 31) def green(t): return _color(t, 32) def yellow(t): return _color(t, 33) def blue(t): return _color(t, 34) def magenta(t): return _color(t, 35) def cyan(t): return _color(t, 36) def white(t): return _color(t, 37) def bold(t): return _color(t, 1) def kw(t): return yellow(t) def num(t): return str(t) def string(t): return t def addr(t): return str(t) def bad(t): return red(t) def good(t): return green(t) def title(t): return t def boolean(t): return str(t) def handle(t): return str(t) class MyFormatter(Formatter): def __init__(self, obj, indent=''): self._obj = obj self._indent = indent def _nlattr(self, key): value = getattr(self._obj.__class__, key) if not isinstance(value, property): raise ValueError('Invalid formatting string {0}'.format(key)) d = getattr(value.fget, 'formatinfo', dict()) # value = value.fget() is exactly the same value = getattr(self._obj, key) if 'fmt' in d: value = d['fmt'](value) title_ = d.get('title', None) return title_, str(value) def get_value(self, key, args, kwds): # Let default get_value() handle ints if not isinstance(key, str): return Formatter.get_value(self, key, args, kwds) # HACK, we allow defining strings via fields to allow # conversions if key[:2] == 's|': return key[2:] if key[:2] == 't|': # title mode ("TITLE ATTR") include_title = True elif key[:2] == 'a|': # plain attribute mode ("ATTR") include_title = False else: # No special field, have default get_value() get it return Formatter.get_value(self, key, args, kwds) key = key[2:] (title_, value) = self._nlattr(key) if include_title: if not title_: title_ = key # fall back to key as title value = '{0} {1}'.format(kw(title_), value) return value def convert_field(self, value, conversion): if conversion == 'r': return repr(value) elif conversion == 's': return str(value) elif conversion == 'k': return kw(value) elif conversion == 'b': return bold(value) elif conversion is None: return value raise ValueError('Unknown converion specifier {0!s}'.format(conversion)) def nl(self, format_string=''): return '\n' + self._indent + self.format(format_string) NL_BYTE_RATE = 0 NL_BIT_RATE = 1 class Rate(object): def __init__(self, rate, mode=NL_BYTE_RATE): self._rate = rate self._mode = mode def __str__(self): return capi.nl_rate2str(self._rate, self._mode, 32)[1] def __int__(self): return self._rate def __cmp__(self, other): return int(self) - int(other) class Size(object): def __init__(self, size): self._size = size def __str__(self): return capi.nl_size2str(self._size, 32)[0] def __int__(self): return self._size def __cmp__(self, other): return int(self) - int(other) libnl-3.2.29/python/netlink/core.py0000644000175000017500000005046213023014600014113 00000000000000# # Netlink interface based on libnl # # Copyright (c) 2011 Thomas Graf # """netlink library based on libnl This module provides an interface to netlink sockets The module contains the following public classes: - Socket -- The netlink socket - Message -- The netlink message - Callback -- The netlink callback handler - Object -- Abstract object (based on struct nl_obect in libnl) used as base class for all object types which can be put into a Cache - Cache -- A collection of objects which are derived from the base class Object. Used for netlink protocols which maintain a list or tree of objects. - DumpParams -- The following exceptions are defined: - NetlinkError -- Base exception for all general purpose exceptions raised. - KernelError -- Raised when the kernel returns an error as response to a request. All other classes or functions in this module are considered implementation details. """ from __future__ import absolute_import from . import capi import sys import socket __all__ = [ 'Socket', 'Message', 'Callback', 'DumpParams', 'Object', 'Cache', 'KernelError', 'NetlinkError', ] __version__ = '0.1' # netlink protocols NETLINK_ROUTE = 0 # NETLINK_UNUSED = 1 NETLINK_USERSOCK = 2 NETLINK_FIREWALL = 3 NETLINK_INET_DIAG = 4 NETLINK_NFLOG = 5 NETLINK_XFRM = 6 NETLINK_SELINUX = 7 NETLINK_ISCSI = 8 NETLINK_AUDIT = 9 NETLINK_FIB_LOOKUP = 10 NETLINK_CONNECTOR = 11 NETLINK_NETFILTER = 12 NETLINK_IP6_FW = 13 NETLINK_DNRTMSG = 14 NETLINK_KOBJECT_UEVENT = 15 NETLINK_GENERIC = 16 NETLINK_SCSITRANSPORT = 18 NETLINK_ECRYPTFS = 19 NL_DONTPAD = 0 NL_AUTO_PORT = 0 NL_AUTO_SEQ = 0 NL_DUMP_LINE = 0 NL_DUMP_DETAILS = 1 NL_DUMP_STATS = 2 NLM_F_REQUEST = 1 NLM_F_MULTI = 2 NLM_F_ACK = 4 NLM_F_ECHO = 8 NLM_F_ROOT = 0x100 NLM_F_MATCH = 0x200 NLM_F_ATOMIC = 0x400 NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH NLM_F_REPLACE = 0x100 NLM_F_EXCL = 0x200 NLM_F_CREATE = 0x400 NLM_F_APPEND = 0x800 class NetlinkError(Exception): def __init__(self, error): self._error = error self._msg = capi.nl_geterror(error) def __str__(self): return self._msg class KernelError(NetlinkError): def __str__(self): return 'Kernel returned: {0}'.format(self._msg) class ImmutableError(NetlinkError): def __init__(self, msg): self._msg = msg def __str__(self): return 'Immutable attribute: {0}'.format(self._msg) class Message(object): """Netlink message""" def __init__(self, size=0): if size == 0: self._msg = capi.nlmsg_alloc() else: self._msg = capi.nlmsg_alloc_size(size) if self._msg is None: raise Exception('Message allocation returned NULL') def __del__(self): capi.nlmsg_free(self._msg) def __len__(self): return capi.nlmsg_len(nlmsg_hdr(self._msg)) @property def protocol(self): return capi.nlmsg_get_proto(self._msg) @protocol.setter def protocol(self, value): capi.nlmsg_set_proto(self._msg, value) @property def maxSize(self): return capi.nlmsg_get_max_size(self._msg) @property def hdr(self): return capi.nlmsg_hdr(self._msg) @property def data(self): return capi.nlmsg_data(self._msg) @property def attrs(self): return capi.nlmsg_attrdata(self._msg) def send(self, sock): sock.send(self) class Callback(object): """Netlink callback""" def __init__(self, kind=capi.NL_CB_DEFAULT): if isinstance(kind, Callback): self._cb = capi.py_nl_cb_clone(kind._cb) else: self._cb = capi.nl_cb_alloc(kind) def __del__(self): capi.py_nl_cb_put(self._cb) def set_type(self, t, k, handler, obj): return capi.py_nl_cb_set(self._cb, t, k, handler, obj) def set_all(self, k, handler, obj): return capi.py_nl_cb_set_all(self._cb, k, handler, obj) def set_err(self, k, handler, obj): return capi.py_nl_cb_err(self._cb, k, handler, obj) def clone(self): return Callback(self) class Socket(object): """Netlink socket""" def __init__(self, cb=None): if isinstance(cb, Callback): self._sock = capi.nl_socket_alloc_cb(cb._cb) elif cb == None: self._sock = capi.nl_socket_alloc() else: raise Exception('\'cb\' parameter has wrong type') if self._sock is None: raise Exception('NULL pointer returned while allocating socket') def __del__(self): capi.nl_socket_free(self._sock) def __str__(self): return 'nlsock<{0}>'.format(self.local_port) @property def local_port(self): return capi.nl_socket_get_local_port(self._sock) @local_port.setter def local_port(self, value): capi.nl_socket_set_local_port(self._sock, int(value)) @property def peer_port(self): return capi.nl_socket_get_peer_port(self._sock) @peer_port.setter def peer_port(self, value): capi.nl_socket_set_peer_port(self._sock, int(value)) @property def peer_groups(self): return capi.nl_socket_get_peer_groups(self._sock) @peer_groups.setter def peer_groups(self, value): capi.nl_socket_set_peer_groups(self._sock, value) def set_bufsize(self, rx, tx): capi.nl_socket_set_buffer_size(self._sock, rx, tx) def connect(self, proto): capi.nl_connect(self._sock, proto) return self def disconnect(self): capi.nl_close(self._sock) def sendto(self, buf): ret = capi.nl_sendto(self._sock, buf, len(buf)) if ret < 0: raise Exception('Failed to send') else: return ret def send_auto_complete(self, msg): if not isinstance(msg, Message): raise Exception('must provide Message instance') ret = capi.nl_send_auto_complete(self._sock, msg._msg) if ret < 0: raise Exception('send_auto_complete failed: ret=%d' % ret) return ret def recvmsgs(self, recv_cb): if not isinstance(recv_cb, Callback): raise Exception('must provide Callback instance') ret = capi.nl_recvmsgs(self._sock, recv_cb._cb) if ret < 0: raise Exception('recvmsg failed: ret=%d' % ret) _sockets = {} def lookup_socket(protocol): try: sock = _sockets[protocol] except KeyError: sock = Socket() sock.connect(protocol) _sockets[protocol] = sock return sock class DumpParams(object): """Dumping parameters""" def __init__(self, type_=NL_DUMP_LINE): self._dp = capi.alloc_dump_params() if not self._dp: raise Exception('Unable to allocate struct nl_dump_params') self._dp.dp_type = type_ def __del__(self): capi.free_dump_params(self._dp) @property def type(self): return self._dp.dp_type @type.setter def type(self, value): self._dp.dp_type = value @property def prefix(self): return self._dp.dp_prefix @prefix.setter def prefix(self, value): self._dp.dp_prefix = value # underscore this to make sure it is deleted first upon module deletion _defaultDumpParams = DumpParams(NL_DUMP_LINE) class Object(object): """Cacheable object (base class)""" def __init__(self, obj_name, name, obj=None): self._obj_name = obj_name self._name = name self._modules = [] if not obj: obj = capi.object_alloc_name(self._obj_name) self._nl_object = obj # Create a clone which stores the original state to notice # modifications clone_obj = capi.nl_object_clone(self._nl_object) self._orig = self._obj2type(clone_obj) def __del__(self): if not self._nl_object: raise ValueError() capi.nl_object_put(self._nl_object) def __str__(self): if hasattr(self, 'format'): return self.format() else: return capi.nl_object_dump_buf(self._nl_object, 4096).rstrip() def _new_instance(self): raise NotImplementedError() def clone(self): """Clone object""" return self._new_instance(capi.nl_object_clone(self._nl_object)) def _module_lookup(self, path, constructor=None): """Lookup object specific module and load it Object implementations consisting of multiple types may offload some type specific code to separate modules which are loadable on demand, e.g. a VLAN link or a specific queueing discipline implementation. Loads the module `path` and calls the constructor if supplied or `module`.init() The constructor/init function typically assigns a new object covering the type specific implementation aspects to the new object, e.g. link.vlan = VLANLink() """ try: __import__(path) except ImportError: return module = sys.modules[path] if constructor: ret = getattr(module, constructor)(self) else: ret = module.init(self) if ret: self._modules.append(ret) def _module_brief(self): ret = '' for module in self._modules: if hasattr(module, 'brief'): ret += module.brief() return ret def dump(self, params=None): """Dump object as human readable text""" if params is None: params = _defaultDumpParams capi.nl_object_dump(self._nl_object, params._dp) @property def mark(self): return bool(capi.nl_object_is_marked(self._nl_object)) @mark.setter def mark(self, value): if value: capi.nl_object_mark(self._nl_object) else: capi.nl_object_unmark(self._nl_object) @property def shared(self): return capi.nl_object_shared(self._nl_object) != 0 @property def attrs(self): attr_list = capi.nl_object_attr_list(self._nl_object, 1024) return attr_list[0].split() @property def refcnt(self): return capi.nl_object_get_refcnt(self._nl_object) # this method resolves multiple levels of sub types to allow # accessing properties of subclass/subtypes (e.g. link.vlan.id) def _resolve(self, attr): obj = self l = attr.split('.') while len(l) > 1: obj = getattr(obj, l.pop(0)) return (obj, l.pop(0)) def _setattr(self, attr, val): obj, attr = self._resolve(attr) return setattr(obj, attr, val) def _hasattr(self, attr): obj, attr = self._resolve(attr) return hasattr(obj, attr) class ObjIterator(object): def __init__(self, cache, obj): self._cache = cache self._nl_object = None if not obj: self._end = 1 else: capi.nl_object_get(obj) self._nl_object = obj self._first = 1 self._end = 0 def __del__(self): if self._nl_object: capi.nl_object_put(self._nl_object) def __iter__(self): return self def get_next(self): return capi.nl_cache_get_next(self._nl_object) def next(self): return self.__next__() def __next__(self): if self._end: raise StopIteration() if self._first: ret = self._nl_object self._first = 0 else: ret = self.get_next() if not ret: self._end = 1 raise StopIteration() # return ref of previous element and acquire ref of current # element to have object stay around until we fetched the # next ptr capi.nl_object_put(self._nl_object) capi.nl_object_get(ret) self._nl_object = ret # reference used inside object capi.nl_object_get(ret) return self._cache._new_object(ret) class ReverseObjIterator(ObjIterator): def get_next(self): return capi.nl_cache_get_prev(self._nl_object) class Cache(object): """Collection of netlink objects""" def __init__(self): if self.__class__ is Cache: raise NotImplementedError() self.arg1 = None self.arg2 = None def __del__(self): capi.nl_cache_free(self._nl_cache) def __len__(self): return capi.nl_cache_nitems(self._nl_cache) def __iter__(self): obj = capi.nl_cache_get_first(self._nl_cache) return ObjIterator(self, obj) def __reversed__(self): obj = capi.nl_cache_get_last(self._nl_cache) return ReverseObjIterator(self, obj) def __contains__(self, item): obj = capi.nl_cache_search(self._nl_cache, item._nl_object) if obj is None: return False else: capi.nl_object_put(obj) return True # called by sub classes to allocate type specific caches by name @staticmethod def _alloc_cache_name(name): return capi.alloc_cache_name(name) # implemented by sub classes, must return new instasnce of cacheable # object @staticmethod def _new_object(obj): raise NotImplementedError() # implemented by sub classes, must return instance of sub class def _new_cache(self, cache): raise NotImplementedError() def subset(self, filter_): """Return new cache containing subset of cache Cretes a new cache containing all objects which match the specified filter. """ if not filter_: raise ValueError() c = capi.nl_cache_subset(self._nl_cache, filter_._nl_object) return self._new_cache(cache=c) def dump(self, params=None, filter_=None): """Dump (print) cache as human readable text""" if not params: params = _defaultDumpParams if filter_: filter_ = filter_._nl_object capi.nl_cache_dump_filter(self._nl_cache, params._dp, filter_) def clear(self): """Remove all cache entries""" capi.nl_cache_clear(self._nl_cache) # Called by sub classes to set first cache argument def _set_arg1(self, arg): self.arg1 = arg capi.nl_cache_set_arg1(self._nl_cache, arg) # Called by sub classes to set second cache argument def _set_arg2(self, arg): self.arg2 = arg capi.nl_cache_set_arg2(self._nl_cache, arg) def refill(self, socket=None): """Clear cache and refill it""" if socket is None: socket = lookup_socket(self._protocol) capi.nl_cache_refill(socket._sock, self._nl_cache) return self def resync(self, socket=None, cb=None, args=None): """Synchronize cache with content in kernel""" if socket is None: socket = lookup_socket(self._protocol) capi.nl_cache_resync(socket._sock, self._nl_cache, cb, args) def provide(self): """Provide this cache to others Caches which have been "provided" are made available to other users (of the same application context) which "require" it. F.e. a link cache is generally provided to allow others to translate interface indexes to link names """ capi.nl_cache_mngt_provide(self._nl_cache) def unprovide(self): """Unprovide this cache No longer make the cache available to others. If the cache has been handed out already, that reference will still be valid. """ capi.nl_cache_mngt_unprovide(self._nl_cache) # Cache Manager (Work in Progress) NL_AUTO_PROVIDE = 1 class CacheManager(object): def __init__(self, protocol, flags=None): self._sock = Socket() self._sock.connect(protocol) if not flags: flags = NL_AUTO_PROVIDE self._mngr = capi.cache_mngr_alloc(self._sock._sock, protocol, flags) def __del__(self): if self._sock: self._sock.disconnect() if self._mngr: capi.nl_cache_mngr_free(self._mngr) def add(self, name): capi.cache_mngr_add(self._mngr, name, None, None) class AddressFamily(object): """Address family representation af = AddressFamily('inet6') # raises: # - ValueError if family name is not known # - TypeError if invalid type is specified for family print af # => 'inet6' (string representation) print int(af) # => 10 (numeric representation) print repr(af) # => AddressFamily('inet6') """ def __init__(self, family=socket.AF_UNSPEC): if isinstance(family, str): family = capi.nl_str2af(family) if family < 0: raise ValueError('Unknown family name') elif not isinstance(family, int): raise TypeError() self._family = family def __str__(self): return capi.nl_af2str(self._family, 32)[0] def __int__(self): return self._family def __repr__(self): return 'AddressFamily({0!r})'.format(str(self)) class AbstractAddress(object): """Abstract address object addr = AbstractAddress('127.0.0.1/8') print addr # => '127.0.0.1/8' print addr.prefixlen # => '8' print addr.family # => 'inet' print len(addr) # => '4' (32bit ipv4 address) a = AbstractAddress('10.0.0.1/24') b = AbstractAddress('10.0.0.2/24') print a == b # => False """ def __init__(self, addr): self._nl_addr = None if isinstance(addr, str): # returns None on success I guess # TO CORRECT addr = capi.addr_parse(addr, socket.AF_UNSPEC) if addr is None: raise ValueError('Invalid address format') elif addr: capi.nl_addr_get(addr) self._nl_addr = addr def __del__(self): if self._nl_addr: capi.nl_addr_put(self._nl_addr) def __cmp__(self, other): if isinstance(other, str): other = AbstractAddress(other) diff = self.prefixlen - other.prefixlen if diff == 0: diff = capi.nl_addr_cmp(self._nl_addr, other._nl_addr) return diff def contains(self, item): diff = int(self.family) - int(item.family) if diff: return False if item.prefixlen < self.prefixlen: return False diff = capi.nl_addr_cmp_prefix(self._nl_addr, item._nl_addr) return diff == 0 def __nonzero__(self): if self._nl_addr: return not capi.nl_addr_iszero(self._nl_addr) else: return False def __len__(self): if self._nl_addr: return capi.nl_addr_get_len(self._nl_addr) else: return 0 def __str__(self): if self._nl_addr: return capi.nl_addr2str(self._nl_addr, 64)[0] else: return 'none' @property def shared(self): """True if address is shared (multiple users)""" if self._nl_addr: return capi.nl_addr_shared(self._nl_addr) != 0 else: return False @property def prefixlen(self): """Length of prefix (number of bits)""" if self._nl_addr: return capi.nl_addr_get_prefixlen(self._nl_addr) else: return 0 @prefixlen.setter def prefixlen(self, value): if not self._nl_addr: raise TypeError() capi.nl_addr_set_prefixlen(self._nl_addr, int(value)) @property def family(self): """Address family""" f = 0 if self._nl_addr: f = capi.nl_addr_get_family(self._nl_addr) return AddressFamily(f) @family.setter def family(self, value): if not self._nl_addr: raise TypeError() if not isinstance(value, AddressFamily): value = AddressFamily(value) capi.nl_addr_set_family(self._nl_addr, int(value)) # keyword: # type = { int | str } # immutable = { True | False } # fmt = func (formatting function) # title = string def nlattr(**kwds): """netlink object attribute decorator decorator used to mark mutable and immutable properties of netlink objects. All properties marked as such are regarded to be accessable. @property @netlink.nlattr(type=int) def my_attr(self): return self._my_attr """ def wrap_fn(func): func.formatinfo = kwds return func return wrap_fn libnl-3.2.29/python/netlink/genl/0000755000175000017500000000000013031473756013633 500000000000000libnl-3.2.29/python/netlink/genl/Makefile.am0000644000175000017500000000007213023014600015562 00000000000000# -*- Makefile -*- EXTRA_DIST = \ capi.i \ __init__.py libnl-3.2.29/python/netlink/genl/__init__.py0000644000175000017500000000000013023014600015626 00000000000000libnl-3.2.29/python/netlink/genl/capi.i0000644000175000017500000000627013023014600014622 00000000000000%module capi %{ #include #include #include #include %} %include %include /* #include */ extern int genl_ctrl_alloc_cache(struct nl_sock *, struct nl_cache **o_cache); extern struct genl_family *genl_ctrl_search(struct nl_cache *, int); extern struct genl_family *genl_ctrl_search_by_name(struct nl_cache *, const char *); extern int genl_ctrl_resolve(struct nl_sock *, const char *); extern int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family, const char *grp); /* #include */ extern struct genl_family *genl_family_alloc(void); extern void genl_family_put(struct genl_family *); extern unsigned int genl_family_get_id(struct genl_family *); extern void genl_family_set_id(struct genl_family *, unsigned int); extern char *genl_family_get_name(struct genl_family *); extern void genl_family_set_name(struct genl_family *, const char *name); extern uint8_t genl_family_get_version(struct genl_family *); extern void genl_family_set_version(struct genl_family *, uint8_t); extern uint32_t genl_family_get_hdrsize(struct genl_family *); extern void genl_family_set_hdrsize(struct genl_family *, uint32_t); extern uint32_t genl_family_get_maxattr(struct genl_family *); extern void genl_family_set_maxattr(struct genl_family *, uint32_t); extern int genl_family_add_op(struct genl_family *, int, int); extern int genl_family_add_grp(struct genl_family *, uint32_t , const char *); /* #include */ struct genlmsghdr { uint8_t cmd; uint8_t version; uint16_t reserved; }; /* #include */ extern int genl_connect(struct nl_sock *); extern struct genlmsghdr *genlmsg_hdr(struct nlmsghdr *); extern void *genlmsg_put(struct nl_msg *, uint32_t, uint32_t, int, int, int, uint8_t, uint8_t); struct nlattr { }; struct nla_policy { /** Type of attribute or NLA_UNSPEC */ uint16_t type; /** Minimal length of payload required */ uint16_t minlen; /** Maximal length of payload allowed */ uint16_t maxlen; }; %inline %{ PyObject *py_genlmsg_parse(struct nlmsghdr *nlh, int uhl, int max, PyObject *p) { struct nlattr *tb_msg[max + 1]; struct nla_policy *policy = NULL; void *pol; PyObject *attrs = Py_None; PyObject *k; PyObject *v; PyObject *resobj; int err; int i; if (p != Py_None) { PyObject *pobj; if (!PyList_Check(p)) { fprintf(stderr, "expected list object\n"); err = -1; goto fail; } pobj = PyList_GetItem(p, 0); err = SWIG_ConvertPtr(pobj, &pol, SWIGTYPE_p_nla_policy, 0 | 0 ); if (!SWIG_IsOK(err)) goto fail; policy = pol; } err = genlmsg_parse(nlh, uhl, tb_msg, max, policy); if (err < 0) { fprintf(stderr, "Failed to parse response message\n"); } else { attrs = PyDict_New(); for (i = 0; i <= max; i++) if (tb_msg[i]) { k = PyInt_FromLong((long)i); v = SWIG_NewPointerObj(SWIG_as_voidptr(tb_msg[i]), SWIGTYPE_p_nlattr, 0 | 0 ); PyDict_SetItem(attrs, k, v); } } fail: if (attrs == Py_None) Py_INCREF(Py_None); resobj = Py_BuildValue("(iO)", err, attrs); return resobj; } %} /* #include */ /* nothing yet */ libnl-3.2.29/python/netlink/genl/Makefile.in0000644000175000017500000003017713031473644015624 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = python/netlink/genl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ capi.i \ __init__.py all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python/netlink/genl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign python/netlink/genl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/python/netlink/utils.h0000644000175000017500000000170113023014600014112 00000000000000struct list_head { struct list_head *next; }; #define LIST_HEAD(name) \ struct list_head name = { &(name) } static inline int list_empty(const struct list_head *head) { return head->next == head; } static inline void list_add(struct list_head *new, struct list_head *head) { new->next = head->next; head->next = new; } static inline void list_del(struct list_head *entry, struct list_head *prev) { prev->next = entry->next; entry->next = entry; } #define list_for_each_safe(pos, n, head) \ for (n = (head), pos = (head)->next; pos != (head); \ n = pos, pos = n->next) #undef offsetof #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #ifdef DEBUG #define pynl_dbg(fmt, ...) \ fprintf(stderr, "%s: " fmt, __func__, __VA_ARGS__) #else #define pynl_dbg(fmt, ...) #endif libnl-3.2.29/python/netlink/capi.i0000644000175000017500000006704613023014600013705 00000000000000%module capi %{ #include #include #include #include #include #include #include #include /* enable define below to get swig api debug messages */ /*#define DEBUG*/ #include "utils.h" %} %include %include %include %include %inline %{ struct nl_dump_params *alloc_dump_params(void) { struct nl_dump_params *dp; if (!(dp = calloc(1, sizeof(*dp)))) return NULL; dp->dp_fd = stdout; return dp; } void free_dump_params(struct nl_dump_params *dp) { free(dp); } %}; /* */ enum nl_dump_type { NL_DUMP_LINE, /**< Dump object briefly on one line */ NL_DUMP_DETAILS, /**< Dump all attributes but no statistics */ NL_DUMP_STATS, /**< Dump all attributes including statistics */ __NL_DUMP_MAX, }; struct nl_dump_params { /** * Specifies the type of dump that is requested. */ enum nl_dump_type dp_type; /** * Specifies the number of whitespaces to be put in front * of every new line (indentation). */ int dp_prefix; /** * Causes the cache index to be printed for each element. */ int dp_print_index; /** * Causes each element to be prefixed with the message type. */ int dp_dump_msgtype; /** * A callback invoked for output * * Passed arguments are: * - dumping parameters * - string to append to the output */ void (*dp_cb)(struct nl_dump_params *, char *); /** * A callback invoked for every new line, can be used to * customize the indentation. * * Passed arguments are: * - dumping parameters * - line number starting from 0 */ void (*dp_nl_cb)(struct nl_dump_params *, int); /** * User data pointer, can be used to pass data to callbacks. */ void *dp_data; /** * File descriptor the dumping output should go to */ FILE * dp_fd; /** * Alternatively the output may be redirected into a buffer */ char * dp_buf; /** * Length of the buffer dp_buf */ size_t dp_buflen; /** * PRIVATE * Set if a dump was performed prior to the actual dump handler. */ int dp_pre_dump; /** * PRIVATE * Owned by the current caller */ int dp_ivar; unsigned int dp_line; }; /* */ extern unsigned int if_nametoindex(const char *ifname); /* */ extern const char *nl_geterror(int); /* */ extern double nl_cancel_down_bytes(unsigned long long, char **); extern double nl_cancel_down_bits(unsigned long long, char **); %cstring_output_maxsize(char *buf, size_t len) extern int nl_rate2str(unsigned long long rate, int type, char *buf, size_t len); extern double nl_cancel_down_us(uint32_t, char **); extern long nl_size2int(const char *); %cstring_output_maxsize(char *buf, const size_t len) extern char *nl_size2str(const size_t, char *buf, const size_t len); extern long nl_prob2int(const char *); extern int nl_get_user_hz(void); extern uint32_t nl_us2ticks(uint32_t); extern uint32_t nl_ticks2us(uint32_t); extern int nl_str2msec(const char *, uint64_t *); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_msec2str(uint64_t, char *buf, size_t len); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_llproto2str(int, char *buf, size_t len); extern int nl_str2llproto(const char *); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_ether_proto2str(int, char *buf, size_t len); extern int nl_str2ether_proto(const char *); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_ip_proto2str(int, char *buf, size_t len); extern int nl_str2ip_proto(const char *); extern void nl_new_line(struct nl_dump_params *); extern void nl_dump(struct nl_dump_params *, const char *, ...); extern void nl_dump_line(struct nl_dump_params *, const char *, ...); /* */ extern struct nl_dump_params *alloc_dump_params(void); extern void free_dump_params(struct nl_dump_params *); extern int nl_connect(struct nl_sock *, int); extern void nl_close(struct nl_sock *); /* */ extern struct nl_sock *nl_socket_alloc(void); extern struct nl_sock *nl_socket_alloc_cb(struct nl_cb *); extern void nl_socket_free(struct nl_sock *); extern uint32_t nl_socket_get_local_port(const struct nl_sock *); extern void nl_socket_set_local_port(struct nl_sock *, uint32_t); extern uint32_t nl_socket_get_peer_port(const struct nl_sock *); extern void nl_socket_set_peer_port(struct nl_sock *, uint32_t); extern uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk); extern void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups); extern int nl_socket_set_buffer_size(struct nl_sock *, int, int); extern void nl_socket_set_cb(struct nl_sock *, struct nl_cb *); extern int nl_socket_add_membership(struct nl_sock *, int); extern int nl_socket_drop_membership(struct nl_sock *, int); extern int nl_send_auto_complete(struct nl_sock *, struct nl_msg *); extern int nl_recvmsgs(struct nl_sock *, struct nl_cb *); /* */ extern int nlmsg_size(int); extern int nlmsg_total_size(int); extern int nlmsg_padlen(int); extern void * nlmsg_data(const struct nlmsghdr *); extern int nlmsg_datalen(const struct nlmsghdr *); extern void * nlmsg_tail(const struct nlmsghdr *); /* attribute access */ extern struct nlattr * nlmsg_attrdata(const struct nlmsghdr *, int); extern int nlmsg_attrlen(const struct nlmsghdr *, int); /* message parsing */ extern int nlmsg_valid_hdr(const struct nlmsghdr *, int); extern int nlmsg_ok(const struct nlmsghdr *, int); extern struct nlmsghdr * nlmsg_next(struct nlmsghdr *, int *); extern int nlmsg_parse(struct nlmsghdr *, int, struct nlattr **, int, struct nla_policy *); extern struct nlattr * nlmsg_find_attr(struct nlmsghdr *, int, int); extern int nlmsg_validate(struct nlmsghdr *, int, int, struct nla_policy *); extern struct nl_msg * nlmsg_alloc(void); extern struct nl_msg * nlmsg_alloc_size(size_t); extern struct nl_msg * nlmsg_alloc_simple(int, int); extern void nlmsg_set_default_size(size_t); extern struct nl_msg * nlmsg_inherit(struct nlmsghdr *); extern struct nl_msg * nlmsg_convert(struct nlmsghdr *); extern void * nlmsg_reserve(struct nl_msg *, size_t, int); extern int nlmsg_append(struct nl_msg *, void *, size_t, int); extern int nlmsg_expand(struct nl_msg *, size_t); extern struct nlmsghdr * nlmsg_put(struct nl_msg *, uint32_t, uint32_t, int, int, int); extern struct nlmsghdr * nlmsg_hdr(struct nl_msg *); extern void nlmsg_get(struct nl_msg *); extern void nlmsg_free(struct nl_msg *); /* attribute modification */ extern void nlmsg_set_proto(struct nl_msg *, int); extern int nlmsg_get_proto(struct nl_msg *); extern size_t nlmsg_get_max_size(struct nl_msg *); extern void nlmsg_set_src(struct nl_msg *, struct sockaddr_nl *); extern struct sockaddr_nl *nlmsg_get_src(struct nl_msg *); extern void nlmsg_set_dst(struct nl_msg *, struct sockaddr_nl *); extern struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *); extern void nlmsg_set_creds(struct nl_msg *, struct ucred *); extern struct ucred * nlmsg_get_creds(struct nl_msg *); extern char * nl_nlmsgtype2str(int, char *, size_t); extern int nl_str2nlmsgtype(const char *); extern char * nl_nlmsg_flags2str(int, char *, size_t); extern int nl_msg_parse(struct nl_msg *, void (*cb)(struct nl_object *, void *), void *); extern void nl_msg_dump(struct nl_msg *, FILE *); %inline %{ struct nl_object *cast_obj(void *obj) { return (struct nl_object *) obj; } struct nl_object *object_alloc_name(const char *name) { struct nl_object *obj; if (nl_object_alloc_name(name, &obj) < 0) return NULL; return obj; } %}; extern struct nl_object *nl_object_alloc(struct nl_object_ops *); extern void nl_object_free(struct nl_object *); extern struct nl_object *nl_object_clone(struct nl_object *); extern void nl_object_get(struct nl_object *); extern void nl_object_put(struct nl_object *); extern int nl_object_shared(struct nl_object *); %cstring_output_maxsize(char *buf, size_t len) extern void nl_object_dump_buf(struct nl_object *, char *buf, size_t len); extern void nl_object_dump(struct nl_object *, struct nl_dump_params *); extern int nl_object_identical(struct nl_object *, struct nl_object *); extern uint32_t nl_object_diff(struct nl_object *, struct nl_object *); extern int nl_object_match_filter(struct nl_object *, struct nl_object *); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_object_attrs2str(struct nl_object *, uint32_t, char *buf, size_t len); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_object_attr_list(struct nl_object *, char *buf, size_t len); extern void nl_object_mark(struct nl_object *); extern void nl_object_unmark(struct nl_object *); extern int nl_object_is_marked(struct nl_object *); extern int nl_object_get_refcnt(struct nl_object *); /* */ typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *); %inline %{ struct nl_cache *alloc_cache_name(const char *name) { struct nl_cache *c; if (nl_cache_alloc_name(name, &c) < 0) return NULL; return c; } struct nl_cache_mngr *alloc_cache_mngr(struct nl_sock *sock, int protocol, int flags) { struct nl_cache_mngr *mngr; if (nl_cache_mngr_alloc(sock, protocol, flags, &mngr) < 0) return NULL; return mngr; } struct nl_cache *cache_mngr_add(struct nl_cache_mngr *mngr, const char *name, change_func_t func, void *arg) { struct nl_cache *cache; if (nl_cache_mngr_add(mngr, name, func, arg, &cache) < 0) return NULL; return cache; } %} /* Access Functions */ extern int nl_cache_nitems(struct nl_cache *); extern int nl_cache_nitems_filter(struct nl_cache *, struct nl_object *); extern struct nl_cache_ops * nl_cache_get_ops(struct nl_cache *); extern struct nl_object * nl_cache_get_first(struct nl_cache *); extern struct nl_object * nl_cache_get_last(struct nl_cache *); extern struct nl_object * nl_cache_get_next(struct nl_object *); extern struct nl_object * nl_cache_get_prev(struct nl_object *); extern struct nl_cache * nl_cache_alloc(struct nl_cache_ops *); extern struct nl_cache * nl_cache_subset(struct nl_cache *, struct nl_object *); extern void nl_cache_clear(struct nl_cache *); extern void nl_cache_free(struct nl_cache *); /* Cache modification */ extern int nl_cache_add(struct nl_cache *, struct nl_object *); extern int nl_cache_parse_and_add(struct nl_cache *, struct nl_msg *); extern void nl_cache_remove(struct nl_object *); extern int nl_cache_refill(struct nl_sock *, struct nl_cache *); extern int nl_cache_pickup(struct nl_sock *, struct nl_cache *); extern int nl_cache_resync(struct nl_sock *, struct nl_cache *, change_func_t, void *); extern int nl_cache_include(struct nl_cache *, struct nl_object *, change_func_t, void *); extern void nl_cache_set_arg1(struct nl_cache *, int); extern void nl_cache_set_arg2(struct nl_cache *, int); /* General */ extern int nl_cache_is_empty(struct nl_cache *); extern struct nl_object * nl_cache_search(struct nl_cache *, struct nl_object *); extern void nl_cache_mark_all(struct nl_cache *); /* Dumping */ extern void nl_cache_dump(struct nl_cache *, struct nl_dump_params *); extern void nl_cache_dump_filter(struct nl_cache *, struct nl_dump_params *, struct nl_object *); /* Iterators */ extern void nl_cache_foreach(struct nl_cache *, void (*cb)(struct nl_object *, void *), void *arg); extern void nl_cache_foreach_filter(struct nl_cache *, struct nl_object *, void (*cb)(struct nl_object *, void *), void *arg); /* --- cache management --- */ /* Cache type management */ extern struct nl_cache_ops * nl_cache_ops_lookup(const char *); extern struct nl_cache_ops * nl_cache_ops_associate(int, int); extern struct nl_msgtype * nl_msgtype_lookup(struct nl_cache_ops *, int); extern void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *); extern int nl_cache_mngt_register(struct nl_cache_ops *); extern int nl_cache_mngt_unregister(struct nl_cache_ops *); /* Global cache provisioning/requiring */ extern void nl_cache_mngt_provide(struct nl_cache *); extern void nl_cache_mngt_unprovide(struct nl_cache *); extern struct nl_cache * nl_cache_mngt_require(const char *); struct nl_cache_mngr; #define NL_AUTO_PROVIDE 1 extern int nl_cache_mngr_get_fd(struct nl_cache_mngr *); extern int nl_cache_mngr_poll(struct nl_cache_mngr *, int); extern int nl_cache_mngr_data_ready(struct nl_cache_mngr *); extern void nl_cache_mngr_free(struct nl_cache_mngr *); /* */ %inline %{ struct nl_addr *addr_parse(const char *addr, int guess) { struct nl_addr *result; if (nl_addr_parse(addr, guess, &result) < 0) return NULL; return result; } %}; extern struct nl_addr *nl_addr_alloc(size_t); extern struct nl_addr *nl_addr_alloc_attr(struct nlattr *, int); extern struct nl_addr *nl_addr_build(int, void *, size_t); extern struct nl_addr *nl_addr_clone(struct nl_addr *); extern struct nl_addr *nl_addr_get(struct nl_addr *); extern void nl_addr_put(struct nl_addr *); extern int nl_addr_shared(struct nl_addr *); extern int nl_addr_cmp(struct nl_addr *, struct nl_addr *); extern int nl_addr_cmp_prefix(struct nl_addr *, struct nl_addr *); extern int nl_addr_iszero(struct nl_addr *); extern int nl_addr_valid(char *, int); extern int nl_addr_guess_family(struct nl_addr *); extern int nl_addr_fill_sockaddr(struct nl_addr *, struct sockaddr *, socklen_t *); extern int nl_addr_info(struct nl_addr *, struct addrinfo **); extern int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen); extern void nl_addr_set_family(struct nl_addr *, int); extern int nl_addr_get_family(struct nl_addr *); extern int nl_addr_set_binary_addr(struct nl_addr *, void *, size_t); extern void *nl_addr_get_binary_addr(struct nl_addr *); extern unsigned int nl_addr_get_len(struct nl_addr *); extern void nl_addr_set_prefixlen(struct nl_addr *, int); extern unsigned int nl_addr_get_prefixlen(struct nl_addr *); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_af2str(int, char *buf, size_t len); extern int nl_str2af(const char *); %cstring_output_maxsize(char *buf, size_t len) extern char *nl_addr2str(struct nl_addr *, char *buf, size_t len); /* Message Handlers */ /** * Callback actions * @ingroup cb */ enum nl_cb_action { /** Proceed with wathever would come next */ NL_OK, /** Skip this message */ NL_SKIP, /** Stop parsing altogether and discard remaining messages */ NL_STOP, }; /** * Callback kinds * @ingroup cb */ enum nl_cb_kind { /** Default handlers (quiet) */ NL_CB_DEFAULT, /** Verbose default handlers (error messages printed) */ NL_CB_VERBOSE, /** Debug handlers for debugging */ NL_CB_DEBUG, /** Customized handler specified by the user */ NL_CB_CUSTOM, __NL_CB_KIND_MAX, }; #define NL_CB_KIND_MAX (__NL_CB_KIND_MAX - 1) /** * Callback types * @ingroup cb */ enum nl_cb_type { /** Message is valid */ NL_CB_VALID, /** Last message in a series of multi part messages received */ NL_CB_FINISH, /** Report received that data was lost */ NL_CB_OVERRUN, /** Message wants to be skipped */ NL_CB_SKIPPED, /** Message is an acknowledge */ NL_CB_ACK, /** Called for every message received */ NL_CB_MSG_IN, /** Called for every message sent out except for nl_sendto() */ NL_CB_MSG_OUT, /** Message is malformed and invalid */ NL_CB_INVALID, /** Called instead of internal sequence number checking */ NL_CB_SEQ_CHECK, /** Sending of an acknowledge message has been requested */ NL_CB_SEND_ACK, /** Flag NLM_F_DUMP_INTR is set in message */ NL_CB_DUMP_INTR, __NL_CB_TYPE_MAX, }; #define NL_CB_TYPE_MAX (__NL_CB_TYPE_MAX - 1) extern struct nl_cb *nl_cb_alloc(enum nl_cb_kind); extern struct nl_cb *nl_cb_clone(struct nl_cb *); struct nlmsgerr { int error; }; %{ struct pynl_callback { PyObject *cbf; PyObject *cba; }; struct pynl_cbinfo { struct nl_cb *cb; struct pynl_callback cbtype[NL_CB_TYPE_MAX+1]; struct pynl_callback cberr; struct list_head list; }; LIST_HEAD(callback_list); static struct pynl_cbinfo *pynl_find_cbinfo(struct nl_cb *cb, int unlink) { struct list_head *pos, *prev; struct pynl_cbinfo *info; list_for_each_safe(pos, prev, &callback_list) { info = container_of(pos, struct pynl_cbinfo, list); if (info->cb == cb) { if (unlink) list_del(pos, prev); pynl_dbg("cb=%p: found=%p\n", cb, info); return info; } } pynl_dbg("cb=%p: not found\n", cb); return NULL; } static struct pynl_cbinfo *pynl_get_cbinfo(struct nl_cb *cb, int unlink) { struct pynl_cbinfo *info; info = pynl_find_cbinfo(cb, unlink); if (info || unlink) { /* found or no need to allocate a new one */ pynl_dbg("cb=%p: done\n", cb); return info; } info = calloc(1, sizeof(*info)); info->cb = cb; list_add(&info->list, &callback_list); pynl_dbg("cb=%p: added %p\n", cb, info); return info; } static int nl_recv_msg_handler(struct nl_msg *msg, void *arg) { struct pynl_callback *cbd = arg; PyObject *msgobj; PyObject *cbparobj; PyObject *resobj; PyObject *funcobj; int result; if (!cbd) { result = NL_STOP; goto done; } msgobj = SWIG_NewPointerObj(SWIG_as_voidptr(msg), SWIGTYPE_p_nl_msg, 0 | 0 ); /* add selfobj if callback is a method */ if (cbd->cbf && PyMethod_Check(cbd->cbf)) { PyObject *selfobj = PyMethod_Self(cbd->cbf); cbparobj = Py_BuildValue("(OOO)", selfobj ? selfobj : cbd->cba, msgobj, cbd->cba); funcobj = PyMethod_Function(cbd->cbf); pynl_dbg("callback %sbounded instance method %p\n", selfobj ? "" : "un", funcobj); } else { cbparobj = Py_BuildValue("(OO)", msgobj, cbd->cba); funcobj = cbd->cbf; pynl_dbg("callback function %p\n", funcobj); } resobj = PyObject_CallObject(funcobj, cbparobj); Py_DECREF(cbparobj); if (resobj && PyInt_Check(resobj)) result = (int)PyInt_AsLong(resobj); else result = NL_STOP; Py_XDECREF(resobj); done: pynl_dbg("result=%d\n", result); return result; } static int nl_recv_err_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) { struct pynl_callback *cbd = arg; PyObject *errobj; PyObject *cbparobj; PyObject *resobj; PyObject *funcobj; int result; if (!cbd) return NL_STOP; errobj = SWIG_NewPointerObj(SWIG_as_voidptr(err), SWIGTYPE_p_nlmsgerr, 0 | 0 ); /* add selfobj if callback is a method */ if (cbd->cbf && PyMethod_Check(cbd->cbf)) { PyObject *selfobj = PyMethod_Self(cbd->cbf); cbparobj = Py_BuildValue("(OOO)", selfobj ? selfobj : cbd->cba, errobj, cbd->cba); funcobj = PyMethod_Function(cbd->cbf); } else { cbparobj = Py_BuildValue("(OO)", errobj, cbd->cba); funcobj = cbd->cbf; } resobj = PyObject_CallObject(funcobj, cbparobj); Py_DECREF(cbparobj); if (resobj && PyInt_Check(resobj)) result = (int)PyInt_AsLong(resobj); else result = NL_STOP; Py_XDECREF(resobj); pynl_dbg("error: err=%d ret=%d\n", err->error, result); return result; } %} %inline %{ struct nl_cb *py_nl_cb_clone(struct nl_cb *cb) { struct pynl_cbinfo *info, *clone_info; struct nl_cb *clone; int i; clone = nl_cb_clone(cb); info = pynl_find_cbinfo(cb, 0); if (info) { clone_info = pynl_get_cbinfo(clone, 0); /* increase refcnt to callback parameters and copy them */ for (i = 0; info && i <= NL_CB_TYPE_MAX; i++) { Py_XINCREF(info->cbtype[i].cbf); Py_XINCREF(info->cbtype[i].cba); clone_info->cbtype[i].cbf = info->cbtype[i].cbf; clone_info->cbtype[i].cba = info->cbtype[i].cba; } Py_XINCREF(info->cberr.cbf); Py_XINCREF(info->cberr.cba); clone_info->cberr.cbf = info->cberr.cbf; clone_info->cberr.cba = info->cberr.cba; } return clone; } void py_nl_cb_put(struct nl_cb *cb) { struct pynl_cbinfo *info; int i; /* obtain callback info (and unlink) */ info = pynl_get_cbinfo(cb, 1); pynl_dbg("cb=%p, info=%p\n", cb, info); /* decrease refcnt for callback type handlers */ for (i = 0; info && i <= NL_CB_TYPE_MAX; i++) { Py_XDECREF(info->cbtype[i].cbf); Py_XDECREF(info->cbtype[i].cba); } /* decrease refcnt for error handler and free callback info */ if (info) { Py_XDECREF(info->cberr.cbf); Py_XDECREF(info->cberr.cba); free(info); } nl_cb_put(cb); } int py_nl_cb_set(struct nl_cb *cb, enum nl_cb_type t, enum nl_cb_kind k, PyObject *func, PyObject *a) { struct pynl_cbinfo *info; /* obtain callback info */ info = pynl_get_cbinfo(cb, 0); /* clear existing handlers (if any) */ Py_XDECREF(info->cbtype[t].cbf); Py_XDECREF(info->cbtype[t].cba); info->cbtype[t].cbf = NULL; info->cbtype[t].cba = NULL; pynl_dbg("cb=%p, info=%p, type=%d, kind=%d\n", cb, info, t, k); /* handle custom callback */ if (k == NL_CB_CUSTOM) { Py_XINCREF(func); Py_XINCREF(a); info->cbtype[t].cbf = func; info->cbtype[t].cba = a; return nl_cb_set(cb, t, k, nl_recv_msg_handler, &info->cbtype[t]); } return nl_cb_set(cb, t, k, NULL, NULL); } int py_nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind k, PyObject *func , PyObject *a) { struct pynl_cbinfo *info; int t; info = pynl_get_cbinfo(cb, 0); pynl_dbg("cb=%p, info=%p, kind=%d\n", cb, info, k); for (t = 0; t <= NL_CB_TYPE_MAX; t++) { /* (possibly) free existing handler */ Py_XDECREF(info->cbtype[t].cbf); Py_XDECREF(info->cbtype[t].cba); info->cbtype[t].cbf = NULL; info->cbtype[t].cba = NULL; if (k == NL_CB_CUSTOM) { Py_XINCREF(func); Py_XINCREF(a); info->cbtype[t].cbf = func; info->cbtype[t].cba = a; } } if (k == NL_CB_CUSTOM) /* callback argument is same for all so using idx 0 here */ return nl_cb_set_all(cb, k, nl_recv_msg_handler, &info->cbtype[0]); else return nl_cb_set_all(cb, k, NULL, NULL); } int py_nl_cb_err(struct nl_cb *cb, enum nl_cb_kind k, PyObject *func, PyObject *a) { struct pynl_cbinfo *info; /* obtain callback info */ info = pynl_get_cbinfo(cb, 0); pynl_dbg("cb=%p, info=%p, kind=%d\n", cb, info, k); /* clear existing handlers (if any) */ Py_XDECREF(info->cberr.cbf); Py_XDECREF(info->cberr.cba); info->cberr.cbf = NULL; info->cberr.cba = NULL; /* handle custom callback */ if (k == NL_CB_CUSTOM) { Py_XINCREF(func); Py_XINCREF(a); info->cberr.cbf = func; info->cberr.cba = a; return nl_cb_err(cb, k, nl_recv_err_handler, &info->cberr); } return nl_cb_err(cb, k, NULL, NULL); } %} /* Attributes */ /* * This typemap is a bit tricky as it uses arg1, which is knowledge about * the SWIGged wrapper output. */ %typemap(out) void * { $result = PyByteArray_FromStringAndSize($1, nla_len(arg1)); } extern void *nla_data(struct nlattr *); %typemap(out) void *; extern int nla_type(const struct nlattr *); %typemap(in) (int, const void *) { $1 = Py_SIZE($input); if (PyByteArray_Check($input)) { $2 = ($2_ltype)PyByteArray_AsString($input); } else if (PyString_Check($input)) { $2 = ($2_ltype)PyString_AsString($input); } else SWIG_exception(SWIG_TypeError, "pointer must be bytearray or string."); } extern int nla_put(struct nl_msg *, int, int, const void *); %typemap(in) const void *; /* Integer attribute */ extern uint8_t nla_get_u8(struct nlattr *); extern int nla_put_u8(struct nl_msg *, int, uint8_t); extern uint16_t nla_get_u16(struct nlattr *); extern int nla_put_u16(struct nl_msg *, int, uint16_t); extern uint32_t nla_get_u32(struct nlattr *); extern int nla_put_u32(struct nl_msg *, int, uint32_t); extern uint64_t nla_get_u64(struct nlattr *); extern int nla_put_u64(struct nl_msg *, int, uint64_t); /* String attribute */ extern char * nla_get_string(struct nlattr *); extern char * nla_strdup(struct nlattr *); extern int nla_put_string(struct nl_msg *, int, const char *); /* Flag attribute */ extern int nla_get_flag(struct nlattr *); extern int nla_put_flag(struct nl_msg *, int); /* Msec attribute */ extern unsigned long nla_get_msecs(struct nlattr *); extern int nla_put_msecs(struct nl_msg *, int, unsigned long); /* Attribute nesting */ extern int nla_put_nested(struct nl_msg *, int, struct nl_msg *); extern struct nlattr * nla_nest_start(struct nl_msg *, int); extern int nla_nest_end(struct nl_msg *, struct nlattr *); %inline %{ PyObject *py_nla_parse_nested(int max, struct nlattr *nest_attr, PyObject *p) { struct nlattr *tb_msg[max + 1]; struct nla_policy *policy = NULL; void *pol; PyObject *attrs = Py_None; PyObject *k; PyObject *v; PyObject *resobj; int err; int i; if (p != Py_None) { PyObject *pobj; if (!PyList_Check(p)) { fprintf(stderr, "expected list object\n"); err = -1; goto fail; } pobj = PyList_GetItem(p, 0); err = SWIG_ConvertPtr(pobj, &pol, SWIGTYPE_p_nla_policy, 0 | 0 ); if (!SWIG_IsOK(err)) goto fail; policy = pol; } err = nla_parse_nested(tb_msg, max, nest_attr, policy); if (err < 0) { fprintf(stderr, "Failed to parse response message\n"); } else { attrs = PyDict_New(); for (i = 0; i <= max; i++) if (tb_msg[i]) { k = PyInt_FromLong((long)i); v = SWIG_NewPointerObj(SWIG_as_voidptr(tb_msg[i]), SWIGTYPE_p_nlattr, 0 | 0 ); PyDict_SetItem(attrs, k, v); } } fail: if (attrs == Py_None) Py_INCREF(attrs); resobj = Py_BuildValue("(iO)", err, attrs); return resobj; } /* * nla_get_nested() - get list of nested attributes. * * nla_for_each_() is a macro construct that needs another approach * for Python. Create and return list of nested attributes. */ PyObject *nla_get_nested(struct nlattr *nest_attr) { PyObject *listobj; PyObject *nestattrobj; struct nlattr *pos; int rem; listobj = PyList_New(0); nla_for_each_nested(pos, nest_attr, rem) { nestattrobj = SWIG_NewPointerObj(SWIG_as_voidptr(pos), SWIGTYPE_p_nlattr, 0 | 0 ); PyList_Append(listobj, nestattrobj); } return listobj; } %} /** * @ingroup attr * Basic attribute data types * * See \ref attr_datatypes for more details. */ enum { NLA_UNSPEC, /**< Unspecified type, binary data chunk */ NLA_U8, /**< 8 bit integer */ NLA_U16, /**< 16 bit integer */ NLA_U32, /**< 32 bit integer */ NLA_U64, /**< 64 bit integer */ NLA_STRING, /**< NUL terminated character string */ NLA_FLAG, /**< Flag */ NLA_MSECS, /**< Micro seconds (64bit) */ NLA_NESTED, /**< Nested attributes */ __NLA_TYPE_MAX, }; #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) /** @} */ /** * @ingroup attr * Attribute validation policy. * * See \ref attr_datatypes for more details. */ struct nla_policy { /** Type of attribute or NLA_UNSPEC */ uint16_t type; /** Minimal length of payload required */ uint16_t minlen; /** Maximal length of payload allowed */ uint16_t maxlen; }; %inline %{ PyObject *nla_policy_array(int n_items) { struct nla_policy *policies; PyObject *listobj; PyObject *polobj; int i; policies = calloc(n_items, sizeof(*policies)); listobj = PyList_New(n_items); for (i = 0; i < n_items; i++) { polobj = SWIG_NewPointerObj(SWIG_as_voidptr(&policies[i]), SWIGTYPE_p_nla_policy, 0 | 0 ); PyList_SetItem(listobj, i, polobj); } return listobj; } %} libnl-3.2.29/python/netlink/fixes.h0000644000175000017500000000002413023014600014065 00000000000000#include libnl-3.2.29/python/netlink/Makefile.in0000644000175000017500000004463613031473644014704 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = python/netlink ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = route genl EXTRA_DIST = \ capi.i \ fixes.h \ __init__.py \ core.py \ util.py \ utils.h all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python/netlink/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign python/netlink/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/python/netlink/route/0000755000175000017500000000000013031473756014044 500000000000000libnl-3.2.29/python/netlink/route/Makefile.am0000644000175000017500000000031213023014600015770 00000000000000# -*- Makefile -*- EXTRA_DIST = \ capi.i \ __init__.py \ address.py \ link.py \ tc.py \ links/__init__.py \ links/dummy.py \ links/inet.py \ links/vlan.py \ qdisc/__init__.py \ qdisc/htb.py libnl-3.2.29/python/netlink/route/__init__.py0000644000175000017500000000000013023014600016037 00000000000000libnl-3.2.29/python/netlink/route/link.py0000644000175000017500000004154413023014600015257 00000000000000# # Copyright (c) 2011 Thomas Graf # """Module providing access to network links This module provides an interface to view configured network links, modify them and to add and delete virtual network links. The following is a basic example: import netlink.core as netlink import netlink.route.link as link sock = netlink.Socket() sock.connect(netlink.NETLINK_ROUTE) cache = link.LinkCache() # create new empty link cache cache.refill(sock) # fill cache with all configured links eth0 = cache['eth0'] # lookup link "eth0" print eth0 # print basic configuration The module contains the following public classes: - Link -- Represents a network link. Instances can be created directly via the constructor (empty link objects) or via the refill() method of a LinkCache. - LinkCache -- Derived from netlink.Cache, holds any number of network links (Link instances). Main purpose is to keep a local list of all network links configured in the kernel. The following public functions exist: - get_from_kernel(socket, name) """ from __future__ import absolute_import __version__ = '0.1' __all__ = [ 'LinkCache', 'Link', 'get_from_kernel', ] import socket from .. import core as netlink from .. import capi as core_capi from . import capi as capi from .links import inet as inet from .. import util as util # Link statistics definitions RX_PACKETS = 0 TX_PACKETS = 1 RX_BYTES = 2 TX_BYTES = 3 RX_ERRORS = 4 TX_ERRORS = 5 RX_DROPPED = 6 TX_DROPPED = 7 RX_COMPRESSED = 8 TX_COMPRESSED = 9 RX_FIFO_ERR = 10 TX_FIFO_ERR = 11 RX_LEN_ERR = 12 RX_OVER_ERR = 13 RX_CRC_ERR = 14 RX_FRAME_ERR = 15 RX_MISSED_ERR = 16 TX_ABORT_ERR = 17 TX_CARRIER_ERR = 18 TX_HBEAT_ERR = 19 TX_WIN_ERR = 20 COLLISIONS = 21 MULTICAST = 22 IP6_INPKTS = 23 IP6_INHDRERRORS = 24 IP6_INTOOBIGERRORS = 25 IP6_INNOROUTES = 26 IP6_INADDRERRORS = 27 IP6_INUNKNOWNPROTOS = 28 IP6_INTRUNCATEDPKTS = 29 IP6_INDISCARDS = 30 IP6_INDELIVERS = 31 IP6_OUTFORWDATAGRAMS = 32 IP6_OUTPKTS = 33 IP6_OUTDISCARDS = 34 IP6_OUTNOROUTES = 35 IP6_REASMTIMEOUT = 36 IP6_REASMREQDS = 37 IP6_REASMOKS = 38 IP6_REASMFAILS = 39 IP6_FRAGOKS = 40 IP6_FRAGFAILS = 41 IP6_FRAGCREATES = 42 IP6_INMCASTPKTS = 43 IP6_OUTMCASTPKTS = 44 IP6_INBCASTPKTS = 45 IP6_OUTBCASTPKTS = 46 IP6_INOCTETS = 47 IP6_OUTOCTETS = 48 IP6_INMCASTOCTETS = 49 IP6_OUTMCASTOCTETS = 50 IP6_INBCASTOCTETS = 51 IP6_OUTBCASTOCTETS = 52 ICMP6_INMSGS = 53 ICMP6_INERRORS = 54 ICMP6_OUTMSGS = 55 ICMP6_OUTERRORS = 56 class LinkCache(netlink.Cache): """Cache of network links""" def __init__(self, family=socket.AF_UNSPEC, cache=None): if not cache: cache = self._alloc_cache_name('route/link') self._info_module = None self._protocol = netlink.NETLINK_ROUTE self._nl_cache = cache self._set_arg1(family) def __getitem__(self, key): if type(key) is int: link = capi.rtnl_link_get(self._nl_cache, key) else: link = capi.rtnl_link_get_by_name(self._nl_cache, key) if link is None: raise KeyError() else: return Link.from_capi(link) @staticmethod def _new_object(obj): return Link(obj) def _new_cache(self, cache): return LinkCache(family=self.arg1, cache=cache) class Link(netlink.Object): """Network link""" def __init__(self, obj=None): netlink.Object.__init__(self, 'route/link', 'link', obj) self._rtnl_link = self._obj2type(self._nl_object) if self.type: self._module_lookup('netlink.route.links.' + self.type) self.inet = inet.InetLink(self) self.af = {'inet' : self.inet } def __enter__(self): return self def __exit__(self, exc_type, exc_value, tb): if exc_type is None: self.change() else: return false @classmethod def from_capi(cls, obj): return cls(capi.link2obj(obj)) @staticmethod def _obj2type(obj): return capi.obj2link(obj) def __cmp__(self, other): return self.ifindex - other.ifindex @staticmethod def _new_instance(obj): if not obj: raise ValueError() return Link(obj) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def ifindex(self): """interface index""" return capi.rtnl_link_get_ifindex(self._rtnl_link) @ifindex.setter def ifindex(self, value): capi.rtnl_link_set_ifindex(self._rtnl_link, int(value)) # ifindex is immutable but we assume that if _orig does not # have an ifindex specified, it was meant to be given here if capi.rtnl_link_get_ifindex(self._orig) == 0: capi.rtnl_link_set_ifindex(self._orig, int(value)) @property @netlink.nlattr(type=str, fmt=util.bold) def name(self): """Name of link""" return capi.rtnl_link_get_name(self._rtnl_link) @name.setter def name(self, value): capi.rtnl_link_set_name(self._rtnl_link, value) # name is the secondary identifier, if _orig does not have # the name specified yet, assume it was meant to be specified # here. ifindex will always take priority, therefore if ifindex # is specified as well, this will be ignored automatically. if capi.rtnl_link_get_name(self._orig) is None: capi.rtnl_link_set_name(self._orig, value) @property @netlink.nlattr(type=str, fmt=util.string) def flags(self): """Flags Setting this property will *Not* reset flags to value you supply in Examples: link.flags = '+xxx' # add xxx flag link.flags = 'xxx' # exactly the same link.flags = '-xxx' # remove xxx flag link.flags = [ '+xxx', '-yyy' ] # list operation """ flags = capi.rtnl_link_get_flags(self._rtnl_link) return capi.rtnl_link_flags2str(flags, 256)[0].split(',') def _set_flag(self, flag): if flag.startswith('-'): i = capi.rtnl_link_str2flags(flag[1:]) capi.rtnl_link_unset_flags(self._rtnl_link, i) elif flag.startswith('+'): i = capi.rtnl_link_str2flags(flag[1:]) capi.rtnl_link_set_flags(self._rtnl_link, i) else: i = capi.rtnl_link_str2flags(flag) capi.rtnl_link_set_flags(self._rtnl_link, i) @flags.setter def flags(self, value): if not (type(value) is str): for flag in value: self._set_flag(flag) else: self._set_flag(value) @property @netlink.nlattr(type=int, fmt=util.num) def mtu(self): """Maximum Transmission Unit""" return capi.rtnl_link_get_mtu(self._rtnl_link) @mtu.setter def mtu(self, value): capi.rtnl_link_set_mtu(self._rtnl_link, int(value)) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def family(self): """Address family""" return capi.rtnl_link_get_family(self._rtnl_link) @family.setter def family(self, value): capi.rtnl_link_set_family(self._rtnl_link, value) @property @netlink.nlattr(type=str, fmt=util.addr) def address(self): """Hardware address (MAC address)""" a = capi.rtnl_link_get_addr(self._rtnl_link) return netlink.AbstractAddress(a) @address.setter def address(self, value): capi.rtnl_link_set_addr(self._rtnl_link, value._addr) @property @netlink.nlattr(type=str, fmt=util.addr) def broadcast(self): """Hardware broadcast address""" a = capi.rtnl_link_get_broadcast(self._rtnl_link) return netlink.AbstractAddress(a) @broadcast.setter def broadcast(self, value): capi.rtnl_link_set_broadcast(self._rtnl_link, value._addr) @property @netlink.nlattr(type=str, immutable=True, fmt=util.string) def qdisc(self): """Name of qdisc (cannot be changed)""" return capi.rtnl_link_get_qdisc(self._rtnl_link) @qdisc.setter def qdisc(self, value): capi.rtnl_link_set_qdisc(self._rtnl_link, value) @property @netlink.nlattr(type=int, fmt=util.num) def txqlen(self): """Length of transmit queue""" return capi.rtnl_link_get_txqlen(self._rtnl_link) @txqlen.setter def txqlen(self, value): capi.rtnl_link_set_txqlen(self._rtnl_link, int(value)) @property @netlink.nlattr(type=str, immutable=True, fmt=util.string) def arptype(self): """Type of link (cannot be changed)""" type_ = capi.rtnl_link_get_arptype(self._rtnl_link) return core_capi.nl_llproto2str(type_, 64)[0] @arptype.setter def arptype(self, value): i = core_capi.nl_str2llproto(value) capi.rtnl_link_set_arptype(self._rtnl_link, i) @property @netlink.nlattr(type=str, immutable=True, fmt=util.string, title='state') def operstate(self): """Operational status""" operstate = capi.rtnl_link_get_operstate(self._rtnl_link) return capi.rtnl_link_operstate2str(operstate, 32)[0] @operstate.setter def operstate(self, value): i = capi.rtnl_link_str2operstate(value) capi.rtnl_link_set_operstate(self._rtnl_link, i) @property @netlink.nlattr(type=str, immutable=True, fmt=util.string) def mode(self): """Link mode""" mode = capi.rtnl_link_get_linkmode(self._rtnl_link) return capi.rtnl_link_mode2str(mode, 32)[0] @mode.setter def mode(self, value): i = capi.rtnl_link_str2mode(value) capi.rtnl_link_set_linkmode(self._rtnl_link, i) @property @netlink.nlattr(type=str, fmt=util.string) def alias(self): """Interface alias (SNMP)""" return capi.rtnl_link_get_ifalias(self._rtnl_link) @alias.setter def alias(self, value): capi.rtnl_link_set_ifalias(self._rtnl_link, value) @property @netlink.nlattr(type=str, fmt=util.string) def type(self): """Link type""" return capi.rtnl_link_get_type(self._rtnl_link) @type.setter def type(self, value): if capi.rtnl_link_set_type(self._rtnl_link, value) < 0: raise NameError('unknown info type') self._module_lookup('netlink.route.links.' + value) def get_stat(self, stat): """Retrieve statistical information""" if type(stat) is str: stat = capi.rtnl_link_str2stat(stat) if stat < 0: raise NameError('unknown name of statistic') return capi.rtnl_link_get_stat(self._rtnl_link, stat) def enslave(self, slave, sock=None): if not sock: sock = netlink.lookup_socket(netlink.NETLINK_ROUTE) return capi.rtnl_link_enslave(sock._sock, self._rtnl_link, slave._rtnl_link) def release(self, slave, sock=None): if not sock: sock = netlink.lookup_socket(netlink.NETLINK_ROUTE) return capi.rtnl_link_release(sock._sock, self._rtnl_link, slave._rtnl_link) def add(self, sock=None, flags=None): if not sock: sock = netlink.lookup_socket(netlink.NETLINK_ROUTE) if not flags: flags = netlink.NLM_F_CREATE ret = capi.rtnl_link_add(sock._sock, self._rtnl_link, flags) if ret < 0: raise netlink.KernelError(ret) def change(self, sock=None, flags=0): """Commit changes made to the link object""" if sock is None: sock = netlink.lookup_socket(netlink.NETLINK_ROUTE) if not self._orig: raise netlink.NetlinkError('Original link not available') ret = capi.rtnl_link_change(sock._sock, self._orig, self._rtnl_link, flags) if ret < 0: raise netlink.KernelError(ret) def delete(self, sock=None): """Attempt to delete this link in the kernel""" if sock is None: sock = netlink.lookup_socket(netlink.NETLINK_ROUTE) ret = capi.rtnl_link_delete(sock._sock, self._rtnl_link) if ret < 0: raise netlink.KernelError(ret) ################################################################### # private properties # # Used for formatting output. USE AT OWN RISK @property def _state(self): if 'up' in self.flags: buf = util.good('up') if 'lowerup' not in self.flags: buf += ' ' + util.bad('no-carrier') else: buf = util.bad('down') return buf @property def _brief(self): return self._module_brief() + self._foreach_af('brief') @property def _flags(self): ignore = [ 'up', 'running', 'lowerup', ] return ','.join([flag for flag in self.flags if flag not in ignore]) def _foreach_af(self, name, args=None): buf = '' for af in self.af: try: func = getattr(self.af[af], name) s = str(func(args)) if len(s) > 0: buf += ' ' + s except AttributeError: pass return buf def format(self, details=False, stats=False, indent=''): """Return link as formatted text""" fmt = util.MyFormatter(self, indent) buf = fmt.format('{a|ifindex} {a|name} {a|arptype} {a|address} '\ '{a|_state} <{a|_flags}> {a|_brief}') if details: buf += fmt.nl('\t{t|mtu} {t|txqlen} {t|weight} '\ '{t|qdisc} {t|operstate}') buf += fmt.nl('\t{t|broadcast} {t|alias}') buf += self._foreach_af('details', fmt) if stats: l = [['Packets', RX_PACKETS, TX_PACKETS], ['Bytes', RX_BYTES, TX_BYTES], ['Errors', RX_ERRORS, TX_ERRORS], ['Dropped', RX_DROPPED, TX_DROPPED], ['Compressed', RX_COMPRESSED, TX_COMPRESSED], ['FIFO Errors', RX_FIFO_ERR, TX_FIFO_ERR], ['Length Errors', RX_LEN_ERR, None], ['Over Errors', RX_OVER_ERR, None], ['CRC Errors', RX_CRC_ERR, None], ['Frame Errors', RX_FRAME_ERR, None], ['Missed Errors', RX_MISSED_ERR, None], ['Abort Errors', None, TX_ABORT_ERR], ['Carrier Errors', None, TX_CARRIER_ERR], ['Heartbeat Errors', None, TX_HBEAT_ERR], ['Window Errors', None, TX_WIN_ERR], ['Collisions', None, COLLISIONS], ['Multicast', None, MULTICAST], ['', None, None], ['Ipv6:', None, None], ['Packets', IP6_INPKTS, IP6_OUTPKTS], ['Bytes', IP6_INOCTETS, IP6_OUTOCTETS], ['Discards', IP6_INDISCARDS, IP6_OUTDISCARDS], ['Multicast Packets', IP6_INMCASTPKTS, IP6_OUTMCASTPKTS], ['Multicast Bytes', IP6_INMCASTOCTETS, IP6_OUTMCASTOCTETS], ['Broadcast Packets', IP6_INBCASTPKTS, IP6_OUTBCASTPKTS], ['Broadcast Bytes', IP6_INBCASTOCTETS, IP6_OUTBCASTOCTETS], ['Delivers', IP6_INDELIVERS, None], ['Forwarded', None, IP6_OUTFORWDATAGRAMS], ['No Routes', IP6_INNOROUTES, IP6_OUTNOROUTES], ['Header Errors', IP6_INHDRERRORS, None], ['Too Big Errors', IP6_INTOOBIGERRORS, None], ['Address Errors', IP6_INADDRERRORS, None], ['Unknown Protocol', IP6_INUNKNOWNPROTOS, None], ['Truncated Packets', IP6_INTRUNCATEDPKTS, None], ['Reasm Timeouts', IP6_REASMTIMEOUT, None], ['Reasm Requests', IP6_REASMREQDS, None], ['Reasm Failures', IP6_REASMFAILS, None], ['Reasm OK', IP6_REASMOKS, None], ['Frag Created', None, IP6_FRAGCREATES], ['Frag Failures', None, IP6_FRAGFAILS], ['Frag OK', None, IP6_FRAGOKS], ['', None, None], ['ICMPv6:', None, None], ['Messages', ICMP6_INMSGS, ICMP6_OUTMSGS], ['Errors', ICMP6_INERRORS, ICMP6_OUTERRORS]] buf += '\n\t%s%s%s%s\n' % (33 * ' ', util.title('RX'), 15 * ' ', util.title('TX')) for row in l: row[0] = util.kw(row[0]) row[1] = self.get_stat(row[1]) if row[1] else '' row[2] = self.get_stat(row[2]) if row[2] else '' buf += '\t{0[0]:27} {0[1]:>16} {0[2]:>16}\n'.format(row) buf += self._foreach_af('stats') return buf def get(name, sock=None): """Lookup Link object directly from kernel""" if not name: raise ValueError() if not sock: sock = netlink.lookup_socket(netlink.NETLINK_ROUTE) link = capi.get_from_kernel(sock._sock, 0, name) if not link: return None return Link.from_capi(link) _link_cache = LinkCache() def resolve(name): _link_cache.refill() return _link_cache[name] libnl-3.2.29/python/netlink/route/tc.py0000644000175000017500000003707513023014600014734 00000000000000# # Copyright (c) 2011 Thomas Graf # from __future__ import absolute_import __all__ = [ 'TcCache', 'Tc', 'QdiscCache', 'Qdisc', 'TcClassCache', 'TcClass', ] from .. import core as netlink from . import capi as capi from .. import util as util from . import link as Link TC_PACKETS = 0 TC_BYTES = 1 TC_RATE_BPS = 2 TC_RATE_PPS = 3 TC_QLEN = 4 TC_BACKLOG = 5 TC_DROPS = 6 TC_REQUEUES = 7 TC_OVERLIMITS = 9 TC_H_ROOT = 0xFFFFFFFF TC_H_INGRESS = 0xFFFFFFF1 STAT_PACKETS = 0 STAT_BYTES = 1 STAT_RATE_BPS = 2 STAT_RATE_PPS = 3 STAT_QLEN = 4 STAT_BACKLOG = 5 STAT_DROPS = 6 STAT_REQUEUES = 7 STAT_OVERLIMITS = 8 STAT_MAX = STAT_OVERLIMITS class Handle(object): """ Traffic control handle Representation of a traffic control handle which uniquely identifies each traffic control object in its link namespace. handle = tc.Handle('10:20') handle = tc.handle('root') print int(handle) print str(handle) """ def __init__(self, val=None): if type(val) is str: val = capi.tc_str2handle(val) elif not val: val = 0 self._val = int(val) def __cmp__(self, other): if other is None: other = 0 if isinstance(other, Handle): return int(self) - int(other) elif isinstance(other, int): return int(self) - other else: raise TypeError() def __int__(self): return self._val def __str__(self): return capi.rtnl_tc_handle2str(self._val, 64)[0] def isroot(self): return self._val == TC_H_ROOT or self._val == TC_H_INGRESS class TcCache(netlink.Cache): """Cache of traffic control object""" def __getitem__(self, key): raise NotImplementedError() class Tc(netlink.Object): def __cmp__(self, other): diff = self.ifindex - other.ifindex if diff == 0: diff = int(self.handle) - int(other.handle) return diff def _tc_module_lookup(self): self._module_lookup(self._module_path + self.kind, 'init_' + self._name) @property def root(self): """True if tc object is a root object""" return self.parent.isroot() @property def ifindex(self): """interface index""" return capi.rtnl_tc_get_ifindex(self._rtnl_tc) @ifindex.setter def ifindex(self, value): capi.rtnl_tc_set_ifindex(self._rtnl_tc, int(value)) @property def link(self): link = capi.rtnl_tc_get_link(self._rtnl_tc) if not link: return None return Link.Link.from_capi(link) @link.setter def link(self, value): capi.rtnl_tc_set_link(self._rtnl_tc, value._link) @property def mtu(self): return capi.rtnl_tc_get_mtu(self._rtnl_tc) @mtu.setter def mtu(self, value): capi.rtnl_tc_set_mtu(self._rtnl_tc, int(value)) @property def mpu(self): return capi.rtnl_tc_get_mpu(self._rtnl_tc) @mpu.setter def mpu(self, value): capi.rtnl_tc_set_mpu(self._rtnl_tc, int(value)) @property def overhead(self): return capi.rtnl_tc_get_overhead(self._rtnl_tc) @overhead.setter def overhead(self, value): capi.rtnl_tc_set_overhead(self._rtnl_tc, int(value)) @property def linktype(self): return capi.rtnl_tc_get_linktype(self._rtnl_tc) @linktype.setter def linktype(self, value): capi.rtnl_tc_set_linktype(self._rtnl_tc, int(value)) @property @netlink.nlattr(fmt=util.handle) def handle(self): return Handle(capi.rtnl_tc_get_handle(self._rtnl_tc)) @handle.setter def handle(self, value): capi.rtnl_tc_set_handle(self._rtnl_tc, int(value)) @property @netlink.nlattr(fmt=util.handle) def parent(self): return Handle(capi.rtnl_tc_get_parent(self._rtnl_tc)) @parent.setter def parent(self, value): capi.rtnl_tc_set_parent(self._rtnl_tc, int(value)) @property @netlink.nlattr(fmt=util.bold) def kind(self): return capi.rtnl_tc_get_kind(self._rtnl_tc) @kind.setter def kind(self, value): capi.rtnl_tc_set_kind(self._rtnl_tc, value) self._tc_module_lookup() def get_stat(self, id): return capi.rtnl_tc_get_stat(self._rtnl_tc, id) @property def _dev(self): buf = util.kw('dev') + ' ' if self.link: return buf + util.string(self.link.name) else: return buf + util.num(self.ifindex) def brief(self, title, nodev=False, noparent=False): ret = title + ' {a|kind} {a|handle}' if not nodev: ret += ' {a|_dev}' if not noparent: ret += ' {t|parent}' return ret + self._module_brief() @staticmethod def details(): return '{t|mtu} {t|mpu} {t|overhead} {t|linktype}' @property def packets(self): return self.get_stat(STAT_PACKETS) @property def bytes(self): return self.get_stat(STAT_BYTES) @property def qlen(self): return self.get_stat(STAT_QLEN) @staticmethod def stats(fmt): return fmt.nl('{t|packets} {t|bytes} {t|qlen}') class QdiscCache(netlink.Cache): """Cache of qdiscs""" def __init__(self, cache=None): if not cache: cache = self._alloc_cache_name('route/qdisc') self._protocol = netlink.NETLINK_ROUTE self._nl_cache = cache # def __getitem__(self, key): # if type(key) is int: # link = capi.rtnl_link_get(self._this, key) # elif type(key) is str: # link = capi.rtnl_link_get_by_name(self._this, key) # # if qdisc is None: # raise KeyError() # else: # return Qdisc._from_capi(capi.qdisc2obj(qdisc)) @staticmethod def _new_object(obj): return Qdisc(obj) @staticmethod def _new_cache(cache): return QdiscCache(cache=cache) class Qdisc(Tc): """Queueing discipline""" def __init__(self, obj=None): netlink.Object.__init__(self, 'route/qdisc', 'qdisc', obj) self._module_path = 'netlink.route.qdisc.' self._rtnl_qdisc = self._obj2type(self._nl_object) self._rtnl_tc = capi.obj2tc(self._nl_object) if self.kind: self._tc_module_lookup() @classmethod def from_capi(cls, obj): return cls(capi.qdisc2obj(obj)) @staticmethod def _obj2type(obj): return capi.obj2qdisc(obj) @staticmethod def _new_instance(obj): if not obj: raise ValueError() return Qdisc(obj) @property def childs(self): ret = [] if int(self.handle): ret += get_cls(self.ifindex, parent=self.handle) if self.root: ret += get_class(self.ifindex, parent=TC_H_ROOT) ret += get_class(self.ifindex, parent=self.handle) return ret # def add(self, socket, flags=None): # if not flags: # flags = netlink.NLM_F_CREATE # # ret = capi.rtnl_link_add(socket._sock, self._link, flags) # if ret < 0: # raise netlink.KernelError(ret) # # def change(self, socket, flags=0): # """Commit changes made to the link object""" # if not self._orig: # raise NetlinkError('Original link not available') # ret = capi.rtnl_link_change(socket._sock, self._orig, self._link, flags) # if ret < 0: # raise netlink.KernelError(ret) # # def delete(self, socket): # """Attempt to delete this link in the kernel""" # ret = capi.rtnl_link_delete(socket._sock, self._link) # if ret < 0: # raise netlink.KernelError(ret) def format(self, details=False, stats=False, nodev=False, noparent=False, indent=''): """Return qdisc as formatted text""" fmt = util.MyFormatter(self, indent) buf = fmt.format(self.brief('qdisc', nodev, noparent)) if details: buf += fmt.nl('\t' + self.details()) if stats: buf += self.stats(fmt) # if stats: # l = [['Packets', RX_PACKETS, TX_PACKETS], # ['Bytes', RX_BYTES, TX_BYTES], # ['Errors', RX_ERRORS, TX_ERRORS], # ['Dropped', RX_DROPPED, TX_DROPPED], # ['Compressed', RX_COMPRESSED, TX_COMPRESSED], # ['FIFO Errors', RX_FIFO_ERR, TX_FIFO_ERR], # ['Length Errors', RX_LEN_ERR, None], # ['Over Errors', RX_OVER_ERR, None], # ['CRC Errors', RX_CRC_ERR, None], # ['Frame Errors', RX_FRAME_ERR, None], # ['Missed Errors', RX_MISSED_ERR, None], # ['Abort Errors', None, TX_ABORT_ERR], # ['Carrier Errors', None, TX_CARRIER_ERR], # ['Heartbeat Errors', None, TX_HBEAT_ERR], # ['Window Errors', None, TX_WIN_ERR], # ['Collisions', None, COLLISIONS], # ['Multicast', None, MULTICAST], # ['', None, None], # ['Ipv6:', None, None], # ['Packets', IP6_INPKTS, IP6_OUTPKTS], # ['Bytes', IP6_INOCTETS, IP6_OUTOCTETS], # ['Discards', IP6_INDISCARDS, IP6_OUTDISCARDS], # ['Multicast Packets', IP6_INMCASTPKTS, IP6_OUTMCASTPKTS], # ['Multicast Bytes', IP6_INMCASTOCTETS, IP6_OUTMCASTOCTETS], # ['Broadcast Packets', IP6_INBCASTPKTS, IP6_OUTBCASTPKTS], # ['Broadcast Bytes', IP6_INBCASTOCTETS, IP6_OUTBCASTOCTETS], # ['Delivers', IP6_INDELIVERS, None], # ['Forwarded', None, IP6_OUTFORWDATAGRAMS], # ['No Routes', IP6_INNOROUTES, IP6_OUTNOROUTES], # ['Header Errors', IP6_INHDRERRORS, None], # ['Too Big Errors', IP6_INTOOBIGERRORS, None], # ['Address Errors', IP6_INADDRERRORS, None], # ['Unknown Protocol', IP6_INUNKNOWNPROTOS, None], # ['Truncated Packets', IP6_INTRUNCATEDPKTS, None], # ['Reasm Timeouts', IP6_REASMTIMEOUT, None], # ['Reasm Requests', IP6_REASMREQDS, None], # ['Reasm Failures', IP6_REASMFAILS, None], # ['Reasm OK', IP6_REASMOKS, None], # ['Frag Created', None, IP6_FRAGCREATES], # ['Frag Failures', None, IP6_FRAGFAILS], # ['Frag OK', None, IP6_FRAGOKS], # ['', None, None], # ['ICMPv6:', None, None], # ['Messages', ICMP6_INMSGS, ICMP6_OUTMSGS], # ['Errors', ICMP6_INERRORS, ICMP6_OUTERRORS]] # # buf += '\n\t%s%s%s%s\n' % (33 * ' ', util.title('RX'), # 15 * ' ', util.title('TX')) # # for row in l: # row[0] = util.kw(row[0]) # row[1] = self.get_stat(row[1]) if row[1] else '' # row[2] = self.get_stat(row[2]) if row[2] else '' # buf += '\t{0:27} {1:>16} {2:>16}\n'.format(*row) return buf class TcClassCache(netlink.Cache): """Cache of traffic classes""" def __init__(self, ifindex, cache=None): if not cache: cache = self._alloc_cache_name('route/class') self._protocol = netlink.NETLINK_ROUTE self._nl_cache = cache self._set_arg1(ifindex) @staticmethod def _new_object(obj): return TcClass(obj) def _new_cache(self, cache): return TcClassCache(self.arg1, cache=cache) class TcClass(Tc): """Traffic Class""" def __init__(self, obj=None): netlink.Object.__init__(self, 'route/class', 'class', obj) self._module_path = 'netlink.route.qdisc.' self._rtnl_class = self._obj2type(self._nl_object) self._rtnl_tc = capi.obj2tc(self._nl_object) if self.kind: self._tc_module_lookup() @classmethod def from_capi(cls, obj): return cls(capi.class2obj(obj)) @staticmethod def _obj2type(obj): return capi.obj2class(obj) @staticmethod def _new_instance(obj): if not obj: raise ValueError() return TcClass(obj) @property def childs(self): ret = [] # classes can have classifiers, child classes and leaf # qdiscs ret += get_cls(self.ifindex, parent=self.handle) ret += get_class(self.ifindex, parent=self.handle) ret += get_qdisc(self.ifindex, parent=self.handle) return ret def format(self, details=False, _stats=False, nodev=False, noparent=False, indent=''): """Return class as formatted text""" fmt = util.MyFormatter(self, indent) buf = fmt.format(self.brief('class', nodev, noparent)) if details: buf += fmt.nl('\t' + self.details()) return buf class ClassifierCache(netlink.Cache): """Cache of traffic classifiers objects""" def __init__(self, ifindex, parent, cache=None): if not cache: cache = self._alloc_cache_name('route/cls') self._protocol = netlink.NETLINK_ROUTE self._nl_cache = cache self._set_arg1(ifindex) self._set_arg2(int(parent)) @staticmethod def _new_object(obj): return Classifier(obj) def _new_cache(self, cache): return ClassifierCache(self.arg1, self.arg2, cache=cache) class Classifier(Tc): """Classifier""" def __init__(self, obj=None): netlink.Object.__init__(self, 'route/cls', 'cls', obj) self._module_path = 'netlink.route.cls.' self._rtnl_cls = self._obj2type(self._nl_object) self._rtnl_tc = capi.obj2tc(self._nl_object) @classmethod def from_capi(cls, obj): return cls(capi.cls2obj(obj)) @staticmethod def _obj2type(obj): return capi.obj2cls(obj) @staticmethod def _new_instance(obj): if not obj: raise ValueError() return Classifier(obj) @property def priority(self): return capi.rtnl_cls_get_prio(self._rtnl_cls) @priority.setter def priority(self, value): capi.rtnl_cls_set_prio(self._rtnl_cls, int(value)) @property def protocol(self): return capi.rtnl_cls_get_protocol(self._rtnl_cls) @protocol.setter def protocol(self, value): capi.rtnl_cls_set_protocol(self._rtnl_cls, int(value)) @property def childs(self): return [] def format(self, details=False, _stats=False, nodev=False, noparent=False, indent=''): """Return class as formatted text""" fmt = util.MyFormatter(self, indent) buf = fmt.format(self.brief('classifier', nodev, noparent)) buf += fmt.format(' {t|priority} {t|protocol}') if details: buf += fmt.nl('\t' + self.details()) return buf _qdisc_cache = QdiscCache() def get_qdisc(ifindex, handle=None, parent=None): l = [] _qdisc_cache.refill() for qdisc in _qdisc_cache: if qdisc.ifindex != ifindex: continue if (handle is not None) and (qdisc.handle != handle): continue if (parent is not None) and (qdisc.parent != parent): continue l.append(qdisc) return l _class_cache = {} def get_class(ifindex, parent, handle=None): l = [] try: cache = _class_cache[ifindex] except KeyError: cache = TcClassCache(ifindex) _class_cache[ifindex] = cache cache.refill() for cl in cache: if (parent is not None) and (cl.parent != parent): continue if (handle is not None) and (cl.handle != handle): continue l.append(cl) return l _cls_cache = {} def get_cls(ifindex, parent, handle=None): chain = _cls_cache.get(ifindex, dict()) try: cache = chain[parent] except KeyError: cache = ClassifierCache(ifindex, parent) chain[parent] = cache cache.refill() if handle is None: return [ cls for cls in cache ] return [ cls for cls in cache if cls.handle == handle ] libnl-3.2.29/python/netlink/route/address.py0000644000175000017500000002542413023014600015746 00000000000000# # Copyright (c) 2011 Thomas Graf # """Module providing access to network addresses """ from __future__ import absolute_import __version__ = '1.0' __all__ = [ 'AddressCache', 'Address'] import datetime from .. import core as netlink from . import capi as capi from . import link as Link from .. import util as util class AddressCache(netlink.Cache): """Cache containing network addresses""" def __init__(self, cache=None): if not cache: cache = self._alloc_cache_name('route/addr') self._protocol = netlink.NETLINK_ROUTE self._nl_cache = cache def __getitem__(self, key): # Using ifindex=0 here implies that the local address itself # is unique, otherwise the first occurence is returned. return self.lookup(0, key) def lookup(self, ifindex, local): if type(local) is str: local = netlink.AbstractAddress(local) addr = capi.rtnl_addr_get(self._nl_cache, ifindex, local._nl_addr) if addr is None: raise KeyError() return Address._from_capi(addr) @staticmethod def _new_object(obj): return Address(obj) @staticmethod def _new_cache(cache): return AddressCache(cache=cache) class Address(netlink.Object): """Network address""" def __init__(self, obj=None): netlink.Object.__init__(self, 'route/addr', 'address', obj) self._rtnl_addr = self._obj2type(self._nl_object) @classmethod def _from_capi(cls, obj): return cls(capi.addr2obj(obj)) @staticmethod def _obj2type(obj): return capi.obj2addr(obj) def __cmp__(self, other): # sort by: # 1. network link # 2. address family # 3. local address (including prefixlen) diff = self.ifindex - other.ifindex if diff == 0: diff = self.family - other.family if diff == 0: diff = capi.nl_addr_cmp(self.local, other.local) return diff @staticmethod def _new_instance(obj): return Address(obj) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def ifindex(self): """interface index""" return capi.rtnl_addr_get_ifindex(self._rtnl_addr) @ifindex.setter def ifindex(self, value): link = Link.resolve(value) if not link: raise ValueError() self.link = link @property @netlink.nlattr(type=str, fmt=util.string) def link(self): link = capi.rtnl_addr_get_link(self._rtnl_addr) if not link: return None return Link.Link.from_capi(link) @link.setter def link(self, value): if type(value) is str: try: value = Link.resolve(value) except KeyError: raise ValueError() capi.rtnl_addr_set_link(self._rtnl_addr, value._rtnl_link) # ifindex is immutable but we assume that if _orig does not # have an ifindex specified, it was meant to be given here if capi.rtnl_addr_get_ifindex(self._orig) == 0: capi.rtnl_addr_set_ifindex(self._orig, value.ifindex) @property @netlink.nlattr(type=str, fmt=util.string) def label(self): """address label""" return capi.rtnl_addr_get_label(self._rtnl_addr) @label.setter def label(self, value): capi.rtnl_addr_set_label(self._rtnl_addr, value) @property @netlink.nlattr(type=str, fmt=util.string) def flags(self): """Flags Setting this property will *Not* reset flags to value you supply in Examples: addr.flags = '+xxx' # add xxx flag addr.flags = 'xxx' # exactly the same addr.flags = '-xxx' # remove xxx flag addr.flags = [ '+xxx', '-yyy' ] # list operation """ flags = capi.rtnl_addr_get_flags(self._rtnl_addr) return capi.rtnl_addr_flags2str(flags, 256)[0].split(',') def _set_flag(self, flag): if flag.startswith('-'): i = capi.rtnl_addr_str2flags(flag[1:]) capi.rtnl_addr_unset_flags(self._rtnl_addr, i) elif flag.startswith('+'): i = capi.rtnl_addr_str2flags(flag[1:]) capi.rtnl_addr_set_flags(self._rtnl_addr, i) else: i = capi.rtnl_addr_str2flags(flag) capi.rtnl_addr_set_flags(self._rtnl_addr, i) @flags.setter def flags(self, value): if type(value) is list: for flag in value: self._set_flag(flag) else: self._set_flag(value) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def family(self): """Address family""" fam = capi.rtnl_addr_get_family(self._rtnl_addr) return netlink.AddressFamily(fam) @family.setter def family(self, value): if not isinstance(value, netlink.AddressFamily): value = netlink.AddressFamily(value) capi.rtnl_addr_set_family(self._rtnl_addr, int(value)) @property @netlink.nlattr(type=int, fmt=util.num) def scope(self): """Address scope""" scope = capi.rtnl_addr_get_scope(self._rtnl_addr) return capi.rtnl_scope2str(scope, 32)[0] @scope.setter def scope(self, value): if type(value) is str: value = capi.rtnl_str2scope(value) capi.rtnl_addr_set_scope(self._rtnl_addr, value) @property @netlink.nlattr(type=str, immutable=True, fmt=util.addr) def local(self): """Local address""" a = capi.rtnl_addr_get_local(self._rtnl_addr) return netlink.AbstractAddress(a) @local.setter def local(self, value): a = netlink.AbstractAddress(value) capi.rtnl_addr_set_local(self._rtnl_addr, a._nl_addr) # local is immutable but we assume that if _orig does not # have a local address specified, it was meant to be given here if capi.rtnl_addr_get_local(self._orig) is None: capi.rtnl_addr_set_local(self._orig, a._nl_addr) @property @netlink.nlattr(type=str, fmt=util.addr) def peer(self): """Peer address""" a = capi.rtnl_addr_get_peer(self._rtnl_addr) return netlink.AbstractAddress(a) @peer.setter def peer(self, value): a = netlink.AbstractAddress(value) capi.rtnl_addr_set_peer(self._rtnl_addr, a._nl_addr) @property @netlink.nlattr(type=str, fmt=util.addr) def broadcast(self): """Broadcast address""" a = capi.rtnl_addr_get_broadcast(self._rtnl_addr) return netlink.AbstractAddress(a) @broadcast.setter def broadcast(self, value): a = netlink.AbstractAddress(value) capi.rtnl_addr_set_broadcast(self._rtnl_addr, a._nl_addr) @property @netlink.nlattr(type=str, fmt=util.addr) def multicast(self): """multicast address""" a = capi.rtnl_addr_get_multicast(self._rtnl_addr) return netlink.AbstractAddress(a) @multicast.setter def multicast(self, value): try: a = netlink.AbstractAddress(value) except ValueError as err: raise AttributeError('multicast', err) capi.rtnl_addr_set_multicast(self._rtnl_addr, a._nl_addr) @property @netlink.nlattr(type=str, fmt=util.addr) def anycast(self): """anycast address""" a = capi.rtnl_addr_get_anycast(self._rtnl_addr) return netlink.AbstractAddress(a) @anycast.setter def anycast(self, value): a = netlink.AbstractAddress(value) capi.rtnl_addr_set_anycast(self._rtnl_addr, a._nl_addr) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def valid_lifetime(self): """Valid lifetime""" msecs = capi.rtnl_addr_get_valid_lifetime(self._rtnl_addr) if msecs == 0xFFFFFFFF: return None else: return datetime.timedelta(seconds=msecs) @valid_lifetime.setter def valid_lifetime(self, value): capi.rtnl_addr_set_valid_lifetime(self._rtnl_addr, int(value)) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def preferred_lifetime(self): """Preferred lifetime""" msecs = capi.rtnl_addr_get_preferred_lifetime(self._rtnl_addr) if msecs == 0xFFFFFFFF: return None else: return datetime.timedelta(seconds=msecs) @preferred_lifetime.setter def preferred_lifetime(self, value): capi.rtnl_addr_set_preferred_lifetime(self._rtnl_addr, int(value)) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def create_time(self): """Creation time""" hsec = capi.rtnl_addr_get_create_time(self._rtnl_addr) return datetime.timedelta(milliseconds=10*hsec) @property @netlink.nlattr(type=int, immutable=True, fmt=util.num) def last_update(self): """Last update""" hsec = capi.rtnl_addr_get_last_update_time(self._rtnl_addr) return datetime.timedelta(milliseconds=10*hsec) def add(self, socket=None, flags=None): if not socket: socket = netlink.lookup_socket(netlink.NETLINK_ROUTE) if not flags: flags = netlink.NLM_F_CREATE ret = capi.rtnl_addr_add(socket._sock, self._rtnl_addr, flags) if ret < 0: raise netlink.KernelError(ret) def delete(self, socket, flags=0): """Attempt to delete this address in the kernel""" ret = capi.rtnl_addr_delete(socket._sock, self._rtnl_addr, flags) if ret < 0: raise netlink.KernelError(ret) ################################################################### # private properties # # Used for formatting output. USE AT OWN RISK @property def _flags(self): return ','.join(self.flags) def format(self, details=False, stats=False, nodev=False, indent=''): """Return address as formatted text""" fmt = util.MyFormatter(self, indent) buf = fmt.format('{a|local!b}') if not nodev: buf += fmt.format(' {a|ifindex}') buf += fmt.format(' {a|scope}') if self.label: buf += fmt.format(' "{a|label}"') buf += fmt.format(' <{a|_flags}>') if details: buf += fmt.nl('\t{t|broadcast} {t|multicast}') \ + fmt.nl('\t{t|peer} {t|anycast}') if self.valid_lifetime: buf += fmt.nl('\t{s|valid-lifetime!k} '\ '{a|valid_lifetime}') if self.preferred_lifetime: buf += fmt.nl('\t{s|preferred-lifetime!k} '\ '{a|preferred_lifetime}') if stats and (self.create_time or self.last_update): buf += self.nl('\t{s|created!k} {a|create_time}'\ ' {s|last-updated!k} {a|last_update}') return buf libnl-3.2.29/python/netlink/route/capi.i0000644000175000017500000004550213023014600015034 00000000000000%module capi %{ #include #include #include #include #include #include #include #include #include #include #include #include #include %} %include %include %inline %{ struct nl_object *link2obj(struct rtnl_link *link) { return OBJ_CAST(link); } struct rtnl_link *obj2link(struct nl_object *obj) { return (struct rtnl_link *) obj; } struct rtnl_link *get_from_kernel(struct nl_sock *sk, int ifindex, const char *name) { struct rtnl_link *link; if (rtnl_link_get_kernel(sk, ifindex, name, &link) < 0) return NULL; return link; } uint32_t inet_get_conf(struct rtnl_link *link, const unsigned int id) { uint32_t result; if (rtnl_link_inet_get_conf(link, id, &result) < 0) return 0; return result; } %}; extern struct nl_object *link2obj(struct rtnl_link *); extern struct rtnl_link *obj2link(struct nl_object *); /* */ %cstring_output_maxsize(char *buf, size_t len) extern char * rtnl_scope2str(int, char *buf, size_t len); extern int rtnl_str2scope(const char *); /* */ extern struct rtnl_link *rtnl_link_alloc(void); extern struct rtnl_link *rtnl_link_get(struct nl_cache *, int); extern struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *, const char *); extern int rtnl_link_build_add_request(struct rtnl_link *, int, struct nl_msg **); extern int rtnl_link_add(struct nl_sock *, struct rtnl_link *, int); extern int rtnl_link_build_change_request(struct rtnl_link *, struct rtnl_link *, int, struct nl_msg **); extern int rtnl_link_change(struct nl_sock *, struct rtnl_link *, struct rtnl_link *, int); extern int rtnl_link_build_delete_request(const struct rtnl_link *, struct nl_msg **); extern int rtnl_link_delete(struct nl_sock *, const struct rtnl_link *); extern int rtnl_link_build_get_request(int, const char *, struct nl_msg **); extern char *rtnl_link_stat2str(int, char *, size_t); extern int rtnl_link_str2stat(const char *); %cstring_output_maxsize(char *buf, size_t len) extern char *rtnl_link_flags2str(int, char *buf, size_t len); extern int rtnl_link_str2flags(const char *); %cstring_output_maxsize(char *buf, size_t len) extern char *rtnl_link_operstate2str(uint8_t, char *buf, size_t len); extern int rtnl_link_str2operstate(const char *); %cstring_output_maxsize(char *buf, size_t len) extern char *rtnl_link_mode2str(uint8_t, char *buf, size_t len); extern int rtnl_link_str2mode(const char *); extern void rtnl_link_set_qdisc(struct rtnl_link *, const char *); extern char *rtnl_link_get_qdisc(struct rtnl_link *); extern void rtnl_link_set_name(struct rtnl_link *, const char *); extern char *rtnl_link_get_name(struct rtnl_link *); extern void rtnl_link_set_flags(struct rtnl_link *, unsigned int); extern void rtnl_link_unset_flags(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_flags(struct rtnl_link *); extern void rtnl_link_set_mtu(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_mtu(struct rtnl_link *); extern void rtnl_link_set_txqlen(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_txqlen(struct rtnl_link *); extern void rtnl_link_set_ifindex(struct rtnl_link *, int); extern int rtnl_link_get_ifindex(struct rtnl_link *); extern void rtnl_link_set_family(struct rtnl_link *, int); extern int rtnl_link_get_family(struct rtnl_link *); extern void rtnl_link_set_arptype(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_arptype(struct rtnl_link *); extern void rtnl_link_set_addr(struct rtnl_link *, struct nl_addr *); extern struct nl_addr *rtnl_link_get_addr(struct rtnl_link *); extern void rtnl_link_set_broadcast(struct rtnl_link *, struct nl_addr *); extern struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *); extern void rtnl_link_set_link(struct rtnl_link *, int); extern int rtnl_link_get_link(struct rtnl_link *); extern void rtnl_link_set_master(struct rtnl_link *, int); extern int rtnl_link_get_master(struct rtnl_link *); extern void rtnl_link_set_operstate(struct rtnl_link *, uint8_t); extern uint8_t rtnl_link_get_operstate(struct rtnl_link *); extern void rtnl_link_set_linkmode(struct rtnl_link *, uint8_t); extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *); extern const char *rtnl_link_get_ifalias(struct rtnl_link *); extern void rtnl_link_set_ifalias(struct rtnl_link *, const char *); extern int rtnl_link_get_num_vf(struct rtnl_link *, uint32_t *); extern uint64_t rtnl_link_get_stat(struct rtnl_link *, int); extern int rtnl_link_set_stat(struct rtnl_link *, const unsigned int, const uint64_t); extern int rtnl_link_set_type(struct rtnl_link *, const char *); extern char *rtnl_link_get_type(struct rtnl_link *); extern int rtnl_link_enslave(struct nl_sock * sock, struct rtnl_link * master, struct rtnl_link * slave); extern int rtnl_link_release(struct nl_sock * sock, struct rtnl_link * slave); /* */ struct vlan_map { uint32_t vm_from; uint32_t vm_to; }; #define VLAN_PRIO_MAX 7 %cstring_output_maxsize(char *buf, size_t len) extern char *rtnl_link_vlan_flags2str(int, char *buf, size_t len); extern int rtnl_link_vlan_str2flags(const char *); extern int rtnl_link_vlan_set_id(struct rtnl_link *, int); extern int rtnl_link_vlan_get_id(struct rtnl_link *); extern int rtnl_link_vlan_set_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_vlan_unset_flags(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_vlan_get_flags(struct rtnl_link *); extern int rtnl_link_vlan_set_ingress_map(struct rtnl_link *, int, uint32_t); extern uint32_t *rtnl_link_vlan_get_ingress_map(struct rtnl_link *); extern int rtnl_link_vlan_set_egress_map(struct rtnl_link *, uint32_t, int); extern struct vlan_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *, int *); /* */ %cstring_output_maxsize(char *buf, size_t len) extern struct rtnl_link *rtnl_link_macvlan_alloc(void); extern int rtnl_link_is_macvlan(struct rtnl_link *); extern char * rtnl_link_macvlan_mode2str(int, char *, size_t); extern int rtnl_link_macvlan_str2mode(const char *); extern char * rtnl_link_macvlan_flags2str(int, char *, size_t); extern int rtnl_link_macvlan_str2flags(const char *); extern int rtnl_link_macvlan_set_mode(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_macvlan_get_mode(struct rtnl_link *); extern int rtnl_link_macvlan_set_flags(struct rtnl_link *, uint16_t); extern int rtnl_link_macvlan_unset_flags(struct rtnl_link *, uint16_t); extern uint16_t rtnl_link_macvlan_get_flags(struct rtnl_link *); /* */ #define VXLAN_ID_MAX 16777215 extern struct rtnl_link *rtnl_link_vxlan_alloc(void); extern int rtnl_link_is_vxlan(struct rtnl_link *); extern int rtnl_link_vxlan_set_id(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_id(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_group(struct rtnl_link *, struct nl_addr *); extern int rtnl_link_vxlan_get_group(struct rtnl_link *, struct nl_addr **); extern int rtnl_link_vxlan_set_link(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_link(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_local(struct rtnl_link *, struct nl_addr *); extern int rtnl_link_vxlan_get_local(struct rtnl_link *, struct nl_addr **); extern int rtnl_link_vxlan_set_ttl(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_ttl(struct rtnl_link *); extern int rtnl_link_vxlan_set_tos(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_tos(struct rtnl_link *); extern int rtnl_link_vxlan_set_learning(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_learning(struct rtnl_link *); extern int rtnl_link_vxlan_enable_learning(struct rtnl_link *); extern int rtnl_link_vxlan_disable_learning(struct rtnl_link *); extern int rtnl_link_vxlan_set_ageing(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_ageing(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_limit(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_limit(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_port_range(struct rtnl_link *, struct ifla_vxlan_port_range *); extern int rtnl_link_vxlan_get_port_range(struct rtnl_link *, struct ifla_vxlan_port_range *); extern int rtnl_link_vxlan_set_proxy(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_proxy(struct rtnl_link *); extern int rtnl_link_vxlan_enable_proxy(struct rtnl_link *); extern int rtnl_link_vxlan_disable_proxy(struct rtnl_link *); extern int rtnl_link_vxlan_set_rsc(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_rsc(struct rtnl_link *); extern int rtnl_link_vxlan_enable_rsc(struct rtnl_link *); extern int rtnl_link_vxlan_disable_rsc(struct rtnl_link *); extern int rtnl_link_vxlan_set_l2miss(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_l2miss(struct rtnl_link *); extern int rtnl_link_vxlan_enable_l2miss(struct rtnl_link *); extern int rtnl_link_vxlan_disable_l2miss(struct rtnl_link *); extern int rtnl_link_vxlan_set_l3miss(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_l3miss(struct rtnl_link *); extern int rtnl_link_vxlan_enable_l3miss(struct rtnl_link *); extern int rtnl_link_vxlan_disable_l3miss(struct rtnl_link *); /* */ enum rtnl_link_bridge_flags { RTNL_BRIDGE_HAIRPIN_MODE = 0x0001, RTNL_BRIDGE_BPDU_GUARD = 0x0002, RTNL_BRIDGE_ROOT_BLOCK = 0x0004, RTNL_BRIDGE_FAST_LEAVE = 0x0008, }; extern int rtnl_link_is_bridge(struct rtnl_link *); extern int rtnl_link_bridge_has_ext_info(struct rtnl_link *); extern int rtnl_link_bridge_set_port_state(struct rtnl_link *, uint8_t ); extern int rtnl_link_bridge_get_port_state(struct rtnl_link *); extern int rtnl_link_bridge_set_priority(struct rtnl_link *, uint16_t); extern int rtnl_link_bridge_get_priority(struct rtnl_link *); extern int rtnl_link_bridge_set_cost(struct rtnl_link *, uint32_t); extern int rtnl_link_bridge_get_cost(struct rtnl_link *, uint32_t *); extern int rtnl_link_bridge_unset_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_set_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_get_flags(struct rtnl_link *); extern char * rtnl_link_bridge_flags2str(int, char *, size_t); extern int rtnl_link_bridge_str2flags(const char *); /* */ %cstring_output_maxsize(char *buf, size_t len) extern const char *rtnl_link_inet_devconf2str(int, char *buf, size_t len); extern unsigned int rtnl_link_inet_str2devconf(const char *); extern int rtnl_link_inet_set_conf(struct rtnl_link *, const unsigned int, uint32_t); /* */ %inline %{ uint32_t tc_str2handle(const char *name) { uint32_t result; if (rtnl_tc_str2handle(name, &result) < 0) return 0; return result; } %}; extern void rtnl_tc_set_ifindex(struct rtnl_tc *, int); extern int rtnl_tc_get_ifindex(struct rtnl_tc *); extern void rtnl_tc_set_link(struct rtnl_tc *, struct rtnl_link *); extern struct rtnl_link *rtnl_tc_get_link(struct rtnl_tc *); extern void rtnl_tc_set_mtu(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_mtu(struct rtnl_tc *); extern void rtnl_tc_set_mpu(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_mpu(struct rtnl_tc *); extern void rtnl_tc_set_overhead(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_overhead(struct rtnl_tc *); extern void rtnl_tc_set_linktype(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_linktype(struct rtnl_tc *); extern void rtnl_tc_set_handle(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_handle(struct rtnl_tc *); extern void rtnl_tc_set_parent(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_parent(struct rtnl_tc *); extern int rtnl_tc_set_kind(struct rtnl_tc *, const char *); extern char * rtnl_tc_get_kind(struct rtnl_tc *); extern uint64_t rtnl_tc_get_stat(struct rtnl_tc *, enum rtnl_tc_stat); extern int rtnl_tc_calc_txtime(int, int); extern int rtnl_tc_calc_bufsize(int, int); extern int rtnl_tc_calc_cell_log(int); extern int rtnl_tc_read_classid_file(void); %cstring_output_maxsize(char *buf, size_t len) extern char * rtnl_tc_handle2str(uint32_t, char *buf, size_t len); extern int rtnl_classid_generate(const char *, uint32_t *, uint32_t); /* */ %inline %{ struct nl_object *qdisc2obj(struct rtnl_qdisc *qdisc) { return OBJ_CAST(qdisc); } struct rtnl_qdisc *obj2qdisc(struct nl_object *obj) { return (struct rtnl_qdisc *) obj; } struct nl_object *class2obj(struct rtnl_class *cl) { return OBJ_CAST(cl); } struct rtnl_class *obj2class(struct nl_object *obj) { return (struct rtnl_class *) obj; } struct nl_object *cls2obj(struct rtnl_cls *cls) { return OBJ_CAST(cls); } struct rtnl_cls *obj2cls(struct nl_object *obj) { return (struct rtnl_cls *) obj; } struct rtnl_tc *obj2tc(struct nl_object *obj) { return TC_CAST(obj); } %}; extern struct rtnl_qdisc * rtnl_qdisc_alloc(void); extern struct rtnl_qdisc * rtnl_qdisc_get(struct nl_cache *, int, uint32_t); extern struct rtnl_qdisc * rtnl_qdisc_get_by_parent(struct nl_cache *, int, uint32_t); extern int rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int, struct nl_msg **); extern int rtnl_qdisc_add(struct nl_sock *, struct rtnl_qdisc *, int); extern int rtnl_qdisc_build_update_request(struct rtnl_qdisc *, struct rtnl_qdisc *, int, struct nl_msg **); extern int rtnl_qdisc_update(struct nl_sock *, struct rtnl_qdisc *, struct rtnl_qdisc *, int); extern int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *, struct nl_msg **); extern int rtnl_qdisc_delete(struct nl_sock *, struct rtnl_qdisc *); /* */ extern struct rtnl_cls *rtnl_cls_alloc(void); extern void rtnl_cls_put(struct rtnl_cls *); extern int rtnl_cls_add(struct nl_sock *, struct rtnl_cls *, int); extern int rtnl_cls_delete(struct nl_sock *, struct rtnl_cls *, int); extern void rtnl_cls_set_prio(struct rtnl_cls *, uint16_t); extern uint16_t rtnl_cls_get_prio(struct rtnl_cls *); extern void rtnl_cls_set_protocol(struct rtnl_cls *, uint16_t); extern uint16_t rtnl_cls_get_protocol(struct rtnl_cls *); /* */ extern uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *); extern int rtnl_htb_set_rate2quantum(struct rtnl_qdisc *, uint32_t); extern uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *); extern int rtnl_htb_set_defcls(struct rtnl_qdisc *, uint32_t); extern uint32_t rtnl_htb_get_prio(struct rtnl_class *); extern int rtnl_htb_set_prio(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_rate(struct rtnl_class *); extern int rtnl_htb_set_rate(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_ceil(struct rtnl_class *); extern int rtnl_htb_set_ceil(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *); extern int rtnl_htb_set_rbuffer(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *); extern int rtnl_htb_set_cbuffer(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_quantum(struct rtnl_class *); extern int rtnl_htb_set_quantum(struct rtnl_class *, uint32_t); extern int rtnl_htb_get_level(struct rtnl_class *); /* */ %inline %{ struct nl_object *addr2obj(struct rtnl_addr *addr) { return OBJ_CAST(addr); } struct rtnl_addr *obj2addr(struct nl_object *obj) { return (struct rtnl_addr *) obj; } %}; extern struct rtnl_addr *rtnl_addr_alloc(void); extern struct rtnl_addr * rtnl_addr_get(struct nl_cache *, int, struct nl_addr *); extern int rtnl_addr_build_add_request(struct rtnl_addr *, int, struct nl_msg **); extern int rtnl_addr_add(struct nl_sock *, struct rtnl_addr *, int); extern int rtnl_addr_build_delete_request(struct rtnl_addr *, int, struct nl_msg **); extern int rtnl_addr_delete(struct nl_sock *, struct rtnl_addr *, int); %cstring_output_maxsize(char *buf, size_t len) extern char * rtnl_addr_flags2str(int, char *buf, size_t len); extern int rtnl_addr_str2flags(const char *); extern int rtnl_addr_set_label(struct rtnl_addr *, const char *); extern char * rtnl_addr_get_label(struct rtnl_addr *); extern void rtnl_addr_set_ifindex(struct rtnl_addr *, int); extern int rtnl_addr_get_ifindex(struct rtnl_addr *); extern void rtnl_addr_set_link(struct rtnl_addr *, struct rtnl_link *); extern struct rtnl_link * rtnl_addr_get_link(struct rtnl_addr *); extern void rtnl_addr_set_family(struct rtnl_addr *, int); extern int rtnl_addr_get_family(struct rtnl_addr *); extern void rtnl_addr_set_prefixlen(struct rtnl_addr *, int); extern int rtnl_addr_get_prefixlen(struct rtnl_addr *); extern void rtnl_addr_set_scope(struct rtnl_addr *, int); extern int rtnl_addr_get_scope(struct rtnl_addr *); extern void rtnl_addr_set_flags(struct rtnl_addr *, unsigned int); extern void rtnl_addr_unset_flags(struct rtnl_addr *, unsigned int); extern unsigned int rtnl_addr_get_flags(struct rtnl_addr *); extern int rtnl_addr_set_local(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *); extern int rtnl_addr_set_peer(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *); extern int rtnl_addr_set_broadcast(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *); extern int rtnl_addr_set_multicast(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *); extern int rtnl_addr_set_anycast(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *); extern uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *); extern void rtnl_addr_set_valid_lifetime(struct rtnl_addr *, uint32_t); extern uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *); extern void rtnl_addr_set_preferred_lifetime(struct rtnl_addr *, uint32_t); extern uint32_t rtnl_addr_get_create_time(struct rtnl_addr *); extern uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *); libnl-3.2.29/python/netlink/route/qdisc/0000755000175000017500000000000013031473756015147 500000000000000libnl-3.2.29/python/netlink/route/qdisc/__init__.py0000644000175000017500000000000013023014600017142 00000000000000libnl-3.2.29/python/netlink/route/qdisc/htb.py0000644000175000017500000000703013023014600016172 00000000000000# # Copyright (c) 2011 Thomas Graf # """HTB qdisc """ from __future__ import absolute_import from ... import core as netlink from ... import util as util from .. import capi as capi from .. import tc as tc class HTBQdisc(object): def __init__(self, qdisc): self._qdisc = qdisc @property @netlink.nlattr(type=int) def default_class(self): return tc.Handle(capi.rtnl_htb_get_defcls(self._qdisc._rtnl_qdisc)) @default_class.setter def default_class(self, value): capi.rtnl_htb_set_defcls(self._qdisc._rtnl_qdisc, int(value)) @property @netlink.nlattr('r2q', type=int) def r2q(self): return capi.rtnl_htb_get_rate2quantum(self._qdisc._rtnl_qdisc) @r2q.setter def r2q(self, value): capi.rtnl_htb_get_rate2quantum(self._qdisc._rtnl_qdisc, int(value)) def brief(self): fmt = util.MyFormatter(self) ret = ' {s|default-class!k} {a|default_class}' if self.r2q: ret += ' {s|r2q!k} {a|r2q}' return fmt.format(ret) class HTBClass(object): def __init__(self, cl): self._class = cl @property @netlink.nlattr(type=str) def rate(self): rate = capi.rtnl_htb_get_rate(self._class._rtnl_class) return util.Rate(rate) @rate.setter def rate(self, value): capi.rtnl_htb_set_rate(self._class._rtnl_class, int(value)) @property @netlink.nlattr(type=str) def ceil(self): ceil = capi.rtnl_htb_get_ceil(self._class._rtnl_class) return util.Rate(ceil) @ceil.setter def ceil(self, value): capi.rtnl_htb_set_ceil(self._class._rtnl_class, int(value)) @property @netlink.nlattr(type=str) def burst(self): burst = capi.rtnl_htb_get_rbuffer(self._class._rtnl_class) return util.Size(burst) @burst.setter def burst(self, value): capi.rtnl_htb_set_rbuffer(self._class._rtnl_class, int(value)) @property @netlink.nlattr(type=str) def ceil_burst(self): burst = capi.rtnl_htb_get_cbuffer(self._class._rtnl_class) return util.Size(burst) @ceil_burst.setter def ceil_burst(self, value): capi.rtnl_htb_set_cbuffer(self._class._rtnl_class, int(value)) @property @netlink.nlattr(type=int) def prio(self): return capi.rtnl_htb_get_prio(self._class._rtnl_class) @prio.setter def prio(self, value): capi.rtnl_htb_set_prio(self._class._rtnl_class, int(value)) @property @netlink.nlattr(type=int) def quantum(self): return capi.rtnl_htb_get_quantum(self._class._rtnl_class) @quantum.setter def quantum(self, value): capi.rtnl_htb_set_quantum(self._class._rtnl_class, int(value)) @property @netlink.nlattr(type=int) def level(self): return capi.rtnl_htb_get_level(self._class._rtnl_class) @level.setter def level(self, value): capi.rtnl_htb_set_level(self._class._rtnl_class, int(value)) def brief(self): fmt = util.MyFormatter(self) ret = ' {t|prio} {t|rate}' if self.rate != self.ceil: ret += ' {s|borrow-up-to!k} {a|ceil}' ret += ' {t|burst}' return fmt.format(ret) def details(self): fmt = util.MyFormatter(self) return fmt.nl('\t{t|level} {t|quantum}') def init_qdisc(qdisc): qdisc.htb = HTBQdisc(qdisc) return qdisc.htb def init_class(cl): cl.htb = HTBClass(cl) return cl.htb #extern void rtnl_htb_set_quantum(struct rtnl_class *, uint32_t quantum); libnl-3.2.29/python/netlink/route/Makefile.in0000644000175000017500000003042213031473644016026 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = python/netlink/route ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ capi.i \ __init__.py \ address.py \ link.py \ tc.py \ links/__init__.py \ links/dummy.py \ links/inet.py \ links/vlan.py \ qdisc/__init__.py \ qdisc/htb.py all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python/netlink/route/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign python/netlink/route/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/python/netlink/route/links/0000755000175000017500000000000013031473756015164 500000000000000libnl-3.2.29/python/netlink/route/links/__init__.py0000644000175000017500000000000013023014600017157 00000000000000libnl-3.2.29/python/netlink/route/links/vlan.py0000644000175000017500000000363413023014600016400 00000000000000# # Copyright (c) 2011 Thomas Graf # """VLAN network link """ from __future__ import absolute_import from ... import core as netlink from .. import capi as capi class VLANLink(object): def __init__(self, link): self._link = link @property @netlink.nlattr(type=int) def id(self): """vlan identifier""" return capi.rtnl_link_vlan_get_id(self._link) @id.setter def id(self, value): capi.rtnl_link_vlan_set_id(self._link, int(value)) @property @netlink.nlattr(type=str) def flags(self): """ VLAN flags Setting this property will *Not* reset flags to value you supply in Examples: link.flags = '+xxx' # add xxx flag link.flags = 'xxx' # exactly the same link.flags = '-xxx' # remove xxx flag link.flags = [ '+xxx', '-yyy' ] # list operation """ flags = capi.rtnl_link_vlan_get_flags(self._link) return capi.rtnl_link_vlan_flags2str(flags, 256)[0].split(',') def _set_flag(self, flag): if flag.startswith('-'): i = capi.rtnl_link_vlan_str2flags(flag[1:]) capi.rtnl_link_vlan_unset_flags(self._link, i) elif flag.startswith('+'): i = capi.rtnl_link_vlan_str2flags(flag[1:]) capi.rtnl_link_vlan_set_flags(self._link, i) else: i = capi.rtnl_link_vlan_str2flags(flag) capi.rtnl_link_vlan_set_flags(self._link, i) @flags.setter def flags(self, value): if type(value) is list: for flag in value: self._set_flag(flag) else: self._set_flag(value) ################################################################### # TODO: # - ingress map # - egress map def brief(self): return 'vlan-id {0}'.format(self.id) def init(link): link.vlan = VLANLink(link._rtnl_link) return link.vlan libnl-3.2.29/python/netlink/route/links/dummy.py0000644000175000017500000000060013023014600016561 00000000000000# # Copyright (c) 2011 Thomas Graf # """Dummy """ from __future__ import absolute_import __version__ = '1.0' __all__ = [ 'init', ] class DummyLink(object): def __init__(self, link): self._rtnl_link = link @staticmethod def brief(): return 'dummy' def init(link): link.dummy = DummyLink(link._rtnl_link) return link.dummy libnl-3.2.29/python/netlink/route/links/inet.py0000644000175000017500000001020213023014600016364 00000000000000# # Copyright (c) 2011 Thomas Graf # """IPv4 """ from __future__ import absolute_import __all__ = [ '', ] from ... import core as netlink from .. import capi as capi from ... import util as util DEVCONF_FORWARDING = 1 DEVCONF_MC_FORWARDING = 2 DEVCONF_PROXY_ARP = 3 DEVCONF_ACCEPT_REDIRECTS = 4 DEVCONF_SECURE_REDIRECTS = 5 DEVCONF_SEND_REDIRECTS = 6 DEVCONF_SHARED_MEDIA = 7 DEVCONF_RP_FILTER = 8 DEVCONF_ACCEPT_SOURCE_ROUTE = 9 DEVCONF_BOOTP_RELAY = 10 DEVCONF_LOG_MARTIANS = 11 DEVCONF_TAG = 12 DEVCONF_ARPFILTER = 13 DEVCONF_MEDIUM_ID = 14 DEVCONF_NOXFRM = 15 DEVCONF_NOPOLICY = 16 DEVCONF_FORCE_IGMP_VERSION = 17 DEVCONF_ARP_ANNOUNCE = 18 DEVCONF_ARP_IGNORE = 19 DEVCONF_PROMOTE_SECONDARIES = 20 DEVCONF_ARP_ACCEPT = 21 DEVCONF_ARP_NOTIFY = 22 DEVCONF_ACCEPT_LOCAL = 23 DEVCONF_SRC_VMARK = 24 DEVCONF_PROXY_ARP_PVLAN = 25 DEVCONF_MAX = DEVCONF_PROXY_ARP_PVLAN def _resolve(id): if type(id) is str: id = capi.rtnl_link_inet_str2devconf(id)[0] if id < 0: raise NameError('unknown configuration id') return id class InetLink(object): def __init__(self, link): self._link = link def details(self, fmt): buf = fmt.nl('\n\t{0}\n\t'.format(util.title('Configuration:'))) for i in range(DEVCONF_FORWARDING, DEVCONF_MAX+1): if i & 1 and i > 1: buf += fmt.nl('\t') txt = util.kw(capi.rtnl_link_inet_devconf2str(i, 32)[0]) buf += fmt.format('{0:28s} {1:12} ', txt, self.get_conf(i)) return buf def get_conf(self, id): return capi.inet_get_conf(self._link._rtnl_link, _resolve(id)) def set_conf(self, id, value): return capi.rtnl_link_inet_set_conf(self._link._rtnl_link, _resolve(id), int(value)) @property @netlink.nlattr(type=bool, fmt=util.boolean) def forwarding(self): return bool(self.get_conf(DEVCONF_FORWARDING)) @forwarding.setter def forwarding(self, value): self.set_conf(DEVCONF_FORWARDING, int(value)) @property @netlink.nlattr(type=bool, fmt=util.boolean) def mc_forwarding(self): return bool(self.get_conf(DEVCONF_MC_FORWARDING)) @mc_forwarding.setter def mc_forwarding(self, value): self.set_conf(DEVCONF_MC_FORWARDING, int(value)) @property @netlink.nlattr(type=bool, fmt=util.boolean) def proxy_arp(self): return bool(self.get_conf(DEVCONF_PROXY_ARP)) @proxy_arp.setter def proxy_arp(self, value): self.set_conf(DEVCONF_PROXY_ARP, int(value)) @property @netlink.nlattr(type=bool, fmt=util.boolean) def accept_redirects(self): return bool(self.get_conf(DEVCONF_ACCEPT_REDIRECTS)) @accept_redirects.setter def accept_redirects(self, value): self.set_conf(DEVCONF_ACCEPT_REDIRECTS, int(value)) @property @netlink.nlattr(type=bool, fmt=util.boolean) def secure_redirects(self): return bool(self.get_conf(DEVCONF_SECURE_REDIRECTS)) @secure_redirects.setter def secure_redirects(self, value): self.set_conf(DEVCONF_SECURE_REDIRECTS, int(value)) @property @netlink.nlattr(type=bool, fmt=util.boolean) def send_redirects(self): return bool(self.get_conf(DEVCONF_SEND_REDIRECTS)) @send_redirects.setter def send_redirects(self, value): self.set_conf(DEVCONF_SEND_REDIRECTS, int(value)) @property @netlink.nlattr(type=bool, fmt=util.boolean) def shared_media(self): return bool(self.get_conf(DEVCONF_SHARED_MEDIA)) @shared_media.setter def shared_media(self, value): self.set_conf(DEVCONF_SHARED_MEDIA, int(value)) # IPV4_DEVCONF_RP_FILTER, # IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, # IPV4_DEVCONF_BOOTP_RELAY, # IPV4_DEVCONF_LOG_MARTIANS, # IPV4_DEVCONF_TAG, # IPV4_DEVCONF_ARPFILTER, # IPV4_DEVCONF_MEDIUM_ID, # IPV4_DEVCONF_NOXFRM, # IPV4_DEVCONF_NOPOLICY, # IPV4_DEVCONF_FORCE_IGMP_VERSION, # IPV4_DEVCONF_ARP_ANNOUNCE, # IPV4_DEVCONF_ARP_IGNORE, # IPV4_DEVCONF_PROMOTE_SECONDARIES, # IPV4_DEVCONF_ARP_ACCEPT, # IPV4_DEVCONF_ARP_NOTIFY, # IPV4_DEVCONF_ACCEPT_LOCAL, # IPV4_DEVCONF_SRC_VMARK, # IPV4_DEVCONF_PROXY_ARP_PVLAN, libnl-3.2.29/python/Makefile.in0000644000175000017500000004474413031473644013240 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = python ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = setup.py CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/setup.py.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = doc examples netlink tests all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign python/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): setup.py: $(top_builddir)/config.status $(srcdir)/setup.py.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/python/examples/0000755000175000017500000000000013031473756013060 500000000000000libnl-3.2.29/python/examples/Makefile.am0000644000175000017500000000010713023014600015006 00000000000000# -*- Makefile -*- EXTRA_DIST = \ iface.py \ nl80211.py \ wiphy.py libnl-3.2.29/python/examples/iface.py0000644000175000017500000000633513023014600014404 00000000000000import netlink.capi as nl import netlink.genl.capi as genl import nl80211 import sys import traceback class test_class: def __init__(self): self.done = 1; def msg_handler(m, a): try: e, attr = genl.py_genlmsg_parse(nl.nlmsg_hdr(m), 0, nl80211.NL80211_ATTR_MAX, None) if nl80211.NL80211_ATTR_WIPHY in attr: thiswiphy = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_WIPHY]) print("phy#%d" % thiswiphy) if nl80211.NL80211_ATTR_IFNAME in attr: print("\tinterface %s" % nl.nla_get_string(attr[nl80211.NL80211_ATTR_IFNAME])); if nl80211.NL80211_ATTR_IFINDEX in attr: print("\tifindex %d" % nl.nla_get_u32(attr[nl80211.NL80211_ATTR_IFINDEX])) if nl80211.NL80211_ATTR_WDEV in attr: print("\twdev 0x%lx" % nl.nla_get_u64(attr[nl80211.NL80211_ATTR_WDEV])) if nl80211.NL80211_ATTR_MAC in attr: print("\tmac %02x:%02x:%02x:%02x:%02x:%02x" % tuple(nl.nla_data(attr[nl80211.NL80211_ATTR_MAC]))) if nl80211.NL80211_ATTR_SSID in attr: print("\tssid ", nl.nla_data(attr[nl80211.NL80211_ATTR_SSID])) if nl80211.NL80211_ATTR_IFTYPE in attr: iftype = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_IFTYPE]) print("\ttype %s" % nl80211.nl80211_iftype2str[iftype]) if nl80211.NL80211_ATTR_WIPHY_FREQ in attr: freq = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_WIPHY_FREQ]) sys.stdout.write("\tfreq %d MHz" % freq); if nl80211.NL80211_ATTR_CHANNEL_WIDTH in attr: chanw = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_CHANNEL_WIDTH]) sys.stdout.write(", width: %s" % nl80211.nl80211_chan_width2str[chanw]) if nl80211.NL80211_ATTR_CENTER_FREQ1 in attr: sys.stdout.write(", center1: %d MHz" % nl.nla_get_u32(attr[nl80211.NL80211_ATTR_CENTER_FREQ1])) if nl80211.NL80211_ATTR_CENTER_FREQ2 in attr: sys.stdout.write(", center2: %d MHz" % nl.nla_get_u32(attr[nl80211.NL80211_ATTR_CENTER_FREQ2])) elif nl80211.NL80211_ATTR_WIPHY_CHANNEL_TYPE in attr: channel_type = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_WIPHY_CHANNEL_TYPE]) sys.stdout.write(" %s" % nl80211.nl80211_channel_type2str(channel_type)); sys.stdout.write("\n"); return nl.NL_SKIP; except Exception as e: (t,v,tb) = sys.exc_info() print v.message traceback.print_tb(tb) def error_handler(err, a): a.done = err.error return nl.NL_STOP def finish_handler(m, a): return nl.NL_SKIP def ack_handler(m, a): a.done = 0 return nl.NL_STOP try: cbd = test_class() tx_cb = nl.nl_cb_alloc(nl.NL_CB_DEFAULT) rx_cb = nl.nl_cb_clone(tx_cb) s = nl.nl_socket_alloc_cb(tx_cb) nl.py_nl_cb_err(rx_cb, nl.NL_CB_CUSTOM, error_handler, cbd); nl.py_nl_cb_set(rx_cb, nl.NL_CB_FINISH, nl.NL_CB_CUSTOM, finish_handler, cbd); nl.py_nl_cb_set(rx_cb, nl.NL_CB_ACK, nl.NL_CB_CUSTOM, ack_handler, cbd); nl.py_nl_cb_set(rx_cb, nl.NL_CB_VALID, nl.NL_CB_CUSTOM, msg_handler, cbd); genl.genl_connect(s) family = genl.genl_ctrl_resolve(s, 'nl80211') m = nl.nlmsg_alloc() genl.genlmsg_put(m, 0, 0, family, 0, 0, nl80211.NL80211_CMD_GET_INTERFACE, 0) nl.nla_put_u32(m, nl80211.NL80211_ATTR_IFINDEX, nl.if_nametoindex('wlan0')) err = nl.nl_send_auto_complete(s, m); if err < 0: nl.nlmsg_free(msg) while cbd.done > 0 and not err < 0: err = nl.nl_recvmsgs(s, rx_cb) except Exception as e: (t, v, tb) = sys.exc_info() print v.message traceback.print_tb(tb) libnl-3.2.29/python/examples/Makefile.in0000644000175000017500000003020013031473644015034 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = python/examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ iface.py \ nl80211.py \ wiphy.py all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python/examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign python/examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/python/examples/wiphy.py0000644000175000017500000001130713023014600014470 00000000000000import netlink.capi as nl import netlink.genl.capi as genl import nl80211 import sys import traceback class test_class: def __init__(self): self.done = 1; def freq_to_ch(freq): if freq == 2484: return 14; if freq < 2484: return (freq - 2407) / 5; # FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) if freq < 45000: return freq/5 - 1000; if freq >= 58320 and freq <= 64800: return (freq - 56160) / 2160; return 0; def handle_freq(attr, pol): e, fattr = nl.py_nla_parse_nested(nl80211.NL80211_FREQUENCY_ATTR_MAX, attr, pol) if nl80211.NL80211_FREQUENCY_ATTR_FREQ in fattr: freq = nl.nla_get_u32(fattr[nl80211.NL80211_FREQUENCY_ATTR_FREQ]) sys.stdout.write("\t\tfreq %d MHz [%d]" % (freq, freq_to_ch(freq))) if nl80211.NL80211_FREQUENCY_ATTR_MAX_TX_POWER in fattr and not (nl80211.NL80211_FREQUENCY_ATTR_DISABLED in fattr): sys.stdout.write(" (%.1f dBm)" % (0.01 * nl.nla_get_u32(fattr[nl80211.NL80211_FREQUENCY_ATTR_MAX_TX_POWER]))) if nl80211.NL80211_FREQUENCY_ATTR_DISABLED in fattr: sys.stdout.write(" (disabled)") sys.stdout.write("\n") def handle_band(attr, fpol): e, battr = nl.py_nla_parse_nested(nl80211.NL80211_BAND_ATTR_MAX, attr, None) print("\tband %d:" % nl.nla_type(attr)) if nl80211.NL80211_BAND_ATTR_FREQS in battr: for fattr in nl.nla_get_nested(battr[nl80211.NL80211_BAND_ATTR_FREQS]): handle_freq(fattr, fpol) def cipher_name(suite): suite_val = '%02x%02x%02x%02x' % tuple(reversed(suite)) if suite_val == '000fac01': return "WEP40 (00-0f-ac:1)" elif suite_val == '000fac05': return "WEP104 (00-0f-ac:5)" elif suite_val == '000fac02': return "TKIP (00-0f-ac:2)" elif suite_val == '000fac04': return "CCMP (00-0f-ac:4)" elif suite_val == '000fac06': return "CMAC (00-0f-ac:6)" elif suite_val == '000fac08': return "GCMP (00-0f-ac:8)" elif suite_val == '00147201': return "WPI-SMS4 (00-14-72:1)" else: return suite_val def msg_handler(m, a): try: e, attr = genl.py_genlmsg_parse(nl.nlmsg_hdr(m), 0, nl80211.NL80211_ATTR_MAX, None) if nl80211.NL80211_ATTR_WIPHY_NAME in attr: print('wiphy %s' % nl.nla_get_string(attr[nl80211.NL80211_ATTR_WIPHY_NAME])) if nl80211.NL80211_ATTR_WIPHY_BANDS in attr: fpol = nl.nla_policy_array(nl80211.NL80211_FREQUENCY_ATTR_MAX + 1) fpol[nl80211.NL80211_FREQUENCY_ATTR_FREQ].type = nl.NLA_U32 fpol[nl80211.NL80211_FREQUENCY_ATTR_DISABLED].type = nl.NLA_FLAG fpol[nl80211.NL80211_FREQUENCY_ATTR_PASSIVE_SCAN].type = nl.NLA_FLAG fpol[nl80211.NL80211_FREQUENCY_ATTR_NO_IBSS].type = nl.NLA_FLAG fpol[nl80211.NL80211_FREQUENCY_ATTR_RADAR].type = nl.NLA_FLAG fpol[nl80211.NL80211_FREQUENCY_ATTR_MAX_TX_POWER].type = nl.NLA_U32 nattrs = nl.nla_get_nested(attr[nl80211.NL80211_ATTR_WIPHY_BANDS]) for nattr in nattrs: handle_band(nattr, fpol) if nl80211.NL80211_ATTR_CIPHER_SUITES in attr: ciphers = nl.nla_data(attr[nl80211.NL80211_ATTR_CIPHER_SUITES]) num = len(ciphers) / 4 if num > 0: print("\tSupported Ciphers:"); for i in range(0, num, 4): print("\t\t* %s" % cipher_name(ciphers[i:i+4])) if nl80211.NL80211_ATTR_SUPPORTED_IFTYPES in attr: print("\tSupported interface modes:") ifattr = nl.nla_get_nested(attr[nl80211.NL80211_ATTR_SUPPORTED_IFTYPES]) for nl_mode in ifattr: print("\t\t* %s" % nl80211.nl80211_iftype2str[nl.nla_type(nl_mode)]) if nl80211.NL80211_ATTR_SOFTWARE_IFTYPES in attr: print("\tsoftware interface modes (can always be added):") ifattr = nl.nla_get_nested(attr[nl80211.NL80211_ATTR_SOFTWARE_IFTYPES]) for nl_mode in ifattr: print("\t\t* %s" % nl80211.nl80211_iftype2str[nl.nla_type(nl_mode)]) return nl.NL_SKIP except Exception as e: (t,v,tb) = sys.exc_info() print v.message traceback.print_tb(tb) def error_handler(err, a): a.done = err.error return nl.NL_STOP def finish_handler(m, a): return nl.NL_SKIP def ack_handler(m, a): a.done = 0 return nl.NL_STOP try: cbd = test_class() tx_cb = nl.nl_cb_alloc(nl.NL_CB_DEFAULT) rx_cb = nl.nl_cb_clone(tx_cb) s = nl.nl_socket_alloc_cb(tx_cb) nl.py_nl_cb_err(rx_cb, nl.NL_CB_CUSTOM, error_handler, cbd); nl.py_nl_cb_set(rx_cb, nl.NL_CB_FINISH, nl.NL_CB_CUSTOM, finish_handler, cbd); nl.py_nl_cb_set(rx_cb, nl.NL_CB_ACK, nl.NL_CB_CUSTOM, ack_handler, cbd); nl.py_nl_cb_set(rx_cb, nl.NL_CB_VALID, nl.NL_CB_CUSTOM, msg_handler, cbd); genl.genl_connect(s) family = genl.genl_ctrl_resolve(s, 'nl80211') m = nl.nlmsg_alloc() genl.genlmsg_put(m, 0, 0, family, 0, 0, nl80211.NL80211_CMD_GET_WIPHY, 0) nl.nla_put_u32(m, nl80211.NL80211_ATTR_WIPHY, 7) err = nl.nl_send_auto_complete(s, m); if err < 0: nl.nlmsg_free(msg) while cbd.done > 0 and not err < 0: err = nl.nl_recvmsgs(s, rx_cb) except Exception as e: (t, v, tb) = sys.exc_info() print v.message traceback.print_tb(tb) libnl-3.2.29/python/examples/nl80211.py0000644000175000017500000020725013023014600014341 00000000000000########################################################### # file: nl80211.py # --------------------------------------------------------- # This file is generated using extract.py using pycparser ########################################################### NL80211_GENL_FAMILY = 'nl80211' NL80211_CMD_UNSPEC = 0 NL80211_CMD_GET_WIPHY = 1 NL80211_CMD_SET_WIPHY = 2 NL80211_CMD_NEW_WIPHY = 3 NL80211_CMD_DEL_WIPHY = 4 NL80211_CMD_GET_INTERFACE = 5 NL80211_CMD_SET_INTERFACE = 6 NL80211_CMD_NEW_INTERFACE = 7 NL80211_CMD_DEL_INTERFACE = 8 NL80211_CMD_GET_KEY = 9 NL80211_CMD_SET_KEY = 10 NL80211_CMD_NEW_KEY = 11 NL80211_CMD_DEL_KEY = 12 NL80211_CMD_GET_BEACON = 13 NL80211_CMD_SET_BEACON = 14 NL80211_CMD_START_AP = 15 NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP NL80211_CMD_STOP_AP = 16 NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP NL80211_CMD_GET_STATION = 17 NL80211_CMD_SET_STATION = 18 NL80211_CMD_NEW_STATION = 19 NL80211_CMD_DEL_STATION = 20 NL80211_CMD_GET_MPATH = 21 NL80211_CMD_SET_MPATH = 22 NL80211_CMD_NEW_MPATH = 23 NL80211_CMD_DEL_MPATH = 24 NL80211_CMD_SET_BSS = 25 NL80211_CMD_SET_REG = 26 NL80211_CMD_REQ_SET_REG = 27 NL80211_CMD_GET_MESH_CONFIG = 28 NL80211_CMD_SET_MESH_CONFIG = 29 NL80211_CMD_SET_MGMT_EXTRA_IE = 30 NL80211_CMD_GET_REG = 31 NL80211_CMD_GET_SCAN = 32 NL80211_CMD_TRIGGER_SCAN = 33 NL80211_CMD_NEW_SCAN_RESULTS = 34 NL80211_CMD_SCAN_ABORTED = 35 NL80211_CMD_REG_CHANGE = 36 NL80211_CMD_AUTHENTICATE = 37 NL80211_CMD_ASSOCIATE = 38 NL80211_CMD_DEAUTHENTICATE = 39 NL80211_CMD_DISASSOCIATE = 40 NL80211_CMD_MICHAEL_MIC_FAILURE = 41 NL80211_CMD_REG_BEACON_HINT = 42 NL80211_CMD_JOIN_IBSS = 43 NL80211_CMD_LEAVE_IBSS = 44 NL80211_CMD_TESTMODE = 45 NL80211_CMD_CONNECT = 46 NL80211_CMD_ROAM = 47 NL80211_CMD_DISCONNECT = 48 NL80211_CMD_SET_WIPHY_NETNS = 49 NL80211_CMD_GET_SURVEY = 50 NL80211_CMD_NEW_SURVEY_RESULTS = 51 NL80211_CMD_SET_PMKSA = 52 NL80211_CMD_DEL_PMKSA = 53 NL80211_CMD_FLUSH_PMKSA = 54 NL80211_CMD_REMAIN_ON_CHANNEL = 55 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL = 56 NL80211_CMD_SET_TX_BITRATE_MASK = 57 NL80211_CMD_REGISTER_FRAME = 58 NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME NL80211_CMD_FRAME = 59 NL80211_CMD_ACTION = NL80211_CMD_FRAME NL80211_CMD_FRAME_TX_STATUS = 60 NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS NL80211_CMD_SET_POWER_SAVE = 61 NL80211_CMD_GET_POWER_SAVE = 62 NL80211_CMD_SET_CQM = 63 NL80211_CMD_NOTIFY_CQM = 64 NL80211_CMD_SET_CHANNEL = 65 NL80211_CMD_SET_WDS_PEER = 66 NL80211_CMD_FRAME_WAIT_CANCEL = 67 NL80211_CMD_JOIN_MESH = 68 NL80211_CMD_LEAVE_MESH = 69 NL80211_CMD_UNPROT_DEAUTHENTICATE = 70 NL80211_CMD_UNPROT_DISASSOCIATE = 71 NL80211_CMD_NEW_PEER_CANDIDATE = 72 NL80211_CMD_GET_WOWLAN = 73 NL80211_CMD_SET_WOWLAN = 74 NL80211_CMD_START_SCHED_SCAN = 75 NL80211_CMD_STOP_SCHED_SCAN = 76 NL80211_CMD_SCHED_SCAN_RESULTS = 77 NL80211_CMD_SCHED_SCAN_STOPPED = 78 NL80211_CMD_SET_REKEY_OFFLOAD = 79 NL80211_CMD_PMKSA_CANDIDATE = 80 NL80211_CMD_TDLS_OPER = 81 NL80211_CMD_TDLS_MGMT = 82 NL80211_CMD_UNEXPECTED_FRAME = 83 NL80211_CMD_PROBE_CLIENT = 84 NL80211_CMD_REGISTER_BEACONS = 85 NL80211_CMD_UNEXPECTED_4ADDR_FRAME = 86 NL80211_CMD_SET_NOACK_MAP = 87 NL80211_CMD_CH_SWITCH_NOTIFY = 88 NL80211_CMD_START_P2P_DEVICE = 89 NL80211_CMD_STOP_P2P_DEVICE = 90 NL80211_CMD_CONN_FAILED = 91 NL80211_CMD_SET_MCAST_RATE = 92 NL80211_CMD_SET_MAC_ACL = 93 NL80211_CMD_RADAR_DETECT = 94 NL80211_CMD_GET_PROTOCOL_FEATURES = 95 NL80211_CMD_UPDATE_FT_IES = 96 NL80211_CMD_FT_EVENT = 97 NL80211_CMD_CRIT_PROTOCOL_START = 98 NL80211_CMD_CRIT_PROTOCOL_STOP = 99 __NL80211_CMD_AFTER_LAST = 100 NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 NL80211_ATTR_UNSPEC = 0 NL80211_ATTR_WIPHY = 1 NL80211_ATTR_WIPHY_NAME = 2 NL80211_ATTR_IFINDEX = 3 NL80211_ATTR_IFNAME = 4 NL80211_ATTR_IFTYPE = 5 NL80211_ATTR_MAC = 6 NL80211_ATTR_KEY_DATA = 7 NL80211_ATTR_KEY_IDX = 8 NL80211_ATTR_KEY_CIPHER = 9 NL80211_ATTR_KEY_SEQ = 10 NL80211_ATTR_KEY_DEFAULT = 11 NL80211_ATTR_BEACON_INTERVAL = 12 NL80211_ATTR_DTIM_PERIOD = 13 NL80211_ATTR_BEACON_HEAD = 14 NL80211_ATTR_BEACON_TAIL = 15 NL80211_ATTR_STA_AID = 16 NL80211_ATTR_STA_FLAGS = 17 NL80211_ATTR_STA_LISTEN_INTERVAL = 18 NL80211_ATTR_STA_SUPPORTED_RATES = 19 NL80211_ATTR_STA_VLAN = 20 NL80211_ATTR_STA_INFO = 21 NL80211_ATTR_WIPHY_BANDS = 22 NL80211_ATTR_MNTR_FLAGS = 23 NL80211_ATTR_MESH_ID = 24 NL80211_ATTR_STA_PLINK_ACTION = 25 NL80211_ATTR_MPATH_NEXT_HOP = 26 NL80211_ATTR_MPATH_INFO = 27 NL80211_ATTR_BSS_CTS_PROT = 28 NL80211_ATTR_BSS_SHORT_PREAMBLE = 29 NL80211_ATTR_BSS_SHORT_SLOT_TIME = 30 NL80211_ATTR_HT_CAPABILITY = 31 NL80211_ATTR_SUPPORTED_IFTYPES = 32 NL80211_ATTR_REG_ALPHA2 = 33 NL80211_ATTR_REG_RULES = 34 NL80211_ATTR_MESH_CONFIG = 35 NL80211_ATTR_BSS_BASIC_RATES = 36 NL80211_ATTR_WIPHY_TXQ_PARAMS = 37 NL80211_ATTR_WIPHY_FREQ = 38 NL80211_ATTR_WIPHY_CHANNEL_TYPE = 39 NL80211_ATTR_KEY_DEFAULT_MGMT = 40 NL80211_ATTR_MGMT_SUBTYPE = 41 NL80211_ATTR_IE = 42 NL80211_ATTR_MAX_NUM_SCAN_SSIDS = 43 NL80211_ATTR_SCAN_FREQUENCIES = 44 NL80211_ATTR_SCAN_SSIDS = 45 NL80211_ATTR_GENERATION = 46 NL80211_ATTR_BSS = 47 NL80211_ATTR_REG_INITIATOR = 48 NL80211_ATTR_REG_TYPE = 49 NL80211_ATTR_SUPPORTED_COMMANDS = 50 NL80211_ATTR_FRAME = 51 NL80211_ATTR_SSID = 52 NL80211_ATTR_AUTH_TYPE = 53 NL80211_ATTR_REASON_CODE = 54 NL80211_ATTR_KEY_TYPE = 55 NL80211_ATTR_MAX_SCAN_IE_LEN = 56 NL80211_ATTR_CIPHER_SUITES = 57 NL80211_ATTR_FREQ_BEFORE = 58 NL80211_ATTR_FREQ_AFTER = 59 NL80211_ATTR_FREQ_FIXED = 60 NL80211_ATTR_WIPHY_RETRY_SHORT = 61 NL80211_ATTR_WIPHY_RETRY_LONG = 62 NL80211_ATTR_WIPHY_FRAG_THRESHOLD = 63 NL80211_ATTR_WIPHY_RTS_THRESHOLD = 64 NL80211_ATTR_TIMED_OUT = 65 NL80211_ATTR_USE_MFP = 66 NL80211_ATTR_STA_FLAGS2 = 67 NL80211_ATTR_CONTROL_PORT = 68 NL80211_ATTR_TESTDATA = 69 NL80211_ATTR_PRIVACY = 70 NL80211_ATTR_DISCONNECTED_BY_AP = 71 NL80211_ATTR_STATUS_CODE = 72 NL80211_ATTR_CIPHER_SUITES_PAIRWISE = 73 NL80211_ATTR_CIPHER_SUITE_GROUP = 74 NL80211_ATTR_WPA_VERSIONS = 75 NL80211_ATTR_AKM_SUITES = 76 NL80211_ATTR_REQ_IE = 77 NL80211_ATTR_RESP_IE = 78 NL80211_ATTR_PREV_BSSID = 79 NL80211_ATTR_KEY = 80 NL80211_ATTR_KEYS = 81 NL80211_ATTR_PID = 82 NL80211_ATTR_4ADDR = 83 NL80211_ATTR_SURVEY_INFO = 84 NL80211_ATTR_PMKID = 85 NL80211_ATTR_MAX_NUM_PMKIDS = 86 NL80211_ATTR_DURATION = 87 NL80211_ATTR_COOKIE = 88 NL80211_ATTR_WIPHY_COVERAGE_CLASS = 89 NL80211_ATTR_TX_RATES = 90 NL80211_ATTR_FRAME_MATCH = 91 NL80211_ATTR_ACK = 92 NL80211_ATTR_PS_STATE = 93 NL80211_ATTR_CQM = 94 NL80211_ATTR_LOCAL_STATE_CHANGE = 95 NL80211_ATTR_AP_ISOLATE = 96 NL80211_ATTR_WIPHY_TX_POWER_SETTING = 97 NL80211_ATTR_WIPHY_TX_POWER_LEVEL = 98 NL80211_ATTR_TX_FRAME_TYPES = 99 NL80211_ATTR_RX_FRAME_TYPES = 100 NL80211_ATTR_FRAME_TYPE = 101 NL80211_ATTR_CONTROL_PORT_ETHERTYPE = 102 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT = 103 NL80211_ATTR_SUPPORT_IBSS_RSN = 104 NL80211_ATTR_WIPHY_ANTENNA_TX = 105 NL80211_ATTR_WIPHY_ANTENNA_RX = 106 NL80211_ATTR_MCAST_RATE = 107 NL80211_ATTR_OFFCHANNEL_TX_OK = 108 NL80211_ATTR_BSS_HT_OPMODE = 109 NL80211_ATTR_KEY_DEFAULT_TYPES = 110 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION = 111 NL80211_ATTR_MESH_SETUP = 112 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX = 113 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX = 114 NL80211_ATTR_SUPPORT_MESH_AUTH = 115 NL80211_ATTR_STA_PLINK_STATE = 116 NL80211_ATTR_WOWLAN_TRIGGERS = 117 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED = 118 NL80211_ATTR_SCHED_SCAN_INTERVAL = 119 NL80211_ATTR_INTERFACE_COMBINATIONS = 120 NL80211_ATTR_SOFTWARE_IFTYPES = 121 NL80211_ATTR_REKEY_DATA = 122 NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS = 123 NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN = 124 NL80211_ATTR_SCAN_SUPP_RATES = 125 NL80211_ATTR_HIDDEN_SSID = 126 NL80211_ATTR_IE_PROBE_RESP = 127 NL80211_ATTR_IE_ASSOC_RESP = 128 NL80211_ATTR_STA_WME = 129 NL80211_ATTR_SUPPORT_AP_UAPSD = 130 NL80211_ATTR_ROAM_SUPPORT = 131 NL80211_ATTR_SCHED_SCAN_MATCH = 132 NL80211_ATTR_MAX_MATCH_SETS = 133 NL80211_ATTR_PMKSA_CANDIDATE = 134 NL80211_ATTR_TX_NO_CCK_RATE = 135 NL80211_ATTR_TDLS_ACTION = 136 NL80211_ATTR_TDLS_DIALOG_TOKEN = 137 NL80211_ATTR_TDLS_OPERATION = 138 NL80211_ATTR_TDLS_SUPPORT = 139 NL80211_ATTR_TDLS_EXTERNAL_SETUP = 140 NL80211_ATTR_DEVICE_AP_SME = 141 NL80211_ATTR_DONT_WAIT_FOR_ACK = 142 NL80211_ATTR_FEATURE_FLAGS = 143 NL80211_ATTR_PROBE_RESP_OFFLOAD = 144 NL80211_ATTR_PROBE_RESP = 145 NL80211_ATTR_DFS_REGION = 146 NL80211_ATTR_DISABLE_HT = 147 NL80211_ATTR_HT_CAPABILITY_MASK = 148 NL80211_ATTR_NOACK_MAP = 149 NL80211_ATTR_INACTIVITY_TIMEOUT = 150 NL80211_ATTR_RX_SIGNAL_DBM = 151 NL80211_ATTR_BG_SCAN_PERIOD = 152 NL80211_ATTR_WDEV = 153 NL80211_ATTR_USER_REG_HINT_TYPE = 154 NL80211_ATTR_CONN_FAILED_REASON = 155 NL80211_ATTR_SAE_DATA = 156 NL80211_ATTR_VHT_CAPABILITY = 157 NL80211_ATTR_SCAN_FLAGS = 158 NL80211_ATTR_CHANNEL_WIDTH = 159 NL80211_ATTR_CENTER_FREQ1 = 160 NL80211_ATTR_CENTER_FREQ2 = 161 NL80211_ATTR_P2P_CTWINDOW = 162 NL80211_ATTR_P2P_OPPPS = 163 NL80211_ATTR_LOCAL_MESH_POWER_MODE = 164 NL80211_ATTR_ACL_POLICY = 165 NL80211_ATTR_MAC_ADDRS = 166 NL80211_ATTR_MAC_ACL_MAX = 167 NL80211_ATTR_RADAR_EVENT = 168 NL80211_ATTR_EXT_CAPA = 169 NL80211_ATTR_EXT_CAPA_MASK = 170 NL80211_ATTR_STA_CAPABILITY = 171 NL80211_ATTR_STA_EXT_CAPABILITY = 172 NL80211_ATTR_PROTOCOL_FEATURES = 173 NL80211_ATTR_SPLIT_WIPHY_DUMP = 174 NL80211_ATTR_DISABLE_VHT = 175 NL80211_ATTR_VHT_CAPABILITY_MASK = 176 NL80211_ATTR_MDID = 177 NL80211_ATTR_IE_RIC = 178 NL80211_ATTR_CRIT_PROT_ID = 179 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 180 NL80211_ATTR_PEER_AID = 181 __NL80211_ATTR_AFTER_LAST = 182 NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 NL80211_IFTYPE_UNSPECIFIED = 0 NL80211_IFTYPE_ADHOC = 1 NL80211_IFTYPE_STATION = 2 NL80211_IFTYPE_AP = 3 NL80211_IFTYPE_AP_VLAN = 4 NL80211_IFTYPE_WDS = 5 NL80211_IFTYPE_MONITOR = 6 NL80211_IFTYPE_MESH_POINT = 7 NL80211_IFTYPE_P2P_CLIENT = 8 NL80211_IFTYPE_P2P_GO = 9 NL80211_IFTYPE_P2P_DEVICE = 10 NUM_NL80211_IFTYPES = 11 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 __NL80211_STA_FLAG_INVALID = 0 NL80211_STA_FLAG_AUTHORIZED = 1 NL80211_STA_FLAG_SHORT_PREAMBLE = 2 NL80211_STA_FLAG_WME = 3 NL80211_STA_FLAG_MFP = 4 NL80211_STA_FLAG_AUTHENTICATED = 5 NL80211_STA_FLAG_TDLS_PEER = 6 NL80211_STA_FLAG_ASSOCIATED = 7 __NL80211_STA_FLAG_AFTER_LAST = 8 NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 __NL80211_RATE_INFO_INVALID = 0 NL80211_RATE_INFO_BITRATE = 1 NL80211_RATE_INFO_MCS = 2 NL80211_RATE_INFO_40_MHZ_WIDTH = 3 NL80211_RATE_INFO_SHORT_GI = 4 NL80211_RATE_INFO_BITRATE32 = 5 NL80211_RATE_INFO_VHT_MCS = 6 NL80211_RATE_INFO_VHT_NSS = 7 NL80211_RATE_INFO_80_MHZ_WIDTH = 8 NL80211_RATE_INFO_80P80_MHZ_WIDTH = 9 NL80211_RATE_INFO_160_MHZ_WIDTH = 10 __NL80211_RATE_INFO_AFTER_LAST = 11 NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 __NL80211_STA_BSS_PARAM_INVALID = 0 NL80211_STA_BSS_PARAM_CTS_PROT = 1 NL80211_STA_BSS_PARAM_SHORT_PREAMBLE = 2 NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME = 3 NL80211_STA_BSS_PARAM_DTIM_PERIOD = 4 NL80211_STA_BSS_PARAM_BEACON_INTERVAL = 5 __NL80211_STA_BSS_PARAM_AFTER_LAST = 6 NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1 __NL80211_STA_INFO_INVALID = 0 NL80211_STA_INFO_INACTIVE_TIME = 1 NL80211_STA_INFO_RX_BYTES = 2 NL80211_STA_INFO_TX_BYTES = 3 NL80211_STA_INFO_LLID = 4 NL80211_STA_INFO_PLID = 5 NL80211_STA_INFO_PLINK_STATE = 6 NL80211_STA_INFO_SIGNAL = 7 NL80211_STA_INFO_TX_BITRATE = 8 NL80211_STA_INFO_RX_PACKETS = 9 NL80211_STA_INFO_TX_PACKETS = 10 NL80211_STA_INFO_TX_RETRIES = 11 NL80211_STA_INFO_TX_FAILED = 12 NL80211_STA_INFO_SIGNAL_AVG = 13 NL80211_STA_INFO_RX_BITRATE = 14 NL80211_STA_INFO_BSS_PARAM = 15 NL80211_STA_INFO_CONNECTED_TIME = 16 NL80211_STA_INFO_STA_FLAGS = 17 NL80211_STA_INFO_BEACON_LOSS = 18 NL80211_STA_INFO_T_OFFSET = 19 NL80211_STA_INFO_LOCAL_PM = 20 NL80211_STA_INFO_PEER_PM = 21 NL80211_STA_INFO_NONPEER_PM = 22 NL80211_STA_INFO_RX_BYTES64 = 23 NL80211_STA_INFO_TX_BYTES64 = 24 NL80211_STA_INFO_CHAIN_SIGNAL = 25 NL80211_STA_INFO_CHAIN_SIGNAL_AVG = 26 __NL80211_STA_INFO_AFTER_LAST = 27 NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 NL80211_MPATH_FLAG_ACTIVE = 1 << 0 NL80211_MPATH_FLAG_RESOLVING = 1 << 1 NL80211_MPATH_FLAG_SN_VALID = 1 << 2 NL80211_MPATH_FLAG_FIXED = 1 << 3 NL80211_MPATH_FLAG_RESOLVED = 1 << 4 __NL80211_MPATH_INFO_INVALID = 0 NL80211_MPATH_INFO_FRAME_QLEN = 1 NL80211_MPATH_INFO_SN = 2 NL80211_MPATH_INFO_METRIC = 3 NL80211_MPATH_INFO_EXPTIME = 4 NL80211_MPATH_INFO_FLAGS = 5 NL80211_MPATH_INFO_DISCOVERY_TIMEOUT = 6 NL80211_MPATH_INFO_DISCOVERY_RETRIES = 7 __NL80211_MPATH_INFO_AFTER_LAST = 8 NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1 __NL80211_BAND_ATTR_INVALID = 0 NL80211_BAND_ATTR_FREQS = 1 NL80211_BAND_ATTR_RATES = 2 NL80211_BAND_ATTR_HT_MCS_SET = 3 NL80211_BAND_ATTR_HT_CAPA = 4 NL80211_BAND_ATTR_HT_AMPDU_FACTOR = 5 NL80211_BAND_ATTR_HT_AMPDU_DENSITY = 6 NL80211_BAND_ATTR_VHT_MCS_SET = 7 NL80211_BAND_ATTR_VHT_CAPA = 8 __NL80211_BAND_ATTR_AFTER_LAST = 9 NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 __NL80211_FREQUENCY_ATTR_INVALID = 0 NL80211_FREQUENCY_ATTR_FREQ = 1 NL80211_FREQUENCY_ATTR_DISABLED = 2 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN = 3 NL80211_FREQUENCY_ATTR_NO_IBSS = 4 NL80211_FREQUENCY_ATTR_RADAR = 5 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 6 NL80211_FREQUENCY_ATTR_DFS_STATE = 7 NL80211_FREQUENCY_ATTR_DFS_TIME = 8 NL80211_FREQUENCY_ATTR_NO_HT40_MINUS = 9 NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 10 NL80211_FREQUENCY_ATTR_NO_80MHZ = 11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 12 __NL80211_FREQUENCY_ATTR_AFTER_LAST = 13 NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1 __NL80211_BITRATE_ATTR_INVALID = 0 NL80211_BITRATE_ATTR_RATE = 1 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE = 2 __NL80211_BITRATE_ATTR_AFTER_LAST = 3 NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1 NL80211_REGDOM_SET_BY_CORE = 0 NL80211_REGDOM_SET_BY_USER = 1 NL80211_REGDOM_SET_BY_DRIVER = 2 NL80211_REGDOM_SET_BY_COUNTRY_IE = 3 NL80211_REGDOM_TYPE_COUNTRY = 0 NL80211_REGDOM_TYPE_WORLD = 1 NL80211_REGDOM_TYPE_CUSTOM_WORLD = 2 NL80211_REGDOM_TYPE_INTERSECTION = 3 __NL80211_REG_RULE_ATTR_INVALID = 0 NL80211_ATTR_REG_RULE_FLAGS = 1 NL80211_ATTR_FREQ_RANGE_START = 2 NL80211_ATTR_FREQ_RANGE_END = 3 NL80211_ATTR_FREQ_RANGE_MAX_BW = 4 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN = 5 NL80211_ATTR_POWER_RULE_MAX_EIRP = 6 __NL80211_REG_RULE_ATTR_AFTER_LAST = 7 NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID = 0 NL80211_SCHED_SCAN_MATCH_ATTR_SSID = 1 NL80211_SCHED_SCAN_MATCH_ATTR_RSSI = 2 __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST = 3 NL80211_SCHED_SCAN_MATCH_ATTR_MAX = __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 NL80211_RRF_NO_OFDM = 1 << 0 NL80211_RRF_NO_CCK = 1 << 1 NL80211_RRF_NO_INDOOR = 1 << 2 NL80211_RRF_NO_OUTDOOR = 1 << 3 NL80211_RRF_DFS = 1 << 4 NL80211_RRF_PTP_ONLY = 1 << 5 NL80211_RRF_PTMP_ONLY = 1 << 6 NL80211_RRF_PASSIVE_SCAN = 1 << 7 NL80211_RRF_NO_IBSS = 1 << 8 NL80211_DFS_UNSET = 0 NL80211_DFS_FCC = 1 NL80211_DFS_ETSI = 2 NL80211_DFS_JP = 3 NL80211_USER_REG_HINT_USER = 0 NL80211_USER_REG_HINT_CELL_BASE = 1 __NL80211_SURVEY_INFO_INVALID = 0 NL80211_SURVEY_INFO_FREQUENCY = 1 NL80211_SURVEY_INFO_NOISE = 2 NL80211_SURVEY_INFO_IN_USE = 3 NL80211_SURVEY_INFO_CHANNEL_TIME = 4 NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY = 5 NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 6 NL80211_SURVEY_INFO_CHANNEL_TIME_RX = 7 NL80211_SURVEY_INFO_CHANNEL_TIME_TX = 8 __NL80211_SURVEY_INFO_AFTER_LAST = 9 NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 __NL80211_MNTR_FLAG_INVALID = 0 NL80211_MNTR_FLAG_FCSFAIL = 1 NL80211_MNTR_FLAG_PLCPFAIL = 2 NL80211_MNTR_FLAG_CONTROL = 3 NL80211_MNTR_FLAG_OTHER_BSS = 4 NL80211_MNTR_FLAG_COOK_FRAMES = 5 NL80211_MNTR_FLAG_ACTIVE = 6 __NL80211_MNTR_FLAG_AFTER_LAST = 7 NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1 NL80211_MESH_POWER_UNKNOWN = 0 NL80211_MESH_POWER_ACTIVE = 1 NL80211_MESH_POWER_LIGHT_SLEEP = 2 NL80211_MESH_POWER_DEEP_SLEEP = 3 __NL80211_MESH_POWER_AFTER_LAST = 4 NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1 __NL80211_MESHCONF_INVALID = 0 NL80211_MESHCONF_RETRY_TIMEOUT = 1 NL80211_MESHCONF_CONFIRM_TIMEOUT = 2 NL80211_MESHCONF_HOLDING_TIMEOUT = 3 NL80211_MESHCONF_MAX_PEER_LINKS = 4 NL80211_MESHCONF_MAX_RETRIES = 5 NL80211_MESHCONF_TTL = 6 NL80211_MESHCONF_AUTO_OPEN_PLINKS = 7 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES = 8 NL80211_MESHCONF_PATH_REFRESH_TIME = 9 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT = 10 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT = 11 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL = 12 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME = 13 NL80211_MESHCONF_HWMP_ROOTMODE = 14 NL80211_MESHCONF_ELEMENT_TTL = 15 NL80211_MESHCONF_HWMP_RANN_INTERVAL = 16 NL80211_MESHCONF_GATE_ANNOUNCEMENTS = 17 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL = 18 NL80211_MESHCONF_FORWARDING = 19 NL80211_MESHCONF_RSSI_THRESHOLD = 20 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR = 21 NL80211_MESHCONF_HT_OPMODE = 22 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT = 23 NL80211_MESHCONF_HWMP_ROOT_INTERVAL = 24 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL = 25 NL80211_MESHCONF_POWER_MODE = 26 NL80211_MESHCONF_AWAKE_WINDOW = 27 NL80211_MESHCONF_PLINK_TIMEOUT = 28 __NL80211_MESHCONF_ATTR_AFTER_LAST = 29 NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1 __NL80211_MESH_SETUP_INVALID = 0 NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL = 1 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC = 2 NL80211_MESH_SETUP_IE = 3 NL80211_MESH_SETUP_USERSPACE_AUTH = 4 NL80211_MESH_SETUP_USERSPACE_AMPE = 5 NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC = 6 NL80211_MESH_SETUP_USERSPACE_MPM = 7 NL80211_MESH_SETUP_AUTH_PROTOCOL = 8 __NL80211_MESH_SETUP_ATTR_AFTER_LAST = 9 NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1 __NL80211_TXQ_ATTR_INVALID = 0 NL80211_TXQ_ATTR_AC = 1 NL80211_TXQ_ATTR_TXOP = 2 NL80211_TXQ_ATTR_CWMIN = 3 NL80211_TXQ_ATTR_CWMAX = 4 NL80211_TXQ_ATTR_AIFS = 5 __NL80211_TXQ_ATTR_AFTER_LAST = 6 NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1 NL80211_AC_VO = 0 NL80211_AC_VI = 1 NL80211_AC_BE = 2 NL80211_AC_BK = 3 NL80211_NUM_ACS = 4 NL80211_CHAN_NO_HT = 0 NL80211_CHAN_HT20 = 1 NL80211_CHAN_HT40MINUS = 2 NL80211_CHAN_HT40PLUS = 3 NL80211_CHAN_WIDTH_20_NOHT = 0 NL80211_CHAN_WIDTH_20 = 1 NL80211_CHAN_WIDTH_40 = 2 NL80211_CHAN_WIDTH_80 = 3 NL80211_CHAN_WIDTH_80P80 = 4 NL80211_CHAN_WIDTH_160 = 5 __NL80211_BSS_INVALID = 0 NL80211_BSS_BSSID = 1 NL80211_BSS_FREQUENCY = 2 NL80211_BSS_TSF = 3 NL80211_BSS_BEACON_INTERVAL = 4 NL80211_BSS_CAPABILITY = 5 NL80211_BSS_INFORMATION_ELEMENTS = 6 NL80211_BSS_SIGNAL_MBM = 7 NL80211_BSS_SIGNAL_UNSPEC = 8 NL80211_BSS_STATUS = 9 NL80211_BSS_SEEN_MS_AGO = 10 NL80211_BSS_BEACON_IES = 11 __NL80211_BSS_AFTER_LAST = 12 NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1 NL80211_BSS_STATUS_AUTHENTICATED = 0 NL80211_BSS_STATUS_ASSOCIATED = 1 NL80211_BSS_STATUS_IBSS_JOINED = 2 NL80211_AUTHTYPE_OPEN_SYSTEM = 0 NL80211_AUTHTYPE_SHARED_KEY = 1 NL80211_AUTHTYPE_FT = 2 NL80211_AUTHTYPE_NETWORK_EAP = 3 NL80211_AUTHTYPE_SAE = 4 __NL80211_AUTHTYPE_NUM = 5 NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1 NL80211_AUTHTYPE_AUTOMATIC = 6 NL80211_KEYTYPE_GROUP = 0 NL80211_KEYTYPE_PAIRWISE = 1 NL80211_KEYTYPE_PEERKEY = 2 NUM_NL80211_KEYTYPES = 3 NL80211_MFP_NO = 0 NL80211_MFP_REQUIRED = 1 NL80211_WPA_VERSION_1 = 1 << 0 NL80211_WPA_VERSION_2 = 1 << 1 __NL80211_KEY_DEFAULT_TYPE_INVALID = 0 NL80211_KEY_DEFAULT_TYPE_UNICAST = 1 NL80211_KEY_DEFAULT_TYPE_MULTICAST = 2 NUM_NL80211_KEY_DEFAULT_TYPES = 3 __NL80211_KEY_INVALID = 0 NL80211_KEY_DATA = 1 NL80211_KEY_IDX = 2 NL80211_KEY_CIPHER = 3 NL80211_KEY_SEQ = 4 NL80211_KEY_DEFAULT = 5 NL80211_KEY_DEFAULT_MGMT = 6 NL80211_KEY_TYPE = 7 NL80211_KEY_DEFAULT_TYPES = 8 __NL80211_KEY_AFTER_LAST = 9 NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1 __NL80211_TXRATE_INVALID = 0 NL80211_TXRATE_LEGACY = 1 NL80211_TXRATE_MCS = 2 __NL80211_TXRATE_AFTER_LAST = 3 NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 NL80211_BAND_2GHZ = 0 NL80211_BAND_5GHZ = 1 NL80211_BAND_60GHZ = 2 NL80211_PS_DISABLED = 0 NL80211_PS_ENABLED = 1 __NL80211_ATTR_CQM_INVALID = 0 NL80211_ATTR_CQM_RSSI_THOLD = 1 NL80211_ATTR_CQM_RSSI_HYST = 2 NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT = 3 NL80211_ATTR_CQM_PKT_LOSS_EVENT = 4 NL80211_ATTR_CQM_TXE_RATE = 5 NL80211_ATTR_CQM_TXE_PKTS = 6 NL80211_ATTR_CQM_TXE_INTVL = 7 __NL80211_ATTR_CQM_AFTER_LAST = 8 NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW = 0 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH = 1 NL80211_CQM_RSSI_BEACON_LOSS_EVENT = 2 NL80211_TX_POWER_AUTOMATIC = 0 NL80211_TX_POWER_LIMITED = 1 NL80211_TX_POWER_FIXED = 2 __NL80211_WOWLAN_PKTPAT_INVALID = 0 NL80211_WOWLAN_PKTPAT_MASK = 1 NL80211_WOWLAN_PKTPAT_PATTERN = 2 NL80211_WOWLAN_PKTPAT_OFFSET = 3 NUM_NL80211_WOWLAN_PKTPAT = 4 MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1 __NL80211_WOWLAN_TRIG_INVALID = 0 NL80211_WOWLAN_TRIG_ANY = 1 NL80211_WOWLAN_TRIG_DISCONNECT = 2 NL80211_WOWLAN_TRIG_MAGIC_PKT = 3 NL80211_WOWLAN_TRIG_PKT_PATTERN = 4 NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED = 5 NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE = 6 NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST = 7 NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE = 8 NL80211_WOWLAN_TRIG_RFKILL_RELEASE = 9 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 = 10 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN = 11 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 = 12 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN = 13 NL80211_WOWLAN_TRIG_TCP_CONNECTION = 14 NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH = 15 NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST = 16 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS = 17 NUM_NL80211_WOWLAN_TRIG = 18 MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 __NL80211_WOWLAN_TCP_INVALID = 0 NL80211_WOWLAN_TCP_SRC_IPV4 = 1 NL80211_WOWLAN_TCP_DST_IPV4 = 2 NL80211_WOWLAN_TCP_DST_MAC = 3 NL80211_WOWLAN_TCP_SRC_PORT = 4 NL80211_WOWLAN_TCP_DST_PORT = 5 NL80211_WOWLAN_TCP_DATA_PAYLOAD = 6 NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ = 7 NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN = 8 NL80211_WOWLAN_TCP_DATA_INTERVAL = 9 NL80211_WOWLAN_TCP_WAKE_PAYLOAD = 10 NL80211_WOWLAN_TCP_WAKE_MASK = 11 NUM_NL80211_WOWLAN_TCP = 12 MAX_NL80211_WOWLAN_TCP = NUM_NL80211_WOWLAN_TCP - 1 NL80211_IFACE_LIMIT_UNSPEC = 0 NL80211_IFACE_LIMIT_MAX = 1 NL80211_IFACE_LIMIT_TYPES = 2 NUM_NL80211_IFACE_LIMIT = 3 MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1 NL80211_IFACE_COMB_UNSPEC = 0 NL80211_IFACE_COMB_LIMITS = 1 NL80211_IFACE_COMB_MAXNUM = 2 NL80211_IFACE_COMB_STA_AP_BI_MATCH = 3 NL80211_IFACE_COMB_NUM_CHANNELS = 4 NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS = 5 NUM_NL80211_IFACE_COMB = 6 MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1 NL80211_PLINK_LISTEN = 0 NL80211_PLINK_OPN_SNT = 1 NL80211_PLINK_OPN_RCVD = 2 NL80211_PLINK_CNF_RCVD = 3 NL80211_PLINK_ESTAB = 4 NL80211_PLINK_HOLDING = 5 NL80211_PLINK_BLOCKED = 6 NUM_NL80211_PLINK_STATES = 7 MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 NL80211_PLINK_ACTION_NO_ACTION = 0 NL80211_PLINK_ACTION_OPEN = 1 NL80211_PLINK_ACTION_BLOCK = 2 NUM_NL80211_PLINK_ACTIONS = 3 __NL80211_REKEY_DATA_INVALID = 0 NL80211_REKEY_DATA_KEK = 1 NL80211_REKEY_DATA_KCK = 2 NL80211_REKEY_DATA_REPLAY_CTR = 3 NUM_NL80211_REKEY_DATA = 4 MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1 NL80211_HIDDEN_SSID_NOT_IN_USE = 0 NL80211_HIDDEN_SSID_ZERO_LEN = 1 NL80211_HIDDEN_SSID_ZERO_CONTENTS = 2 __NL80211_STA_WME_INVALID = 0 NL80211_STA_WME_UAPSD_QUEUES = 1 NL80211_STA_WME_MAX_SP = 2 __NL80211_STA_WME_AFTER_LAST = 3 NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1 __NL80211_PMKSA_CANDIDATE_INVALID = 0 NL80211_PMKSA_CANDIDATE_INDEX = 1 NL80211_PMKSA_CANDIDATE_BSSID = 2 NL80211_PMKSA_CANDIDATE_PREAUTH = 3 NUM_NL80211_PMKSA_CANDIDATE = 4 MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1 NL80211_TDLS_DISCOVERY_REQ = 0 NL80211_TDLS_SETUP = 1 NL80211_TDLS_TEARDOWN = 2 NL80211_TDLS_ENABLE_LINK = 3 NL80211_TDLS_DISABLE_LINK = 4 NL80211_FEATURE_SK_TX_STATUS = 1 << 0 NL80211_FEATURE_HT_IBSS = 1 << 1 NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2 NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3 NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4 NL80211_FEATURE_SAE = 1 << 5 NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6 NL80211_FEATURE_SCAN_FLUSH = 1 << 7 NL80211_FEATURE_AP_SCAN = 1 << 8 NL80211_FEATURE_VIF_TXPOWER = 1 << 9 NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10 NL80211_FEATURE_P2P_GO_CTWIN = 1 << 11 NL80211_FEATURE_P2P_GO_OPPPS = 1 << 12 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14 NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15 NL80211_FEATURE_USERSPACE_MPM = 1 << 16 NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS = 1 << 0 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 = 1 << 1 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P = 1 << 2 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U = 1 << 3 NL80211_CONN_FAIL_MAX_CLIENTS = 0 NL80211_CONN_FAIL_BLOCKED_CLIENT = 1 NL80211_SCAN_FLAG_LOW_PRIORITY = 1 << 0 NL80211_SCAN_FLAG_FLUSH = 1 << 1 NL80211_SCAN_FLAG_AP = 1 << 2 NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED = 0 NL80211_ACL_POLICY_DENY_UNLESS_LISTED = 1 NL80211_RADAR_DETECTED = 0 NL80211_RADAR_CAC_FINISHED = 1 NL80211_RADAR_CAC_ABORTED = 2 NL80211_RADAR_NOP_FINISHED = 3 NL80211_DFS_USABLE = 0 NL80211_DFS_UNAVAILABLE = 1 NL80211_DFS_AVAILABLE = 2 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0 NL80211_CRIT_PROTO_UNSPEC = 0 NL80211_CRIT_PROTO_DHCP = 1 NL80211_CRIT_PROTO_EAPOL = 2 NL80211_CRIT_PROTO_APIPA = 3 NUM_NL80211_CRIT_PROTO = 4 nl80211_commands2str = { NL80211_CMD_UNSPEC: "NL80211_CMD_UNSPEC", NL80211_CMD_GET_WIPHY: "NL80211_CMD_GET_WIPHY", NL80211_CMD_SET_WIPHY: "NL80211_CMD_SET_WIPHY", NL80211_CMD_NEW_WIPHY: "NL80211_CMD_NEW_WIPHY", NL80211_CMD_DEL_WIPHY: "NL80211_CMD_DEL_WIPHY", NL80211_CMD_GET_INTERFACE: "NL80211_CMD_GET_INTERFACE", NL80211_CMD_SET_INTERFACE: "NL80211_CMD_SET_INTERFACE", NL80211_CMD_NEW_INTERFACE: "NL80211_CMD_NEW_INTERFACE", NL80211_CMD_DEL_INTERFACE: "NL80211_CMD_DEL_INTERFACE", NL80211_CMD_GET_KEY: "NL80211_CMD_GET_KEY", NL80211_CMD_SET_KEY: "NL80211_CMD_SET_KEY", NL80211_CMD_NEW_KEY: "NL80211_CMD_NEW_KEY", NL80211_CMD_DEL_KEY: "NL80211_CMD_DEL_KEY", NL80211_CMD_GET_BEACON: "NL80211_CMD_GET_BEACON", NL80211_CMD_SET_BEACON: "NL80211_CMD_SET_BEACON", NL80211_CMD_START_AP: "NL80211_CMD_START_AP", NL80211_CMD_STOP_AP: "NL80211_CMD_STOP_AP", NL80211_CMD_GET_STATION: "NL80211_CMD_GET_STATION", NL80211_CMD_SET_STATION: "NL80211_CMD_SET_STATION", NL80211_CMD_NEW_STATION: "NL80211_CMD_NEW_STATION", NL80211_CMD_DEL_STATION: "NL80211_CMD_DEL_STATION", NL80211_CMD_GET_MPATH: "NL80211_CMD_GET_MPATH", NL80211_CMD_SET_MPATH: "NL80211_CMD_SET_MPATH", NL80211_CMD_NEW_MPATH: "NL80211_CMD_NEW_MPATH", NL80211_CMD_DEL_MPATH: "NL80211_CMD_DEL_MPATH", NL80211_CMD_SET_BSS: "NL80211_CMD_SET_BSS", NL80211_CMD_SET_REG: "NL80211_CMD_SET_REG", NL80211_CMD_REQ_SET_REG: "NL80211_CMD_REQ_SET_REG", NL80211_CMD_GET_MESH_CONFIG: "NL80211_CMD_GET_MESH_CONFIG", NL80211_CMD_SET_MESH_CONFIG: "NL80211_CMD_SET_MESH_CONFIG", NL80211_CMD_SET_MGMT_EXTRA_IE: "NL80211_CMD_SET_MGMT_EXTRA_IE", NL80211_CMD_GET_REG: "NL80211_CMD_GET_REG", NL80211_CMD_GET_SCAN: "NL80211_CMD_GET_SCAN", NL80211_CMD_TRIGGER_SCAN: "NL80211_CMD_TRIGGER_SCAN", NL80211_CMD_NEW_SCAN_RESULTS: "NL80211_CMD_NEW_SCAN_RESULTS", NL80211_CMD_SCAN_ABORTED: "NL80211_CMD_SCAN_ABORTED", NL80211_CMD_REG_CHANGE: "NL80211_CMD_REG_CHANGE", NL80211_CMD_AUTHENTICATE: "NL80211_CMD_AUTHENTICATE", NL80211_CMD_ASSOCIATE: "NL80211_CMD_ASSOCIATE", NL80211_CMD_DEAUTHENTICATE: "NL80211_CMD_DEAUTHENTICATE", NL80211_CMD_DISASSOCIATE: "NL80211_CMD_DISASSOCIATE", NL80211_CMD_MICHAEL_MIC_FAILURE: "NL80211_CMD_MICHAEL_MIC_FAILURE", NL80211_CMD_REG_BEACON_HINT: "NL80211_CMD_REG_BEACON_HINT", NL80211_CMD_JOIN_IBSS: "NL80211_CMD_JOIN_IBSS", NL80211_CMD_LEAVE_IBSS: "NL80211_CMD_LEAVE_IBSS", NL80211_CMD_TESTMODE: "NL80211_CMD_TESTMODE", NL80211_CMD_CONNECT: "NL80211_CMD_CONNECT", NL80211_CMD_ROAM: "NL80211_CMD_ROAM", NL80211_CMD_DISCONNECT: "NL80211_CMD_DISCONNECT", NL80211_CMD_SET_WIPHY_NETNS: "NL80211_CMD_SET_WIPHY_NETNS", NL80211_CMD_GET_SURVEY: "NL80211_CMD_GET_SURVEY", NL80211_CMD_NEW_SURVEY_RESULTS: "NL80211_CMD_NEW_SURVEY_RESULTS", NL80211_CMD_SET_PMKSA: "NL80211_CMD_SET_PMKSA", NL80211_CMD_DEL_PMKSA: "NL80211_CMD_DEL_PMKSA", NL80211_CMD_FLUSH_PMKSA: "NL80211_CMD_FLUSH_PMKSA", NL80211_CMD_REMAIN_ON_CHANNEL: "NL80211_CMD_REMAIN_ON_CHANNEL", NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: "NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL", NL80211_CMD_SET_TX_BITRATE_MASK: "NL80211_CMD_SET_TX_BITRATE_MASK", NL80211_CMD_REGISTER_FRAME: "NL80211_CMD_REGISTER_FRAME", NL80211_CMD_FRAME: "NL80211_CMD_FRAME", NL80211_CMD_FRAME_TX_STATUS: "NL80211_CMD_FRAME_TX_STATUS", NL80211_CMD_SET_POWER_SAVE: "NL80211_CMD_SET_POWER_SAVE", NL80211_CMD_GET_POWER_SAVE: "NL80211_CMD_GET_POWER_SAVE", NL80211_CMD_SET_CQM: "NL80211_CMD_SET_CQM", NL80211_CMD_NOTIFY_CQM: "NL80211_CMD_NOTIFY_CQM", NL80211_CMD_SET_CHANNEL: "NL80211_CMD_SET_CHANNEL", NL80211_CMD_SET_WDS_PEER: "NL80211_CMD_SET_WDS_PEER", NL80211_CMD_FRAME_WAIT_CANCEL: "NL80211_CMD_FRAME_WAIT_CANCEL", NL80211_CMD_JOIN_MESH: "NL80211_CMD_JOIN_MESH", NL80211_CMD_LEAVE_MESH: "NL80211_CMD_LEAVE_MESH", NL80211_CMD_UNPROT_DEAUTHENTICATE: "NL80211_CMD_UNPROT_DEAUTHENTICATE", NL80211_CMD_UNPROT_DISASSOCIATE: "NL80211_CMD_UNPROT_DISASSOCIATE", NL80211_CMD_NEW_PEER_CANDIDATE: "NL80211_CMD_NEW_PEER_CANDIDATE", NL80211_CMD_GET_WOWLAN: "NL80211_CMD_GET_WOWLAN", NL80211_CMD_SET_WOWLAN: "NL80211_CMD_SET_WOWLAN", NL80211_CMD_START_SCHED_SCAN: "NL80211_CMD_START_SCHED_SCAN", NL80211_CMD_STOP_SCHED_SCAN: "NL80211_CMD_STOP_SCHED_SCAN", NL80211_CMD_SCHED_SCAN_RESULTS: "NL80211_CMD_SCHED_SCAN_RESULTS", NL80211_CMD_SCHED_SCAN_STOPPED: "NL80211_CMD_SCHED_SCAN_STOPPED", NL80211_CMD_SET_REKEY_OFFLOAD: "NL80211_CMD_SET_REKEY_OFFLOAD", NL80211_CMD_PMKSA_CANDIDATE: "NL80211_CMD_PMKSA_CANDIDATE", NL80211_CMD_TDLS_OPER: "NL80211_CMD_TDLS_OPER", NL80211_CMD_TDLS_MGMT: "NL80211_CMD_TDLS_MGMT", NL80211_CMD_UNEXPECTED_FRAME: "NL80211_CMD_UNEXPECTED_FRAME", NL80211_CMD_PROBE_CLIENT: "NL80211_CMD_PROBE_CLIENT", NL80211_CMD_REGISTER_BEACONS: "NL80211_CMD_REGISTER_BEACONS", NL80211_CMD_UNEXPECTED_4ADDR_FRAME: "NL80211_CMD_UNEXPECTED_4ADDR_FRAME", NL80211_CMD_SET_NOACK_MAP: "NL80211_CMD_SET_NOACK_MAP", NL80211_CMD_CH_SWITCH_NOTIFY: "NL80211_CMD_CH_SWITCH_NOTIFY", NL80211_CMD_START_P2P_DEVICE: "NL80211_CMD_START_P2P_DEVICE", NL80211_CMD_STOP_P2P_DEVICE: "NL80211_CMD_STOP_P2P_DEVICE", NL80211_CMD_CONN_FAILED: "NL80211_CMD_CONN_FAILED", NL80211_CMD_SET_MCAST_RATE: "NL80211_CMD_SET_MCAST_RATE", NL80211_CMD_SET_MAC_ACL: "NL80211_CMD_SET_MAC_ACL", NL80211_CMD_RADAR_DETECT: "NL80211_CMD_RADAR_DETECT", NL80211_CMD_GET_PROTOCOL_FEATURES: "NL80211_CMD_GET_PROTOCOL_FEATURES", NL80211_CMD_UPDATE_FT_IES: "NL80211_CMD_UPDATE_FT_IES", NL80211_CMD_FT_EVENT: "NL80211_CMD_FT_EVENT", NL80211_CMD_CRIT_PROTOCOL_START: "NL80211_CMD_CRIT_PROTOCOL_START", NL80211_CMD_CRIT_PROTOCOL_STOP: "NL80211_CMD_CRIT_PROTOCOL_STOP", __NL80211_CMD_AFTER_LAST: "__NL80211_CMD_AFTER_LAST", } nl80211_attrs2str = { NL80211_ATTR_UNSPEC: "NL80211_ATTR_UNSPEC", NL80211_ATTR_WIPHY: "NL80211_ATTR_WIPHY", NL80211_ATTR_WIPHY_NAME: "NL80211_ATTR_WIPHY_NAME", NL80211_ATTR_IFINDEX: "NL80211_ATTR_IFINDEX", NL80211_ATTR_IFNAME: "NL80211_ATTR_IFNAME", NL80211_ATTR_IFTYPE: "NL80211_ATTR_IFTYPE", NL80211_ATTR_MAC: "NL80211_ATTR_MAC", NL80211_ATTR_KEY_DATA: "NL80211_ATTR_KEY_DATA", NL80211_ATTR_KEY_IDX: "NL80211_ATTR_KEY_IDX", NL80211_ATTR_KEY_CIPHER: "NL80211_ATTR_KEY_CIPHER", NL80211_ATTR_KEY_SEQ: "NL80211_ATTR_KEY_SEQ", NL80211_ATTR_KEY_DEFAULT: "NL80211_ATTR_KEY_DEFAULT", NL80211_ATTR_BEACON_INTERVAL: "NL80211_ATTR_BEACON_INTERVAL", NL80211_ATTR_DTIM_PERIOD: "NL80211_ATTR_DTIM_PERIOD", NL80211_ATTR_BEACON_HEAD: "NL80211_ATTR_BEACON_HEAD", NL80211_ATTR_BEACON_TAIL: "NL80211_ATTR_BEACON_TAIL", NL80211_ATTR_STA_AID: "NL80211_ATTR_STA_AID", NL80211_ATTR_STA_FLAGS: "NL80211_ATTR_STA_FLAGS", NL80211_ATTR_STA_LISTEN_INTERVAL: "NL80211_ATTR_STA_LISTEN_INTERVAL", NL80211_ATTR_STA_SUPPORTED_RATES: "NL80211_ATTR_STA_SUPPORTED_RATES", NL80211_ATTR_STA_VLAN: "NL80211_ATTR_STA_VLAN", NL80211_ATTR_STA_INFO: "NL80211_ATTR_STA_INFO", NL80211_ATTR_WIPHY_BANDS: "NL80211_ATTR_WIPHY_BANDS", NL80211_ATTR_MNTR_FLAGS: "NL80211_ATTR_MNTR_FLAGS", NL80211_ATTR_MESH_ID: "NL80211_ATTR_MESH_ID", NL80211_ATTR_STA_PLINK_ACTION: "NL80211_ATTR_STA_PLINK_ACTION", NL80211_ATTR_MPATH_NEXT_HOP: "NL80211_ATTR_MPATH_NEXT_HOP", NL80211_ATTR_MPATH_INFO: "NL80211_ATTR_MPATH_INFO", NL80211_ATTR_BSS_CTS_PROT: "NL80211_ATTR_BSS_CTS_PROT", NL80211_ATTR_BSS_SHORT_PREAMBLE: "NL80211_ATTR_BSS_SHORT_PREAMBLE", NL80211_ATTR_BSS_SHORT_SLOT_TIME: "NL80211_ATTR_BSS_SHORT_SLOT_TIME", NL80211_ATTR_HT_CAPABILITY: "NL80211_ATTR_HT_CAPABILITY", NL80211_ATTR_SUPPORTED_IFTYPES: "NL80211_ATTR_SUPPORTED_IFTYPES", NL80211_ATTR_REG_ALPHA2: "NL80211_ATTR_REG_ALPHA2", NL80211_ATTR_REG_RULES: "NL80211_ATTR_REG_RULES", NL80211_ATTR_MESH_CONFIG: "NL80211_ATTR_MESH_CONFIG", NL80211_ATTR_BSS_BASIC_RATES: "NL80211_ATTR_BSS_BASIC_RATES", NL80211_ATTR_WIPHY_TXQ_PARAMS: "NL80211_ATTR_WIPHY_TXQ_PARAMS", NL80211_ATTR_WIPHY_FREQ: "NL80211_ATTR_WIPHY_FREQ", NL80211_ATTR_WIPHY_CHANNEL_TYPE: "NL80211_ATTR_WIPHY_CHANNEL_TYPE", NL80211_ATTR_KEY_DEFAULT_MGMT: "NL80211_ATTR_KEY_DEFAULT_MGMT", NL80211_ATTR_MGMT_SUBTYPE: "NL80211_ATTR_MGMT_SUBTYPE", NL80211_ATTR_IE: "NL80211_ATTR_IE", NL80211_ATTR_MAX_NUM_SCAN_SSIDS: "NL80211_ATTR_MAX_NUM_SCAN_SSIDS", NL80211_ATTR_SCAN_FREQUENCIES: "NL80211_ATTR_SCAN_FREQUENCIES", NL80211_ATTR_SCAN_SSIDS: "NL80211_ATTR_SCAN_SSIDS", NL80211_ATTR_GENERATION: "NL80211_ATTR_GENERATION", NL80211_ATTR_BSS: "NL80211_ATTR_BSS", NL80211_ATTR_REG_INITIATOR: "NL80211_ATTR_REG_INITIATOR", NL80211_ATTR_REG_TYPE: "NL80211_ATTR_REG_TYPE", NL80211_ATTR_SUPPORTED_COMMANDS: "NL80211_ATTR_SUPPORTED_COMMANDS", NL80211_ATTR_FRAME: "NL80211_ATTR_FRAME", NL80211_ATTR_SSID: "NL80211_ATTR_SSID", NL80211_ATTR_AUTH_TYPE: "NL80211_ATTR_AUTH_TYPE", NL80211_ATTR_REASON_CODE: "NL80211_ATTR_REASON_CODE", NL80211_ATTR_KEY_TYPE: "NL80211_ATTR_KEY_TYPE", NL80211_ATTR_MAX_SCAN_IE_LEN: "NL80211_ATTR_MAX_SCAN_IE_LEN", NL80211_ATTR_CIPHER_SUITES: "NL80211_ATTR_CIPHER_SUITES", NL80211_ATTR_FREQ_BEFORE: "NL80211_ATTR_FREQ_BEFORE", NL80211_ATTR_FREQ_AFTER: "NL80211_ATTR_FREQ_AFTER", NL80211_ATTR_FREQ_FIXED: "NL80211_ATTR_FREQ_FIXED", NL80211_ATTR_WIPHY_RETRY_SHORT: "NL80211_ATTR_WIPHY_RETRY_SHORT", NL80211_ATTR_WIPHY_RETRY_LONG: "NL80211_ATTR_WIPHY_RETRY_LONG", NL80211_ATTR_WIPHY_FRAG_THRESHOLD: "NL80211_ATTR_WIPHY_FRAG_THRESHOLD", NL80211_ATTR_WIPHY_RTS_THRESHOLD: "NL80211_ATTR_WIPHY_RTS_THRESHOLD", NL80211_ATTR_TIMED_OUT: "NL80211_ATTR_TIMED_OUT", NL80211_ATTR_USE_MFP: "NL80211_ATTR_USE_MFP", NL80211_ATTR_STA_FLAGS2: "NL80211_ATTR_STA_FLAGS2", NL80211_ATTR_CONTROL_PORT: "NL80211_ATTR_CONTROL_PORT", NL80211_ATTR_TESTDATA: "NL80211_ATTR_TESTDATA", NL80211_ATTR_PRIVACY: "NL80211_ATTR_PRIVACY", NL80211_ATTR_DISCONNECTED_BY_AP: "NL80211_ATTR_DISCONNECTED_BY_AP", NL80211_ATTR_STATUS_CODE: "NL80211_ATTR_STATUS_CODE", NL80211_ATTR_CIPHER_SUITES_PAIRWISE: "NL80211_ATTR_CIPHER_SUITES_PAIRWISE", NL80211_ATTR_CIPHER_SUITE_GROUP: "NL80211_ATTR_CIPHER_SUITE_GROUP", NL80211_ATTR_WPA_VERSIONS: "NL80211_ATTR_WPA_VERSIONS", NL80211_ATTR_AKM_SUITES: "NL80211_ATTR_AKM_SUITES", NL80211_ATTR_REQ_IE: "NL80211_ATTR_REQ_IE", NL80211_ATTR_RESP_IE: "NL80211_ATTR_RESP_IE", NL80211_ATTR_PREV_BSSID: "NL80211_ATTR_PREV_BSSID", NL80211_ATTR_KEY: "NL80211_ATTR_KEY", NL80211_ATTR_KEYS: "NL80211_ATTR_KEYS", NL80211_ATTR_PID: "NL80211_ATTR_PID", NL80211_ATTR_4ADDR: "NL80211_ATTR_4ADDR", NL80211_ATTR_SURVEY_INFO: "NL80211_ATTR_SURVEY_INFO", NL80211_ATTR_PMKID: "NL80211_ATTR_PMKID", NL80211_ATTR_MAX_NUM_PMKIDS: "NL80211_ATTR_MAX_NUM_PMKIDS", NL80211_ATTR_DURATION: "NL80211_ATTR_DURATION", NL80211_ATTR_COOKIE: "NL80211_ATTR_COOKIE", NL80211_ATTR_WIPHY_COVERAGE_CLASS: "NL80211_ATTR_WIPHY_COVERAGE_CLASS", NL80211_ATTR_TX_RATES: "NL80211_ATTR_TX_RATES", NL80211_ATTR_FRAME_MATCH: "NL80211_ATTR_FRAME_MATCH", NL80211_ATTR_ACK: "NL80211_ATTR_ACK", NL80211_ATTR_PS_STATE: "NL80211_ATTR_PS_STATE", NL80211_ATTR_CQM: "NL80211_ATTR_CQM", NL80211_ATTR_LOCAL_STATE_CHANGE: "NL80211_ATTR_LOCAL_STATE_CHANGE", NL80211_ATTR_AP_ISOLATE: "NL80211_ATTR_AP_ISOLATE", NL80211_ATTR_WIPHY_TX_POWER_SETTING: "NL80211_ATTR_WIPHY_TX_POWER_SETTING", NL80211_ATTR_WIPHY_TX_POWER_LEVEL: "NL80211_ATTR_WIPHY_TX_POWER_LEVEL", NL80211_ATTR_TX_FRAME_TYPES: "NL80211_ATTR_TX_FRAME_TYPES", NL80211_ATTR_RX_FRAME_TYPES: "NL80211_ATTR_RX_FRAME_TYPES", NL80211_ATTR_FRAME_TYPE: "NL80211_ATTR_FRAME_TYPE", NL80211_ATTR_CONTROL_PORT_ETHERTYPE: "NL80211_ATTR_CONTROL_PORT_ETHERTYPE", NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: "NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT", NL80211_ATTR_SUPPORT_IBSS_RSN: "NL80211_ATTR_SUPPORT_IBSS_RSN", NL80211_ATTR_WIPHY_ANTENNA_TX: "NL80211_ATTR_WIPHY_ANTENNA_TX", NL80211_ATTR_WIPHY_ANTENNA_RX: "NL80211_ATTR_WIPHY_ANTENNA_RX", NL80211_ATTR_MCAST_RATE: "NL80211_ATTR_MCAST_RATE", NL80211_ATTR_OFFCHANNEL_TX_OK: "NL80211_ATTR_OFFCHANNEL_TX_OK", NL80211_ATTR_BSS_HT_OPMODE: "NL80211_ATTR_BSS_HT_OPMODE", NL80211_ATTR_KEY_DEFAULT_TYPES: "NL80211_ATTR_KEY_DEFAULT_TYPES", NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: "NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION", NL80211_ATTR_MESH_SETUP: "NL80211_ATTR_MESH_SETUP", NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: "NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX", NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: "NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX", NL80211_ATTR_SUPPORT_MESH_AUTH: "NL80211_ATTR_SUPPORT_MESH_AUTH", NL80211_ATTR_STA_PLINK_STATE: "NL80211_ATTR_STA_PLINK_STATE", NL80211_ATTR_WOWLAN_TRIGGERS: "NL80211_ATTR_WOWLAN_TRIGGERS", NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: "NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED", NL80211_ATTR_SCHED_SCAN_INTERVAL: "NL80211_ATTR_SCHED_SCAN_INTERVAL", NL80211_ATTR_INTERFACE_COMBINATIONS: "NL80211_ATTR_INTERFACE_COMBINATIONS", NL80211_ATTR_SOFTWARE_IFTYPES: "NL80211_ATTR_SOFTWARE_IFTYPES", NL80211_ATTR_REKEY_DATA: "NL80211_ATTR_REKEY_DATA", NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS: "NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS", NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: "NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN", NL80211_ATTR_SCAN_SUPP_RATES: "NL80211_ATTR_SCAN_SUPP_RATES", NL80211_ATTR_HIDDEN_SSID: "NL80211_ATTR_HIDDEN_SSID", NL80211_ATTR_IE_PROBE_RESP: "NL80211_ATTR_IE_PROBE_RESP", NL80211_ATTR_IE_ASSOC_RESP: "NL80211_ATTR_IE_ASSOC_RESP", NL80211_ATTR_STA_WME: "NL80211_ATTR_STA_WME", NL80211_ATTR_SUPPORT_AP_UAPSD: "NL80211_ATTR_SUPPORT_AP_UAPSD", NL80211_ATTR_ROAM_SUPPORT: "NL80211_ATTR_ROAM_SUPPORT", NL80211_ATTR_SCHED_SCAN_MATCH: "NL80211_ATTR_SCHED_SCAN_MATCH", NL80211_ATTR_MAX_MATCH_SETS: "NL80211_ATTR_MAX_MATCH_SETS", NL80211_ATTR_PMKSA_CANDIDATE: "NL80211_ATTR_PMKSA_CANDIDATE", NL80211_ATTR_TX_NO_CCK_RATE: "NL80211_ATTR_TX_NO_CCK_RATE", NL80211_ATTR_TDLS_ACTION: "NL80211_ATTR_TDLS_ACTION", NL80211_ATTR_TDLS_DIALOG_TOKEN: "NL80211_ATTR_TDLS_DIALOG_TOKEN", NL80211_ATTR_TDLS_OPERATION: "NL80211_ATTR_TDLS_OPERATION", NL80211_ATTR_TDLS_SUPPORT: "NL80211_ATTR_TDLS_SUPPORT", NL80211_ATTR_TDLS_EXTERNAL_SETUP: "NL80211_ATTR_TDLS_EXTERNAL_SETUP", NL80211_ATTR_DEVICE_AP_SME: "NL80211_ATTR_DEVICE_AP_SME", NL80211_ATTR_DONT_WAIT_FOR_ACK: "NL80211_ATTR_DONT_WAIT_FOR_ACK", NL80211_ATTR_FEATURE_FLAGS: "NL80211_ATTR_FEATURE_FLAGS", NL80211_ATTR_PROBE_RESP_OFFLOAD: "NL80211_ATTR_PROBE_RESP_OFFLOAD", NL80211_ATTR_PROBE_RESP: "NL80211_ATTR_PROBE_RESP", NL80211_ATTR_DFS_REGION: "NL80211_ATTR_DFS_REGION", NL80211_ATTR_DISABLE_HT: "NL80211_ATTR_DISABLE_HT", NL80211_ATTR_HT_CAPABILITY_MASK: "NL80211_ATTR_HT_CAPABILITY_MASK", NL80211_ATTR_NOACK_MAP: "NL80211_ATTR_NOACK_MAP", NL80211_ATTR_INACTIVITY_TIMEOUT: "NL80211_ATTR_INACTIVITY_TIMEOUT", NL80211_ATTR_RX_SIGNAL_DBM: "NL80211_ATTR_RX_SIGNAL_DBM", NL80211_ATTR_BG_SCAN_PERIOD: "NL80211_ATTR_BG_SCAN_PERIOD", NL80211_ATTR_WDEV: "NL80211_ATTR_WDEV", NL80211_ATTR_USER_REG_HINT_TYPE: "NL80211_ATTR_USER_REG_HINT_TYPE", NL80211_ATTR_CONN_FAILED_REASON: "NL80211_ATTR_CONN_FAILED_REASON", NL80211_ATTR_SAE_DATA: "NL80211_ATTR_SAE_DATA", NL80211_ATTR_VHT_CAPABILITY: "NL80211_ATTR_VHT_CAPABILITY", NL80211_ATTR_SCAN_FLAGS: "NL80211_ATTR_SCAN_FLAGS", NL80211_ATTR_CHANNEL_WIDTH: "NL80211_ATTR_CHANNEL_WIDTH", NL80211_ATTR_CENTER_FREQ1: "NL80211_ATTR_CENTER_FREQ1", NL80211_ATTR_CENTER_FREQ2: "NL80211_ATTR_CENTER_FREQ2", NL80211_ATTR_P2P_CTWINDOW: "NL80211_ATTR_P2P_CTWINDOW", NL80211_ATTR_P2P_OPPPS: "NL80211_ATTR_P2P_OPPPS", NL80211_ATTR_LOCAL_MESH_POWER_MODE: "NL80211_ATTR_LOCAL_MESH_POWER_MODE", NL80211_ATTR_ACL_POLICY: "NL80211_ATTR_ACL_POLICY", NL80211_ATTR_MAC_ADDRS: "NL80211_ATTR_MAC_ADDRS", NL80211_ATTR_MAC_ACL_MAX: "NL80211_ATTR_MAC_ACL_MAX", NL80211_ATTR_RADAR_EVENT: "NL80211_ATTR_RADAR_EVENT", NL80211_ATTR_EXT_CAPA: "NL80211_ATTR_EXT_CAPA", NL80211_ATTR_EXT_CAPA_MASK: "NL80211_ATTR_EXT_CAPA_MASK", NL80211_ATTR_STA_CAPABILITY: "NL80211_ATTR_STA_CAPABILITY", NL80211_ATTR_STA_EXT_CAPABILITY: "NL80211_ATTR_STA_EXT_CAPABILITY", NL80211_ATTR_PROTOCOL_FEATURES: "NL80211_ATTR_PROTOCOL_FEATURES", NL80211_ATTR_SPLIT_WIPHY_DUMP: "NL80211_ATTR_SPLIT_WIPHY_DUMP", NL80211_ATTR_DISABLE_VHT: "NL80211_ATTR_DISABLE_VHT", NL80211_ATTR_VHT_CAPABILITY_MASK: "NL80211_ATTR_VHT_CAPABILITY_MASK", NL80211_ATTR_MDID: "NL80211_ATTR_MDID", NL80211_ATTR_IE_RIC: "NL80211_ATTR_IE_RIC", NL80211_ATTR_CRIT_PROT_ID: "NL80211_ATTR_CRIT_PROT_ID", NL80211_ATTR_MAX_CRIT_PROT_DURATION: "NL80211_ATTR_MAX_CRIT_PROT_DURATION", NL80211_ATTR_PEER_AID: "NL80211_ATTR_PEER_AID", __NL80211_ATTR_AFTER_LAST: "__NL80211_ATTR_AFTER_LAST", } nl80211_iftype2str = { NL80211_IFTYPE_UNSPECIFIED: "NL80211_IFTYPE_UNSPECIFIED", NL80211_IFTYPE_ADHOC: "NL80211_IFTYPE_ADHOC", NL80211_IFTYPE_STATION: "NL80211_IFTYPE_STATION", NL80211_IFTYPE_AP: "NL80211_IFTYPE_AP", NL80211_IFTYPE_AP_VLAN: "NL80211_IFTYPE_AP_VLAN", NL80211_IFTYPE_WDS: "NL80211_IFTYPE_WDS", NL80211_IFTYPE_MONITOR: "NL80211_IFTYPE_MONITOR", NL80211_IFTYPE_MESH_POINT: "NL80211_IFTYPE_MESH_POINT", NL80211_IFTYPE_P2P_CLIENT: "NL80211_IFTYPE_P2P_CLIENT", NL80211_IFTYPE_P2P_GO: "NL80211_IFTYPE_P2P_GO", NL80211_IFTYPE_P2P_DEVICE: "NL80211_IFTYPE_P2P_DEVICE", NUM_NL80211_IFTYPES: "NUM_NL80211_IFTYPES", } nl80211_sta_flags2str = { __NL80211_STA_FLAG_INVALID: "__NL80211_STA_FLAG_INVALID", NL80211_STA_FLAG_AUTHORIZED: "NL80211_STA_FLAG_AUTHORIZED", NL80211_STA_FLAG_SHORT_PREAMBLE: "NL80211_STA_FLAG_SHORT_PREAMBLE", NL80211_STA_FLAG_WME: "NL80211_STA_FLAG_WME", NL80211_STA_FLAG_MFP: "NL80211_STA_FLAG_MFP", NL80211_STA_FLAG_AUTHENTICATED: "NL80211_STA_FLAG_AUTHENTICATED", NL80211_STA_FLAG_TDLS_PEER: "NL80211_STA_FLAG_TDLS_PEER", NL80211_STA_FLAG_ASSOCIATED: "NL80211_STA_FLAG_ASSOCIATED", __NL80211_STA_FLAG_AFTER_LAST: "__NL80211_STA_FLAG_AFTER_LAST", } nl80211_rate_info2str = { __NL80211_RATE_INFO_INVALID: "__NL80211_RATE_INFO_INVALID", NL80211_RATE_INFO_BITRATE: "NL80211_RATE_INFO_BITRATE", NL80211_RATE_INFO_MCS: "NL80211_RATE_INFO_MCS", NL80211_RATE_INFO_40_MHZ_WIDTH: "NL80211_RATE_INFO_40_MHZ_WIDTH", NL80211_RATE_INFO_SHORT_GI: "NL80211_RATE_INFO_SHORT_GI", NL80211_RATE_INFO_BITRATE32: "NL80211_RATE_INFO_BITRATE32", NL80211_RATE_INFO_VHT_MCS: "NL80211_RATE_INFO_VHT_MCS", NL80211_RATE_INFO_VHT_NSS: "NL80211_RATE_INFO_VHT_NSS", NL80211_RATE_INFO_80_MHZ_WIDTH: "NL80211_RATE_INFO_80_MHZ_WIDTH", NL80211_RATE_INFO_80P80_MHZ_WIDTH: "NL80211_RATE_INFO_80P80_MHZ_WIDTH", NL80211_RATE_INFO_160_MHZ_WIDTH: "NL80211_RATE_INFO_160_MHZ_WIDTH", __NL80211_RATE_INFO_AFTER_LAST: "__NL80211_RATE_INFO_AFTER_LAST", } nl80211_sta_bss_param2str = { __NL80211_STA_BSS_PARAM_INVALID: "__NL80211_STA_BSS_PARAM_INVALID", NL80211_STA_BSS_PARAM_CTS_PROT: "NL80211_STA_BSS_PARAM_CTS_PROT", NL80211_STA_BSS_PARAM_SHORT_PREAMBLE: "NL80211_STA_BSS_PARAM_SHORT_PREAMBLE", NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME: "NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME", NL80211_STA_BSS_PARAM_DTIM_PERIOD: "NL80211_STA_BSS_PARAM_DTIM_PERIOD", NL80211_STA_BSS_PARAM_BEACON_INTERVAL: "NL80211_STA_BSS_PARAM_BEACON_INTERVAL", __NL80211_STA_BSS_PARAM_AFTER_LAST: "__NL80211_STA_BSS_PARAM_AFTER_LAST", } nl80211_sta_info2str = { __NL80211_STA_INFO_INVALID: "__NL80211_STA_INFO_INVALID", NL80211_STA_INFO_INACTIVE_TIME: "NL80211_STA_INFO_INACTIVE_TIME", NL80211_STA_INFO_RX_BYTES: "NL80211_STA_INFO_RX_BYTES", NL80211_STA_INFO_TX_BYTES: "NL80211_STA_INFO_TX_BYTES", NL80211_STA_INFO_LLID: "NL80211_STA_INFO_LLID", NL80211_STA_INFO_PLID: "NL80211_STA_INFO_PLID", NL80211_STA_INFO_PLINK_STATE: "NL80211_STA_INFO_PLINK_STATE", NL80211_STA_INFO_SIGNAL: "NL80211_STA_INFO_SIGNAL", NL80211_STA_INFO_TX_BITRATE: "NL80211_STA_INFO_TX_BITRATE", NL80211_STA_INFO_RX_PACKETS: "NL80211_STA_INFO_RX_PACKETS", NL80211_STA_INFO_TX_PACKETS: "NL80211_STA_INFO_TX_PACKETS", NL80211_STA_INFO_TX_RETRIES: "NL80211_STA_INFO_TX_RETRIES", NL80211_STA_INFO_TX_FAILED: "NL80211_STA_INFO_TX_FAILED", NL80211_STA_INFO_SIGNAL_AVG: "NL80211_STA_INFO_SIGNAL_AVG", NL80211_STA_INFO_RX_BITRATE: "NL80211_STA_INFO_RX_BITRATE", NL80211_STA_INFO_BSS_PARAM: "NL80211_STA_INFO_BSS_PARAM", NL80211_STA_INFO_CONNECTED_TIME: "NL80211_STA_INFO_CONNECTED_TIME", NL80211_STA_INFO_STA_FLAGS: "NL80211_STA_INFO_STA_FLAGS", NL80211_STA_INFO_BEACON_LOSS: "NL80211_STA_INFO_BEACON_LOSS", NL80211_STA_INFO_T_OFFSET: "NL80211_STA_INFO_T_OFFSET", NL80211_STA_INFO_LOCAL_PM: "NL80211_STA_INFO_LOCAL_PM", NL80211_STA_INFO_PEER_PM: "NL80211_STA_INFO_PEER_PM", NL80211_STA_INFO_NONPEER_PM: "NL80211_STA_INFO_NONPEER_PM", NL80211_STA_INFO_RX_BYTES64: "NL80211_STA_INFO_RX_BYTES64", NL80211_STA_INFO_TX_BYTES64: "NL80211_STA_INFO_TX_BYTES64", NL80211_STA_INFO_CHAIN_SIGNAL: "NL80211_STA_INFO_CHAIN_SIGNAL", NL80211_STA_INFO_CHAIN_SIGNAL_AVG: "NL80211_STA_INFO_CHAIN_SIGNAL_AVG", __NL80211_STA_INFO_AFTER_LAST: "__NL80211_STA_INFO_AFTER_LAST", } nl80211_mpath_flags2str = { NL80211_MPATH_FLAG_ACTIVE: "NL80211_MPATH_FLAG_ACTIVE", NL80211_MPATH_FLAG_RESOLVING: "NL80211_MPATH_FLAG_RESOLVING", NL80211_MPATH_FLAG_SN_VALID: "NL80211_MPATH_FLAG_SN_VALID", NL80211_MPATH_FLAG_FIXED: "NL80211_MPATH_FLAG_FIXED", NL80211_MPATH_FLAG_RESOLVED: "NL80211_MPATH_FLAG_RESOLVED", } nl80211_mpath_info2str = { __NL80211_MPATH_INFO_INVALID: "__NL80211_MPATH_INFO_INVALID", NL80211_MPATH_INFO_FRAME_QLEN: "NL80211_MPATH_INFO_FRAME_QLEN", NL80211_MPATH_INFO_SN: "NL80211_MPATH_INFO_SN", NL80211_MPATH_INFO_METRIC: "NL80211_MPATH_INFO_METRIC", NL80211_MPATH_INFO_EXPTIME: "NL80211_MPATH_INFO_EXPTIME", NL80211_MPATH_INFO_FLAGS: "NL80211_MPATH_INFO_FLAGS", NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: "NL80211_MPATH_INFO_DISCOVERY_TIMEOUT", NL80211_MPATH_INFO_DISCOVERY_RETRIES: "NL80211_MPATH_INFO_DISCOVERY_RETRIES", __NL80211_MPATH_INFO_AFTER_LAST: "__NL80211_MPATH_INFO_AFTER_LAST", } nl80211_band_attr2str = { __NL80211_BAND_ATTR_INVALID: "__NL80211_BAND_ATTR_INVALID", NL80211_BAND_ATTR_FREQS: "NL80211_BAND_ATTR_FREQS", NL80211_BAND_ATTR_RATES: "NL80211_BAND_ATTR_RATES", NL80211_BAND_ATTR_HT_MCS_SET: "NL80211_BAND_ATTR_HT_MCS_SET", NL80211_BAND_ATTR_HT_CAPA: "NL80211_BAND_ATTR_HT_CAPA", NL80211_BAND_ATTR_HT_AMPDU_FACTOR: "NL80211_BAND_ATTR_HT_AMPDU_FACTOR", NL80211_BAND_ATTR_HT_AMPDU_DENSITY: "NL80211_BAND_ATTR_HT_AMPDU_DENSITY", NL80211_BAND_ATTR_VHT_MCS_SET: "NL80211_BAND_ATTR_VHT_MCS_SET", NL80211_BAND_ATTR_VHT_CAPA: "NL80211_BAND_ATTR_VHT_CAPA", __NL80211_BAND_ATTR_AFTER_LAST: "__NL80211_BAND_ATTR_AFTER_LAST", } nl80211_frequency_attr2str = { __NL80211_FREQUENCY_ATTR_INVALID: "__NL80211_FREQUENCY_ATTR_INVALID", NL80211_FREQUENCY_ATTR_FREQ: "NL80211_FREQUENCY_ATTR_FREQ", NL80211_FREQUENCY_ATTR_DISABLED: "NL80211_FREQUENCY_ATTR_DISABLED", NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: "NL80211_FREQUENCY_ATTR_PASSIVE_SCAN", NL80211_FREQUENCY_ATTR_NO_IBSS: "NL80211_FREQUENCY_ATTR_NO_IBSS", NL80211_FREQUENCY_ATTR_RADAR: "NL80211_FREQUENCY_ATTR_RADAR", NL80211_FREQUENCY_ATTR_MAX_TX_POWER: "NL80211_FREQUENCY_ATTR_MAX_TX_POWER", NL80211_FREQUENCY_ATTR_DFS_STATE: "NL80211_FREQUENCY_ATTR_DFS_STATE", NL80211_FREQUENCY_ATTR_DFS_TIME: "NL80211_FREQUENCY_ATTR_DFS_TIME", NL80211_FREQUENCY_ATTR_NO_HT40_MINUS: "NL80211_FREQUENCY_ATTR_NO_HT40_MINUS", NL80211_FREQUENCY_ATTR_NO_HT40_PLUS: "NL80211_FREQUENCY_ATTR_NO_HT40_PLUS", NL80211_FREQUENCY_ATTR_NO_80MHZ: "NL80211_FREQUENCY_ATTR_NO_80MHZ", NL80211_FREQUENCY_ATTR_NO_160MHZ: "NL80211_FREQUENCY_ATTR_NO_160MHZ", __NL80211_FREQUENCY_ATTR_AFTER_LAST: "__NL80211_FREQUENCY_ATTR_AFTER_LAST", } nl80211_bitrate_attr2str = { __NL80211_BITRATE_ATTR_INVALID: "__NL80211_BITRATE_ATTR_INVALID", NL80211_BITRATE_ATTR_RATE: "NL80211_BITRATE_ATTR_RATE", NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: "NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE", __NL80211_BITRATE_ATTR_AFTER_LAST: "__NL80211_BITRATE_ATTR_AFTER_LAST", } nl80211_reg_initiator2str = { NL80211_REGDOM_SET_BY_CORE: "NL80211_REGDOM_SET_BY_CORE", NL80211_REGDOM_SET_BY_USER: "NL80211_REGDOM_SET_BY_USER", NL80211_REGDOM_SET_BY_DRIVER: "NL80211_REGDOM_SET_BY_DRIVER", NL80211_REGDOM_SET_BY_COUNTRY_IE: "NL80211_REGDOM_SET_BY_COUNTRY_IE", } nl80211_reg_type2str = { NL80211_REGDOM_TYPE_COUNTRY: "NL80211_REGDOM_TYPE_COUNTRY", NL80211_REGDOM_TYPE_WORLD: "NL80211_REGDOM_TYPE_WORLD", NL80211_REGDOM_TYPE_CUSTOM_WORLD: "NL80211_REGDOM_TYPE_CUSTOM_WORLD", NL80211_REGDOM_TYPE_INTERSECTION: "NL80211_REGDOM_TYPE_INTERSECTION", } nl80211_reg_rule_attr2str = { __NL80211_REG_RULE_ATTR_INVALID: "__NL80211_REG_RULE_ATTR_INVALID", NL80211_ATTR_REG_RULE_FLAGS: "NL80211_ATTR_REG_RULE_FLAGS", NL80211_ATTR_FREQ_RANGE_START: "NL80211_ATTR_FREQ_RANGE_START", NL80211_ATTR_FREQ_RANGE_END: "NL80211_ATTR_FREQ_RANGE_END", NL80211_ATTR_FREQ_RANGE_MAX_BW: "NL80211_ATTR_FREQ_RANGE_MAX_BW", NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: "NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN", NL80211_ATTR_POWER_RULE_MAX_EIRP: "NL80211_ATTR_POWER_RULE_MAX_EIRP", __NL80211_REG_RULE_ATTR_AFTER_LAST: "__NL80211_REG_RULE_ATTR_AFTER_LAST", } nl80211_sched_scan_match_attr2str = { __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: "__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID", NL80211_SCHED_SCAN_MATCH_ATTR_SSID: "NL80211_SCHED_SCAN_MATCH_ATTR_SSID", NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: "NL80211_SCHED_SCAN_MATCH_ATTR_RSSI", __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: "__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST", } nl80211_reg_rule_flags2str = { NL80211_RRF_NO_OFDM: "NL80211_RRF_NO_OFDM", NL80211_RRF_NO_CCK: "NL80211_RRF_NO_CCK", NL80211_RRF_NO_INDOOR: "NL80211_RRF_NO_INDOOR", NL80211_RRF_NO_OUTDOOR: "NL80211_RRF_NO_OUTDOOR", NL80211_RRF_DFS: "NL80211_RRF_DFS", NL80211_RRF_PTP_ONLY: "NL80211_RRF_PTP_ONLY", NL80211_RRF_PTMP_ONLY: "NL80211_RRF_PTMP_ONLY", NL80211_RRF_PASSIVE_SCAN: "NL80211_RRF_PASSIVE_SCAN", NL80211_RRF_NO_IBSS: "NL80211_RRF_NO_IBSS", } nl80211_dfs_regions2str = { } nl80211_user_reg_hint_type2str = { } nl80211_survey_info2str = { __NL80211_SURVEY_INFO_INVALID: "__NL80211_SURVEY_INFO_INVALID", NL80211_SURVEY_INFO_FREQUENCY: "NL80211_SURVEY_INFO_FREQUENCY", NL80211_SURVEY_INFO_NOISE: "NL80211_SURVEY_INFO_NOISE", NL80211_SURVEY_INFO_IN_USE: "NL80211_SURVEY_INFO_IN_USE", NL80211_SURVEY_INFO_CHANNEL_TIME: "NL80211_SURVEY_INFO_CHANNEL_TIME", NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: "NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY", NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: "NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY", NL80211_SURVEY_INFO_CHANNEL_TIME_RX: "NL80211_SURVEY_INFO_CHANNEL_TIME_RX", NL80211_SURVEY_INFO_CHANNEL_TIME_TX: "NL80211_SURVEY_INFO_CHANNEL_TIME_TX", __NL80211_SURVEY_INFO_AFTER_LAST: "__NL80211_SURVEY_INFO_AFTER_LAST", } nl80211_mntr_flags2str = { __NL80211_MNTR_FLAG_INVALID: "__NL80211_MNTR_FLAG_INVALID", NL80211_MNTR_FLAG_FCSFAIL: "NL80211_MNTR_FLAG_FCSFAIL", NL80211_MNTR_FLAG_PLCPFAIL: "NL80211_MNTR_FLAG_PLCPFAIL", NL80211_MNTR_FLAG_CONTROL: "NL80211_MNTR_FLAG_CONTROL", NL80211_MNTR_FLAG_OTHER_BSS: "NL80211_MNTR_FLAG_OTHER_BSS", NL80211_MNTR_FLAG_COOK_FRAMES: "NL80211_MNTR_FLAG_COOK_FRAMES", NL80211_MNTR_FLAG_ACTIVE: "NL80211_MNTR_FLAG_ACTIVE", __NL80211_MNTR_FLAG_AFTER_LAST: "__NL80211_MNTR_FLAG_AFTER_LAST", } nl80211_mesh_power_mode2str = { NL80211_MESH_POWER_UNKNOWN: "NL80211_MESH_POWER_UNKNOWN", NL80211_MESH_POWER_ACTIVE: "NL80211_MESH_POWER_ACTIVE", NL80211_MESH_POWER_LIGHT_SLEEP: "NL80211_MESH_POWER_LIGHT_SLEEP", NL80211_MESH_POWER_DEEP_SLEEP: "NL80211_MESH_POWER_DEEP_SLEEP", __NL80211_MESH_POWER_AFTER_LAST: "__NL80211_MESH_POWER_AFTER_LAST", } nl80211_meshconf_params2str = { __NL80211_MESHCONF_INVALID: "__NL80211_MESHCONF_INVALID", NL80211_MESHCONF_RETRY_TIMEOUT: "NL80211_MESHCONF_RETRY_TIMEOUT", NL80211_MESHCONF_CONFIRM_TIMEOUT: "NL80211_MESHCONF_CONFIRM_TIMEOUT", NL80211_MESHCONF_HOLDING_TIMEOUT: "NL80211_MESHCONF_HOLDING_TIMEOUT", NL80211_MESHCONF_MAX_PEER_LINKS: "NL80211_MESHCONF_MAX_PEER_LINKS", NL80211_MESHCONF_MAX_RETRIES: "NL80211_MESHCONF_MAX_RETRIES", NL80211_MESHCONF_TTL: "NL80211_MESHCONF_TTL", NL80211_MESHCONF_AUTO_OPEN_PLINKS: "NL80211_MESHCONF_AUTO_OPEN_PLINKS", NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: "NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES", NL80211_MESHCONF_PATH_REFRESH_TIME: "NL80211_MESHCONF_PATH_REFRESH_TIME", NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: "NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT", NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: "NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT", NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: "NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL", NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: "NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME", NL80211_MESHCONF_HWMP_ROOTMODE: "NL80211_MESHCONF_HWMP_ROOTMODE", NL80211_MESHCONF_ELEMENT_TTL: "NL80211_MESHCONF_ELEMENT_TTL", NL80211_MESHCONF_HWMP_RANN_INTERVAL: "NL80211_MESHCONF_HWMP_RANN_INTERVAL", NL80211_MESHCONF_GATE_ANNOUNCEMENTS: "NL80211_MESHCONF_GATE_ANNOUNCEMENTS", NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: "NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL", NL80211_MESHCONF_FORWARDING: "NL80211_MESHCONF_FORWARDING", NL80211_MESHCONF_RSSI_THRESHOLD: "NL80211_MESHCONF_RSSI_THRESHOLD", NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: "NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR", NL80211_MESHCONF_HT_OPMODE: "NL80211_MESHCONF_HT_OPMODE", NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: "NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT", NL80211_MESHCONF_HWMP_ROOT_INTERVAL: "NL80211_MESHCONF_HWMP_ROOT_INTERVAL", NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: "NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL", NL80211_MESHCONF_POWER_MODE: "NL80211_MESHCONF_POWER_MODE", NL80211_MESHCONF_AWAKE_WINDOW: "NL80211_MESHCONF_AWAKE_WINDOW", NL80211_MESHCONF_PLINK_TIMEOUT: "NL80211_MESHCONF_PLINK_TIMEOUT", __NL80211_MESHCONF_ATTR_AFTER_LAST: "__NL80211_MESHCONF_ATTR_AFTER_LAST", } nl80211_mesh_setup_params2str = { __NL80211_MESH_SETUP_INVALID: "__NL80211_MESH_SETUP_INVALID", NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: "NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL", NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: "NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC", NL80211_MESH_SETUP_IE: "NL80211_MESH_SETUP_IE", NL80211_MESH_SETUP_USERSPACE_AUTH: "NL80211_MESH_SETUP_USERSPACE_AUTH", NL80211_MESH_SETUP_USERSPACE_AMPE: "NL80211_MESH_SETUP_USERSPACE_AMPE", NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: "NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC", NL80211_MESH_SETUP_USERSPACE_MPM: "NL80211_MESH_SETUP_USERSPACE_MPM", NL80211_MESH_SETUP_AUTH_PROTOCOL: "NL80211_MESH_SETUP_AUTH_PROTOCOL", __NL80211_MESH_SETUP_ATTR_AFTER_LAST: "__NL80211_MESH_SETUP_ATTR_AFTER_LAST", } nl80211_txq_attr2str = { __NL80211_TXQ_ATTR_INVALID: "__NL80211_TXQ_ATTR_INVALID", NL80211_TXQ_ATTR_AC: "NL80211_TXQ_ATTR_AC", NL80211_TXQ_ATTR_TXOP: "NL80211_TXQ_ATTR_TXOP", NL80211_TXQ_ATTR_CWMIN: "NL80211_TXQ_ATTR_CWMIN", NL80211_TXQ_ATTR_CWMAX: "NL80211_TXQ_ATTR_CWMAX", NL80211_TXQ_ATTR_AIFS: "NL80211_TXQ_ATTR_AIFS", __NL80211_TXQ_ATTR_AFTER_LAST: "__NL80211_TXQ_ATTR_AFTER_LAST", } nl80211_ac2str = { NL80211_AC_VO: "NL80211_AC_VO", NL80211_AC_VI: "NL80211_AC_VI", NL80211_AC_BE: "NL80211_AC_BE", NL80211_AC_BK: "NL80211_AC_BK", NL80211_NUM_ACS: "NL80211_NUM_ACS", } nl80211_channel_type2str = { NL80211_CHAN_NO_HT: "NL80211_CHAN_NO_HT", NL80211_CHAN_HT20: "NL80211_CHAN_HT20", NL80211_CHAN_HT40MINUS: "NL80211_CHAN_HT40MINUS", NL80211_CHAN_HT40PLUS: "NL80211_CHAN_HT40PLUS", } nl80211_chan_width2str = { NL80211_CHAN_WIDTH_20_NOHT: "NL80211_CHAN_WIDTH_20_NOHT", NL80211_CHAN_WIDTH_20: "NL80211_CHAN_WIDTH_20", NL80211_CHAN_WIDTH_40: "NL80211_CHAN_WIDTH_40", NL80211_CHAN_WIDTH_80: "NL80211_CHAN_WIDTH_80", NL80211_CHAN_WIDTH_80P80: "NL80211_CHAN_WIDTH_80P80", NL80211_CHAN_WIDTH_160: "NL80211_CHAN_WIDTH_160", } nl80211_bss2str = { __NL80211_BSS_INVALID: "__NL80211_BSS_INVALID", NL80211_BSS_BSSID: "NL80211_BSS_BSSID", NL80211_BSS_FREQUENCY: "NL80211_BSS_FREQUENCY", NL80211_BSS_TSF: "NL80211_BSS_TSF", NL80211_BSS_BEACON_INTERVAL: "NL80211_BSS_BEACON_INTERVAL", NL80211_BSS_CAPABILITY: "NL80211_BSS_CAPABILITY", NL80211_BSS_INFORMATION_ELEMENTS: "NL80211_BSS_INFORMATION_ELEMENTS", NL80211_BSS_SIGNAL_MBM: "NL80211_BSS_SIGNAL_MBM", NL80211_BSS_SIGNAL_UNSPEC: "NL80211_BSS_SIGNAL_UNSPEC", NL80211_BSS_STATUS: "NL80211_BSS_STATUS", NL80211_BSS_SEEN_MS_AGO: "NL80211_BSS_SEEN_MS_AGO", NL80211_BSS_BEACON_IES: "NL80211_BSS_BEACON_IES", __NL80211_BSS_AFTER_LAST: "__NL80211_BSS_AFTER_LAST", } nl80211_bss_status2str = { NL80211_BSS_STATUS_AUTHENTICATED: "NL80211_BSS_STATUS_AUTHENTICATED", NL80211_BSS_STATUS_ASSOCIATED: "NL80211_BSS_STATUS_ASSOCIATED", NL80211_BSS_STATUS_IBSS_JOINED: "NL80211_BSS_STATUS_IBSS_JOINED", } nl80211_auth_type2str = { NL80211_AUTHTYPE_OPEN_SYSTEM: "NL80211_AUTHTYPE_OPEN_SYSTEM", NL80211_AUTHTYPE_SHARED_KEY: "NL80211_AUTHTYPE_SHARED_KEY", NL80211_AUTHTYPE_FT: "NL80211_AUTHTYPE_FT", NL80211_AUTHTYPE_NETWORK_EAP: "NL80211_AUTHTYPE_NETWORK_EAP", NL80211_AUTHTYPE_SAE: "NL80211_AUTHTYPE_SAE", __NL80211_AUTHTYPE_NUM: "__NL80211_AUTHTYPE_NUM", NL80211_AUTHTYPE_AUTOMATIC: "NL80211_AUTHTYPE_AUTOMATIC", } nl80211_key_type2str = { NL80211_KEYTYPE_GROUP: "NL80211_KEYTYPE_GROUP", NL80211_KEYTYPE_PAIRWISE: "NL80211_KEYTYPE_PAIRWISE", NL80211_KEYTYPE_PEERKEY: "NL80211_KEYTYPE_PEERKEY", NUM_NL80211_KEYTYPES: "NUM_NL80211_KEYTYPES", } nl80211_mfp2str = { NL80211_MFP_NO: "NL80211_MFP_NO", NL80211_MFP_REQUIRED: "NL80211_MFP_REQUIRED", } nl80211_wpa_versions2str = { NL80211_WPA_VERSION_1: "NL80211_WPA_VERSION_1", NL80211_WPA_VERSION_2: "NL80211_WPA_VERSION_2", } nl80211_key_default_types2str = { __NL80211_KEY_DEFAULT_TYPE_INVALID: "__NL80211_KEY_DEFAULT_TYPE_INVALID", NL80211_KEY_DEFAULT_TYPE_UNICAST: "NL80211_KEY_DEFAULT_TYPE_UNICAST", NL80211_KEY_DEFAULT_TYPE_MULTICAST: "NL80211_KEY_DEFAULT_TYPE_MULTICAST", NUM_NL80211_KEY_DEFAULT_TYPES: "NUM_NL80211_KEY_DEFAULT_TYPES", } nl80211_key_attributes2str = { __NL80211_KEY_INVALID: "__NL80211_KEY_INVALID", NL80211_KEY_DATA: "NL80211_KEY_DATA", NL80211_KEY_IDX: "NL80211_KEY_IDX", NL80211_KEY_CIPHER: "NL80211_KEY_CIPHER", NL80211_KEY_SEQ: "NL80211_KEY_SEQ", NL80211_KEY_DEFAULT: "NL80211_KEY_DEFAULT", NL80211_KEY_DEFAULT_MGMT: "NL80211_KEY_DEFAULT_MGMT", NL80211_KEY_TYPE: "NL80211_KEY_TYPE", NL80211_KEY_DEFAULT_TYPES: "NL80211_KEY_DEFAULT_TYPES", __NL80211_KEY_AFTER_LAST: "__NL80211_KEY_AFTER_LAST", } nl80211_tx_rate_attributes2str = { __NL80211_TXRATE_INVALID: "__NL80211_TXRATE_INVALID", NL80211_TXRATE_LEGACY: "NL80211_TXRATE_LEGACY", NL80211_TXRATE_MCS: "NL80211_TXRATE_MCS", __NL80211_TXRATE_AFTER_LAST: "__NL80211_TXRATE_AFTER_LAST", } nl80211_band2str = { NL80211_BAND_2GHZ: "NL80211_BAND_2GHZ", NL80211_BAND_5GHZ: "NL80211_BAND_5GHZ", NL80211_BAND_60GHZ: "NL80211_BAND_60GHZ", } nl80211_ps_state2str = { NL80211_PS_DISABLED: "NL80211_PS_DISABLED", NL80211_PS_ENABLED: "NL80211_PS_ENABLED", } nl80211_attr_cqm2str = { __NL80211_ATTR_CQM_INVALID: "__NL80211_ATTR_CQM_INVALID", NL80211_ATTR_CQM_RSSI_THOLD: "NL80211_ATTR_CQM_RSSI_THOLD", NL80211_ATTR_CQM_RSSI_HYST: "NL80211_ATTR_CQM_RSSI_HYST", NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: "NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT", NL80211_ATTR_CQM_PKT_LOSS_EVENT: "NL80211_ATTR_CQM_PKT_LOSS_EVENT", NL80211_ATTR_CQM_TXE_RATE: "NL80211_ATTR_CQM_TXE_RATE", NL80211_ATTR_CQM_TXE_PKTS: "NL80211_ATTR_CQM_TXE_PKTS", NL80211_ATTR_CQM_TXE_INTVL: "NL80211_ATTR_CQM_TXE_INTVL", __NL80211_ATTR_CQM_AFTER_LAST: "__NL80211_ATTR_CQM_AFTER_LAST", } nl80211_cqm_rssi_threshold_event2str = { NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: "NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW", NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: "NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH", NL80211_CQM_RSSI_BEACON_LOSS_EVENT: "NL80211_CQM_RSSI_BEACON_LOSS_EVENT", } nl80211_tx_power_setting2str = { NL80211_TX_POWER_AUTOMATIC: "NL80211_TX_POWER_AUTOMATIC", NL80211_TX_POWER_LIMITED: "NL80211_TX_POWER_LIMITED", NL80211_TX_POWER_FIXED: "NL80211_TX_POWER_FIXED", } nl80211_wowlan_packet_pattern_attr2str = { __NL80211_WOWLAN_PKTPAT_INVALID: "__NL80211_WOWLAN_PKTPAT_INVALID", NL80211_WOWLAN_PKTPAT_MASK: "NL80211_WOWLAN_PKTPAT_MASK", NL80211_WOWLAN_PKTPAT_PATTERN: "NL80211_WOWLAN_PKTPAT_PATTERN", NL80211_WOWLAN_PKTPAT_OFFSET: "NL80211_WOWLAN_PKTPAT_OFFSET", NUM_NL80211_WOWLAN_PKTPAT: "NUM_NL80211_WOWLAN_PKTPAT", } nl80211_wowlan_triggers2str = { __NL80211_WOWLAN_TRIG_INVALID: "__NL80211_WOWLAN_TRIG_INVALID", NL80211_WOWLAN_TRIG_ANY: "NL80211_WOWLAN_TRIG_ANY", NL80211_WOWLAN_TRIG_DISCONNECT: "NL80211_WOWLAN_TRIG_DISCONNECT", NL80211_WOWLAN_TRIG_MAGIC_PKT: "NL80211_WOWLAN_TRIG_MAGIC_PKT", NL80211_WOWLAN_TRIG_PKT_PATTERN: "NL80211_WOWLAN_TRIG_PKT_PATTERN", NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: "NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED", NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: "NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE", NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: "NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST", NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: "NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE", NL80211_WOWLAN_TRIG_RFKILL_RELEASE: "NL80211_WOWLAN_TRIG_RFKILL_RELEASE", NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211: "NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211", NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN: "NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN", NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023: "NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023", NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN: "NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN", NL80211_WOWLAN_TRIG_TCP_CONNECTION: "NL80211_WOWLAN_TRIG_TCP_CONNECTION", NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH: "NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH", NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: "NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST", NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS: "NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS", NUM_NL80211_WOWLAN_TRIG: "NUM_NL80211_WOWLAN_TRIG", } nl80211_wowlan_tcp_attrs2str = { __NL80211_WOWLAN_TCP_INVALID: "__NL80211_WOWLAN_TCP_INVALID", NL80211_WOWLAN_TCP_SRC_IPV4: "NL80211_WOWLAN_TCP_SRC_IPV4", NL80211_WOWLAN_TCP_DST_IPV4: "NL80211_WOWLAN_TCP_DST_IPV4", NL80211_WOWLAN_TCP_DST_MAC: "NL80211_WOWLAN_TCP_DST_MAC", NL80211_WOWLAN_TCP_SRC_PORT: "NL80211_WOWLAN_TCP_SRC_PORT", NL80211_WOWLAN_TCP_DST_PORT: "NL80211_WOWLAN_TCP_DST_PORT", NL80211_WOWLAN_TCP_DATA_PAYLOAD: "NL80211_WOWLAN_TCP_DATA_PAYLOAD", NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ: "NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ", NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN: "NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN", NL80211_WOWLAN_TCP_DATA_INTERVAL: "NL80211_WOWLAN_TCP_DATA_INTERVAL", NL80211_WOWLAN_TCP_WAKE_PAYLOAD: "NL80211_WOWLAN_TCP_WAKE_PAYLOAD", NL80211_WOWLAN_TCP_WAKE_MASK: "NL80211_WOWLAN_TCP_WAKE_MASK", NUM_NL80211_WOWLAN_TCP: "NUM_NL80211_WOWLAN_TCP", } nl80211_iface_limit_attrs2str = { NL80211_IFACE_LIMIT_UNSPEC: "NL80211_IFACE_LIMIT_UNSPEC", NL80211_IFACE_LIMIT_MAX: "NL80211_IFACE_LIMIT_MAX", NL80211_IFACE_LIMIT_TYPES: "NL80211_IFACE_LIMIT_TYPES", NUM_NL80211_IFACE_LIMIT: "NUM_NL80211_IFACE_LIMIT", } nl80211_if_combination_attrs2str = { NL80211_IFACE_COMB_UNSPEC: "NL80211_IFACE_COMB_UNSPEC", NL80211_IFACE_COMB_LIMITS: "NL80211_IFACE_COMB_LIMITS", NL80211_IFACE_COMB_MAXNUM: "NL80211_IFACE_COMB_MAXNUM", NL80211_IFACE_COMB_STA_AP_BI_MATCH: "NL80211_IFACE_COMB_STA_AP_BI_MATCH", NL80211_IFACE_COMB_NUM_CHANNELS: "NL80211_IFACE_COMB_NUM_CHANNELS", NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: "NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS", NUM_NL80211_IFACE_COMB: "NUM_NL80211_IFACE_COMB", } nl80211_plink_state2str = { NL80211_PLINK_LISTEN: "NL80211_PLINK_LISTEN", NL80211_PLINK_OPN_SNT: "NL80211_PLINK_OPN_SNT", NL80211_PLINK_OPN_RCVD: "NL80211_PLINK_OPN_RCVD", NL80211_PLINK_CNF_RCVD: "NL80211_PLINK_CNF_RCVD", NL80211_PLINK_ESTAB: "NL80211_PLINK_ESTAB", NL80211_PLINK_HOLDING: "NL80211_PLINK_HOLDING", NL80211_PLINK_BLOCKED: "NL80211_PLINK_BLOCKED", NUM_NL80211_PLINK_STATES: "NUM_NL80211_PLINK_STATES", } plink_actions2str = { NL80211_PLINK_ACTION_NO_ACTION: "NL80211_PLINK_ACTION_NO_ACTION", NL80211_PLINK_ACTION_OPEN: "NL80211_PLINK_ACTION_OPEN", NL80211_PLINK_ACTION_BLOCK: "NL80211_PLINK_ACTION_BLOCK", NUM_NL80211_PLINK_ACTIONS: "NUM_NL80211_PLINK_ACTIONS", } nl80211_rekey_data2str = { __NL80211_REKEY_DATA_INVALID: "__NL80211_REKEY_DATA_INVALID", NL80211_REKEY_DATA_KEK: "NL80211_REKEY_DATA_KEK", NL80211_REKEY_DATA_KCK: "NL80211_REKEY_DATA_KCK", NL80211_REKEY_DATA_REPLAY_CTR: "NL80211_REKEY_DATA_REPLAY_CTR", NUM_NL80211_REKEY_DATA: "NUM_NL80211_REKEY_DATA", } nl80211_hidden_ssid2str = { NL80211_HIDDEN_SSID_NOT_IN_USE: "NL80211_HIDDEN_SSID_NOT_IN_USE", NL80211_HIDDEN_SSID_ZERO_LEN: "NL80211_HIDDEN_SSID_ZERO_LEN", NL80211_HIDDEN_SSID_ZERO_CONTENTS: "NL80211_HIDDEN_SSID_ZERO_CONTENTS", } nl80211_sta_wme_attr2str = { __NL80211_STA_WME_INVALID: "__NL80211_STA_WME_INVALID", NL80211_STA_WME_UAPSD_QUEUES: "NL80211_STA_WME_UAPSD_QUEUES", NL80211_STA_WME_MAX_SP: "NL80211_STA_WME_MAX_SP", __NL80211_STA_WME_AFTER_LAST: "__NL80211_STA_WME_AFTER_LAST", } nl80211_pmksa_candidate_attr2str = { __NL80211_PMKSA_CANDIDATE_INVALID: "__NL80211_PMKSA_CANDIDATE_INVALID", NL80211_PMKSA_CANDIDATE_INDEX: "NL80211_PMKSA_CANDIDATE_INDEX", NL80211_PMKSA_CANDIDATE_BSSID: "NL80211_PMKSA_CANDIDATE_BSSID", NL80211_PMKSA_CANDIDATE_PREAUTH: "NL80211_PMKSA_CANDIDATE_PREAUTH", NUM_NL80211_PMKSA_CANDIDATE: "NUM_NL80211_PMKSA_CANDIDATE", } nl80211_tdls_operation2str = { NL80211_TDLS_DISCOVERY_REQ: "NL80211_TDLS_DISCOVERY_REQ", NL80211_TDLS_SETUP: "NL80211_TDLS_SETUP", NL80211_TDLS_TEARDOWN: "NL80211_TDLS_TEARDOWN", NL80211_TDLS_ENABLE_LINK: "NL80211_TDLS_ENABLE_LINK", NL80211_TDLS_DISABLE_LINK: "NL80211_TDLS_DISABLE_LINK", } nl80211_feature_flags2str = { NL80211_FEATURE_SK_TX_STATUS: "NL80211_FEATURE_SK_TX_STATUS", NL80211_FEATURE_HT_IBSS: "NL80211_FEATURE_HT_IBSS", NL80211_FEATURE_INACTIVITY_TIMER: "NL80211_FEATURE_INACTIVITY_TIMER", NL80211_FEATURE_CELL_BASE_REG_HINTS: "NL80211_FEATURE_CELL_BASE_REG_HINTS", NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: "NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL", NL80211_FEATURE_SAE: "NL80211_FEATURE_SAE", NL80211_FEATURE_LOW_PRIORITY_SCAN: "NL80211_FEATURE_LOW_PRIORITY_SCAN", NL80211_FEATURE_SCAN_FLUSH: "NL80211_FEATURE_SCAN_FLUSH", NL80211_FEATURE_AP_SCAN: "NL80211_FEATURE_AP_SCAN", NL80211_FEATURE_VIF_TXPOWER: "NL80211_FEATURE_VIF_TXPOWER", NL80211_FEATURE_NEED_OBSS_SCAN: "NL80211_FEATURE_NEED_OBSS_SCAN", NL80211_FEATURE_P2P_GO_CTWIN: "NL80211_FEATURE_P2P_GO_CTWIN", NL80211_FEATURE_P2P_GO_OPPPS: "NL80211_FEATURE_P2P_GO_OPPPS", NL80211_FEATURE_ADVERTISE_CHAN_LIMITS: "NL80211_FEATURE_ADVERTISE_CHAN_LIMITS", NL80211_FEATURE_FULL_AP_CLIENT_STATE: "NL80211_FEATURE_FULL_AP_CLIENT_STATE", NL80211_FEATURE_USERSPACE_MPM: "NL80211_FEATURE_USERSPACE_MPM", NL80211_FEATURE_ACTIVE_MONITOR: "NL80211_FEATURE_ACTIVE_MONITOR", } nl80211_probe_resp_offload_support_attr2str = { NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: "NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS", NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: "NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2", NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: "NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P", NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: "NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U", } nl80211_connect_failed_reason2str = { NL80211_CONN_FAIL_MAX_CLIENTS: "NL80211_CONN_FAIL_MAX_CLIENTS", NL80211_CONN_FAIL_BLOCKED_CLIENT: "NL80211_CONN_FAIL_BLOCKED_CLIENT", } nl80211_scan_flags2str = { NL80211_SCAN_FLAG_LOW_PRIORITY: "NL80211_SCAN_FLAG_LOW_PRIORITY", NL80211_SCAN_FLAG_FLUSH: "NL80211_SCAN_FLAG_FLUSH", NL80211_SCAN_FLAG_AP: "NL80211_SCAN_FLAG_AP", } nl80211_acl_policy2str = { NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: "NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED", NL80211_ACL_POLICY_DENY_UNLESS_LISTED: "NL80211_ACL_POLICY_DENY_UNLESS_LISTED", } nl80211_radar_event2str = { NL80211_RADAR_DETECTED: "NL80211_RADAR_DETECTED", NL80211_RADAR_CAC_FINISHED: "NL80211_RADAR_CAC_FINISHED", NL80211_RADAR_CAC_ABORTED: "NL80211_RADAR_CAC_ABORTED", NL80211_RADAR_NOP_FINISHED: "NL80211_RADAR_NOP_FINISHED", } nl80211_dfs_state2str = { NL80211_DFS_USABLE: "NL80211_DFS_USABLE", NL80211_DFS_UNAVAILABLE: "NL80211_DFS_UNAVAILABLE", NL80211_DFS_AVAILABLE: "NL80211_DFS_AVAILABLE", } nl80211_protocol_features2str = { NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP: "NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP", } nl80211_crit_proto_id2str = { NL80211_CRIT_PROTO_UNSPEC: "NL80211_CRIT_PROTO_UNSPEC", NL80211_CRIT_PROTO_DHCP: "NL80211_CRIT_PROTO_DHCP", NL80211_CRIT_PROTO_EAPOL: "NL80211_CRIT_PROTO_EAPOL", NL80211_CRIT_PROTO_APIPA: "NL80211_CRIT_PROTO_APIPA", NUM_NL80211_CRIT_PROTO: "NUM_NL80211_CRIT_PROTO", } libnl-3.2.29/m4/0000755000175000017500000000000013031473755010240 500000000000000libnl-3.2.29/m4/ltversion.m40000644000175000017500000000127313031473637012451 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) libnl-3.2.29/m4/ltsugar.m40000644000175000017500000001044013031473637012101 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) libnl-3.2.29/m4/lt~obsolete.m40000644000175000017500000001377413031473637013007 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) libnl-3.2.29/m4/ltoptions.m40000644000175000017500000003426213031473637012463 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) libnl-3.2.29/m4/libtool.m40000644000175000017500000112530613031473637012075 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS libnl-3.2.29/libnl-cli-3.0.pc.in0000644000175000017500000000047713023014600012721 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnl-cli Description: Command Line Interface library for netlink sockets Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lnl-cli-@MAJ_VERSION@ Cflags: -I${includedir} Requires: libnl-3.0 libnl-genl-3.0 libnl-nf-3.0 libnl-route-3.0 libnl-3.2.29/libnl-nf-3.sym0000644000175000017500000001633313023014600012216 00000000000000libnl_3 { global: # ops structure ct_obj_ops; exp_obj_ops; log_msg_obj_ops; log_obj_ops; queue_msg_obj_ops; queue_obj_ops; nfnl_connect; nfnl_ct_add; nfnl_ct_alloc; nfnl_ct_alloc_cache; nfnl_ct_build_add_request; nfnl_ct_build_delete_request; nfnl_ct_build_query_request; nfnl_ct_del; nfnl_ct_dump_request; nfnl_ct_get; nfnl_ct_get_bytes; nfnl_ct_get_dst; nfnl_ct_get_dst_port; nfnl_ct_get_family; nfnl_ct_get_icmp_code; nfnl_ct_get_icmp_id; nfnl_ct_get_icmp_type; nfnl_ct_get_id; nfnl_ct_get_mark; nfnl_ct_get_packets; nfnl_ct_get_proto; nfnl_ct_get_src; nfnl_ct_get_src_port; nfnl_ct_get_status; nfnl_ct_get_tcp_state; nfnl_ct_get_timeout; nfnl_ct_get_timestamp; nfnl_ct_get_use; nfnl_ct_get_zone; nfnl_ct_put; nfnl_ct_query; nfnl_ct_set_bytes; nfnl_ct_set_dst; nfnl_ct_set_dst_port; nfnl_ct_set_family; nfnl_ct_set_icmp_code; nfnl_ct_set_icmp_id; nfnl_ct_set_icmp_type; nfnl_ct_set_id; nfnl_ct_set_mark; nfnl_ct_set_packets; nfnl_ct_set_proto; nfnl_ct_set_src; nfnl_ct_set_src_port; nfnl_ct_set_status; nfnl_ct_set_tcp_state; nfnl_ct_set_timeout; nfnl_ct_set_timestamp; nfnl_ct_set_use; nfnl_ct_set_zone; nfnl_ct_status2str; nfnl_ct_str2status; nfnl_ct_str2tcp_state; nfnl_ct_tcp_state2str; nfnl_ct_test_bytes; nfnl_ct_test_dst_port; nfnl_ct_test_icmp_code; nfnl_ct_test_icmp_id; nfnl_ct_test_icmp_type; nfnl_ct_test_id; nfnl_ct_test_mark; nfnl_ct_test_packets; nfnl_ct_test_proto; nfnl_ct_test_src_port; nfnl_ct_test_status; nfnl_ct_test_tcp_state; nfnl_ct_test_timeout; nfnl_ct_test_timestamp; nfnl_ct_test_use; nfnl_ct_test_zone; nfnl_ct_unset_status; nfnl_exp_add; nfnl_exp_alloc; nfnl_exp_alloc_cache; nfnl_exp_build_add_request; nfnl_exp_build_delete_request; nfnl_exp_build_query_request; nfnl_exp_del; nfnl_exp_dump_request; nfnl_exp_flags2str; nfnl_exp_get; nfnl_exp_get_class; nfnl_exp_get_dst; nfnl_exp_get_dst_port; nfnl_exp_get_family; nfnl_exp_get_flags; nfnl_exp_get_fn; nfnl_exp_get_helper_name; nfnl_exp_get_icmp_code; nfnl_exp_get_icmp_id; nfnl_exp_get_icmp_type; nfnl_exp_get_id; nfnl_exp_get_l4protonum; nfnl_exp_get_nat_dir; nfnl_exp_get_src; nfnl_exp_get_src_port; nfnl_exp_get_timeout; nfnl_exp_get_zone; nfnl_exp_put; nfnl_exp_query; nfnl_exp_set_class; nfnl_exp_set_dst; nfnl_exp_set_family; nfnl_exp_set_flags; nfnl_exp_set_fn; nfnl_exp_set_helper_name; nfnl_exp_set_icmp; nfnl_exp_set_id; nfnl_exp_set_l4protonum; nfnl_exp_set_nat_dir; nfnl_exp_set_ports; nfnl_exp_set_src; nfnl_exp_set_timeout; nfnl_exp_set_zone; nfnl_exp_str2flags; nfnl_exp_test_class; nfnl_exp_test_dst; nfnl_exp_test_flags; nfnl_exp_test_fn; nfnl_exp_test_helper_name; nfnl_exp_test_icmp; nfnl_exp_test_id; nfnl_exp_test_l4protonum; nfnl_exp_test_nat_dir; nfnl_exp_test_ports; nfnl_exp_test_src; nfnl_exp_test_timeout; nfnl_exp_test_zone; nfnl_exp_unset_flags; nfnl_inet_hook2str; nfnl_log_alloc; nfnl_log_build_change_request; nfnl_log_build_create_request; nfnl_log_build_delete_request; nfnl_log_build_pf_bind; nfnl_log_build_pf_unbind; nfnl_log_change; nfnl_log_copy_mode2str; nfnl_log_create; nfnl_log_delete; nfnl_log_flags2str; nfnl_log_get; nfnl_log_get_alloc_size; nfnl_log_get_copy_mode; nfnl_log_get_copy_range; nfnl_log_get_flush_timeout; nfnl_log_get_group; nfnl_log_get_queue_threshold; nfnl_log_msg_alloc; nfnl_log_msg_get; nfnl_log_msg_get_family; nfnl_log_msg_get_gid; nfnl_log_msg_get_hook; nfnl_log_msg_get_hwaddr; nfnl_log_msg_get_hwproto; nfnl_log_msg_get_indev; nfnl_log_msg_get_mark; nfnl_log_msg_get_outdev; nfnl_log_msg_get_payload; nfnl_log_msg_get_physindev; nfnl_log_msg_get_physoutdev; nfnl_log_msg_get_prefix; nfnl_log_msg_get_seq; nfnl_log_msg_get_seq_global; nfnl_log_msg_get_timestamp; nfnl_log_msg_get_uid; nfnl_log_msg_put; nfnl_log_msg_set_family; nfnl_log_msg_set_gid; nfnl_log_msg_set_hook; nfnl_log_msg_set_hwaddr; nfnl_log_msg_set_hwproto; nfnl_log_msg_set_indev; nfnl_log_msg_set_mark; nfnl_log_msg_set_outdev; nfnl_log_msg_set_payload; nfnl_log_msg_set_physindev; nfnl_log_msg_set_physoutdev; nfnl_log_msg_set_prefix; nfnl_log_msg_set_seq; nfnl_log_msg_set_seq_global; nfnl_log_msg_set_timestamp; nfnl_log_msg_set_uid; nfnl_log_msg_test_gid; nfnl_log_msg_test_hook; nfnl_log_msg_test_hwproto; nfnl_log_msg_test_mark; nfnl_log_msg_test_seq; nfnl_log_msg_test_seq_global; nfnl_log_msg_test_uid; nfnl_log_pf_bind; nfnl_log_pf_unbind; nfnl_log_put; nfnl_log_set_alloc_size; nfnl_log_set_copy_mode; nfnl_log_set_copy_range; nfnl_log_set_flags; nfnl_log_set_flush_timeout; nfnl_log_set_group; nfnl_log_set_queue_threshold; nfnl_log_str2copy_mode; nfnl_log_str2flags; nfnl_log_test_alloc_size; nfnl_log_test_copy_mode; nfnl_log_test_copy_range; nfnl_log_test_flush_timeout; nfnl_log_test_group; nfnl_log_test_queue_threshold; nfnl_log_unset_flags; nfnl_queue_alloc; nfnl_queue_build_change_request; nfnl_queue_build_create_request; nfnl_queue_build_delete_request; nfnl_queue_build_pf_bind; nfnl_queue_build_pf_unbind; nfnl_queue_change; nfnl_queue_copy_mode2str; nfnl_queue_create; nfnl_queue_delete; nfnl_queue_get; nfnl_queue_get_copy_mode; nfnl_queue_get_copy_range; nfnl_queue_get_group; nfnl_queue_get_maxlen; nfnl_queue_msg_alloc; nfnl_queue_msg_build_verdict; nfnl_queue_msg_build_verdict_batch; nfnl_queue_msg_get; nfnl_queue_msg_get_family; nfnl_queue_msg_get_group; nfnl_queue_msg_get_hook; nfnl_queue_msg_get_hwaddr; nfnl_queue_msg_get_hwproto; nfnl_queue_msg_get_indev; nfnl_queue_msg_get_mark; nfnl_queue_msg_get_outdev; nfnl_queue_msg_get_packetid; nfnl_queue_msg_get_payload; nfnl_queue_msg_get_physindev; nfnl_queue_msg_get_physoutdev; nfnl_queue_msg_get_timestamp; nfnl_queue_msg_get_verdict; nfnl_queue_msg_put; nfnl_queue_msg_send_verdict; nfnl_queue_msg_send_verdict_batch; nfnl_queue_msg_send_verdict_payload; nfnl_queue_msg_set_family; nfnl_queue_msg_set_group; nfnl_queue_msg_set_hook; nfnl_queue_msg_set_hwaddr; nfnl_queue_msg_set_hwproto; nfnl_queue_msg_set_indev; nfnl_queue_msg_set_mark; nfnl_queue_msg_set_outdev; nfnl_queue_msg_set_packetid; nfnl_queue_msg_set_payload; nfnl_queue_msg_set_physindev; nfnl_queue_msg_set_physoutdev; nfnl_queue_msg_set_timestamp; nfnl_queue_msg_set_verdict; nfnl_queue_msg_test_family; nfnl_queue_msg_test_group; nfnl_queue_msg_test_hook; nfnl_queue_msg_test_hwaddr; nfnl_queue_msg_test_hwproto; nfnl_queue_msg_test_indev; nfnl_queue_msg_test_mark; nfnl_queue_msg_test_outdev; nfnl_queue_msg_test_packetid; nfnl_queue_msg_test_payload; nfnl_queue_msg_test_physindev; nfnl_queue_msg_test_physoutdev; nfnl_queue_msg_test_timestamp; nfnl_queue_msg_test_verdict; nfnl_queue_pf_bind; nfnl_queue_pf_unbind; nfnl_queue_put; nfnl_queue_set_copy_mode; nfnl_queue_set_copy_range; nfnl_queue_set_group; nfnl_queue_set_maxlen; nfnl_queue_socket_alloc; nfnl_queue_str2copy_mode; nfnl_queue_test_copy_mode; nfnl_queue_test_copy_range; nfnl_queue_test_group; nfnl_queue_test_maxlen; nfnl_send_simple; nfnl_str2inet_hook; nfnl_str2verdict; nfnl_verdict2str; nfnlmsg_alloc_simple; nfnlmsg_ct_group; nfnlmsg_ct_parse; nfnlmsg_exp_group; nfnlmsg_exp_parse; nfnlmsg_family; nfnlmsg_log_msg_parse; nfnlmsg_put; nfnlmsg_queue_msg_parse; nfnlmsg_res_id; nfnlmsg_subsys; nfnlmsg_subtype; local: *; }; libnl-3.2.29/etc/0000755000175000017500000000000013031473755010473 500000000000000libnl-3.2.29/etc/classid0000644000175000017500000000215213023014600011735 00000000000000############################################################################### # # ClassID <-> Name Translation Table # # This file can be used to assign names to classids for easier reference # in all libnl tools. # # Format: # # qdisc definition # # class deifnition # # class definition referencing an # existing qdisc definition. # # Example: # 1: top # top -> 1:0 # top:1 interactive # interactive -> 1:1 # top:2 www # www -> 1:2 # top:3 bulk # bulk -> 1:3 # 2:1 test_class # test_class -> 2:1 # # Illegal Example: # 30:1 classD # classD:2 invalidClass # classD refers to a class, not a qdisc # ############################################################################### # # Reserved default classids 0:0 none ffff:ffff root ffff:fff1 ingress # # List your classid definitions here: # ############################################################################### # List of auto-generated classids # # DO NOT ADD CLASSID DEFINITIONS BELOW THIS LINE # # libnl-3.2.29/etc/pktloc0000644000175000017500000000277413023014600011621 00000000000000# # Location definitions for packet matching # # name alignment offset mask shift ip.version u8 net+0 0xF0 4 ip.hdrlen u8 net+0 0x0F ip.diffserv u8 net+1 ip.length u16 net+2 ip.id u16 net+4 ip.flag.res u8 net+6 0xff 7 ip.df u8 net+6 0x40 6 ip.mf u8 net+6 0x20 5 ip.offset u16 net+6 0x1FFF ip.ttl u8 net+8 ip.proto u8 net+9 ip.chksum u16 net+10 ip.src u32 net+12 ip.dst u32 net+16 # if ip.ihl > 5 ip.opts u32 net+20 # # IP version 6 # # name alignment offset mask shift ip6.version u8 net+0 0xF0 4 ip6.tc u16 net+0 0xFF0 4 ip6.flowlabel u32 net+0 0xFFFFF ip6.length u16 net+4 ip6.nexthdr u8 net+6 ip6.hoplimit u8 net+7 ip6.src 16 net+8 ip6.dst 16 net+24 # # Transmission Control Protocol (TCP) # # name alignment offset mask shift tcp.sport u16 tcp+0 tcp.dport u16 tcp+2 tcp.seq u32 tcp+4 tcp.ack u32 tcp+8 # Data offset (4 bits) tcp.off u8 tcp+12 0xF0 4 # Reserved [0 0 0] (3 bits) tcp.reserved u8 tcp+12 0x04 1 # ECN [N C E] (3 bits) tcp.ecn u16 tcp+12 0x01C00 6 # Individual TCP flags (0|1) (6 bits in total) tcp.flag.urg u8 tcp+13 0x20 5 tcp.flag.ack u8 tcp+13 0x10 4 tcp.flag.psh u8 tcp+13 0x08 3 tcp.flag.rst u8 tcp+13 0x04 2 tcp.flag.syn u8 tcp+13 0x02 1 tcp.flag.fin u8 tcp+13 0x01 tcp.win u16 tcp+14 tcp.csum u16 tcp+16 tcp.urg u16 tcp+18 tcp.opts u32 tcp+20 # # User Datagram Protocol (UDP) # # name alignment offset mask shift udp.sport u16 tcp+0 udp.dport u16 tcp+2 udp.length u16 tcp+4 udp.csum u16 tcp+6 libnl-3.2.29/configure.ac0000644000175000017500000001513313031472460012121 00000000000000# # configure.in # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation version 2.1 # of the License. # # Copyright (c) 2003-2013 Thomas Graf # # copied from glib m4_define([libnl_major_version], [3]) m4_define([libnl_minor_version], [2]) m4_define([libnl_micro_version], [29]) m4_define([libnl_git_sha], [m4_esyscmd([ ( [ -d ./.git/ ] && [ "$(readlink -f ./.git/)" = "$(readlink -f "$(git rev-parse --git-dir 2>/dev/null)" 2>/dev/null)" ] && git rev-parse --verify -q HEAD 2>/dev/null ) || true ])]) # The following explanation may help to understand the above rules a bit # better: consider that there are three possible kinds of reactions from # users of your library to changes in a shared library: # # 1. Programs using the previous version may use the new version as drop-in # replacement, and programs using the new version can also work with the # previous one. In other words, no recompiling nor relinking is needed. # In this case, bump revision only, don't touch current nor age. # # 2. Programs using the previous version may use the new version as drop-in # replacement, but programs using the new version may use APIs not # present in the previous one. In other words, a program linking against # the new version may fail with “unresolved symbols” if linking against # the old version at runtime: set revision to 0, bump current and age. # # 3. Programs may need to be changed, recompiled, relinked in order to use # the new version. Bump current, set revision and age to 0. m4_define([libnl_lt_current], [224]) m4_define([libnl_lt_revision], [0]) m4_define([libnl_lt_age], [24]) m4_define([libnl_version], [libnl_major_version.libnl_minor_version.libnl_micro_version]) AC_INIT(libnl, [libnl_version], [], [], [http://www.infradead.org/~tgr/libnl/]) AC_CONFIG_HEADERS([lib/defs.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)], []) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) MAJ_VERSION=libnl_major_version AC_SUBST(MAJ_VERSION) MIN_VERSION=libnl_minor_version AC_SUBST(MIN_VERSION) MIC_VERSION=libnl_micro_version AC_SUBST(MIC_VERSION) LIBNL_GIT_SHA=libnl_git_sha LIBNL_VERSION=libnl_version AC_SUBST(LIBNL_VERSION) LT_CURRENT=libnl_lt_current AC_SUBST(LT_CURRENT) LT_REVISION=libnl_lt_revision AC_SUBST(LT_REVISION) LT_AGE=libnl_lt_age AC_SUBST(LT_AGE) AC_PROG_CC AM_PROG_CC_C_O AC_PROG_INSTALL AM_PROG_LIBTOOL AC_PROG_MKDIR_P AC_CHECK_PROGS(FLEX, 'flex') AC_CHECK_PROGS(YACC, 'bison -y') AC_C_CONST AC_C_INLINE PKG_CHECK_MODULES([CHECK], [check >= 0.9.0], [enable_unit_tests="yes"], [AC_MSG_WARN([*** Disabling building of unit tests]) enable_unit_tests="no"]) AM_CONDITIONAL([ENABLE_UNIT_TESTS], [test "$enable_unit_tests" = "yes"]) AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH], [Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]), [pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig']) AC_SUBST([pkgconfigdir]) AC_ARG_ENABLE([cli], AS_HELP_STRING([--enable-cli=yes|no|no-inst|bin|sbin], [Whether to build command line interface utils. Defaults to 'yes' which is a synonym for 'bin'. 'no-inst' means only build, not installing. 'bin'/'sbin' means installing to bin/sbin directory]), [enable_cli="$enableval"], [enable_cli="yes"]) if test "$enable_cli" != "no" && test "$enable_cli" != "no-inst" && test "$enable_cli" != "sbin"; then enable_cli="bin" fi AM_CONDITIONAL([ENABLE_CLI], [test "$enable_cli" != "no"]) AM_CONDITIONAL([ENABLE_CLI_INSTALL_BIN], [test "$enable_cli" = "bin"]) AM_CONDITIONAL([ENABLE_CLI_INSTALL_SBIN], [test "$enable_cli" = "sbin"]) AC_ARG_ENABLE([pthreads], AS_HELP_STRING([--disable-pthreads], [Disable pthreads support]), [enable_pthreads="$enableval"], [enable_pthreads="yes"]) AM_CONDITIONAL([DISABLE_PTHREADS], [test "$enable_pthreads" = "no"]) AC_ARG_ENABLE([debug], AS_HELP_STRING([--disable-debug], [Do not include debugging statements]), [enable_debug="$enableval"], [enable_debug="yes"]) AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = "no" ]) AC_CHECK_LIB([m], [pow], [], AC_MSG_ERROR([libm is required])) if test "x$enable_pthreads" = "xno"; then AC_DEFINE([DISABLE_PTHREADS], [1], [Define to 1 to disable pthreads]) else AC_CHECK_LIB([pthread], [pthread_mutex_lock], [], AC_MSG_ERROR([libpthread is required])) fi if test "x$enable_debug" = "xyes"; then AC_DEFINE([NL_DEBUG], [1], [Define to 1 to enable debugging]) fi AC_CONFIG_SUBDIRS([doc]) AC_CONFIG_FILES([ Makefile libnl-3.0.pc libnl-route-3.0.pc libnl-genl-3.0.pc libnl-nf-3.0.pc libnl-cli-3.0.pc libnl-xfrm-3.0.pc libnl-idiag-3.0.pc lib/Makefile include/Makefile src/Makefile src/lib/Makefile tests/Makefile man/Makefile python/Makefile python/setup.py python/doc/Makefile python/examples/Makefile python/netlink/Makefile python/netlink/genl/Makefile python/netlink/route/Makefile python/tests/Makefile include/netlink/version.h ]) ac_errcount=0 if test -z "$YACC"; then AC_MSG_WARN(bison not found. Please install before continuing.) ac_errcount=$((ac_errcount + 1)) fi if test -z "$FLEX"; then AC_MSG_WARN(flex not found. Please install before continuing.) ac_errcount=$((ac_errcount + 1)) fi if test $ac_errcount -gt 0; then AC_MSG_ERROR(Required packages are missing. Please install them and rerun ./configure) fi AC_OUTPUT echo "-------------------------------------------------------------------------------" echo " NOTE" echo "" echo " There have been some changes starting with 3.2 regarding where and how libnl" echo " is being installed on the system in order to allow multiple libnl versions" echo " to be installed in parallel:" echo "" echo " - Headers will be installed in ${includedir}/libnl${MAJ_VERSION}, therefore" echo " you will need to add \"-I/usr/include/libnl${MAJ_VERSION}\" to CFLAGS" echo "" echo " - The library basename was renamed to libnl-${MAJ_VERSION}, i.e. the SO names become" echo " libnl-${MAJ_VERSION}.so., libnl-route-${MAJ_VERSION}.so, etc." echo "" echo " - libtool versioning was assumed, to ease detection of compatible library" echo " versions." echo "" echo " If you are using pkg-config for detecting and linking against the library " echo " things will continue magically as if nothing every happened. If you are " echo " linking manually you need to adapt your Makefiles or switch to using " echo " pkg-config files." echo "" echo "-------------------------------------------------------------------------------" libnl-3.2.29/include/0000755000175000017500000000000013031473756011344 500000000000000libnl-3.2.29/include/Makefile.am0000644000175000017500000001170413023014600013277 00000000000000# -*- Makefile -*- libnlincludedir = $(includedir)/libnl@MAJ_VERSION@ nobase_libnlinclude_HEADERS = \ netlink/fib_lookup/lookup.h \ netlink/fib_lookup/request.h \ netlink/genl/ctrl.h \ netlink/genl/family.h \ netlink/genl/genl.h \ netlink/genl/mngt.h \ netlink/netfilter/ct.h \ netlink/netfilter/exp.h \ netlink/netfilter/log.h \ netlink/netfilter/log_msg.h \ netlink/netfilter/netfilter.h \ netlink/netfilter/nfnl.h \ netlink/netfilter/queue.h \ netlink/netfilter/queue_msg.h \ netlink/addr.h \ netlink/attr.h \ netlink/cache.h \ netlink/data.h \ netlink/errno.h \ netlink/handlers.h \ netlink/hash.h \ netlink/hashtable.h \ netlink/list.h \ netlink/msg.h \ netlink/netlink-compat.h \ netlink/netlink-kernel.h \ netlink/netlink.h \ netlink/object.h \ netlink/route/action.h \ netlink/route/act/mirred.h \ netlink/route/act/skbedit.h \ netlink/route/act/gact.h \ netlink/route/cls/ematch/cmp.h \ netlink/route/cls/ematch/meta.h \ netlink/route/cls/ematch/nbyte.h \ netlink/route/cls/ematch/text.h \ netlink/route/cls/basic.h \ netlink/route/cls/cgroup.h \ netlink/route/cls/ematch.h \ netlink/route/cls/fw.h \ netlink/route/cls/police.h \ netlink/route/cls/u32.h \ netlink/route/link/api.h \ netlink/route/link/bonding.h \ netlink/route/link/bridge.h \ netlink/route/link/can.h \ netlink/route/link/inet.h \ netlink/route/link/inet6.h \ netlink/route/link/info-api.h \ netlink/route/link/macsec.h \ netlink/route/link/macvlan.h \ netlink/route/link/macvtap.h \ netlink/route/link/vlan.h \ netlink/route/link/vxlan.h \ netlink/route/link/veth.h \ netlink/route/link/ip6tnl.h \ netlink/route/link/ipgre.h \ netlink/route/link/ipip.h \ netlink/route/link/ipvti.h \ netlink/route/link/sit.h \ netlink/route/link/ipvlan.h \ netlink/route/link/vrf.h \ netlink/route/link/sriov.h \ netlink/route/link/ppp.h \ netlink/route/qdisc/cbq.h \ netlink/route/qdisc/dsmark.h \ netlink/route/qdisc/fifo.h \ netlink/route/qdisc/htb.h \ netlink/route/qdisc/netem.h \ netlink/route/qdisc/prio.h \ netlink/route/qdisc/red.h \ netlink/route/qdisc/sfq.h \ netlink/route/qdisc/tbf.h \ netlink/route/qdisc/plug.h \ netlink/route/qdisc/fq_codel.h \ netlink/route/qdisc/hfsc.h \ netlink/route/addr.h \ netlink/route/class.h \ netlink/route/classifier.h \ netlink/route/link.h \ netlink/route/neighbour.h \ netlink/route/neightbl.h \ netlink/route/nexthop.h \ netlink/route/pktloc.h \ netlink/route/qdisc.h \ netlink/route/route.h \ netlink/route/rtnl.h \ netlink/route/rule.h \ netlink/route/tc.h \ netlink/socket.h \ netlink/types.h \ netlink/utils.h \ netlink/version.h \ netlink/cache-api.h \ netlink/object-api.h \ netlink/route/tc-api.h \ netlink/idiag/idiagnl.h \ netlink/idiag/meminfo.h \ netlink/idiag/msg.h \ netlink/idiag/req.h \ netlink/idiag/vegasinfo.h \ netlink/xfrm/ae.h \ netlink/xfrm/lifetime.h \ netlink/xfrm/sa.h \ netlink/xfrm/selector.h \ netlink/xfrm/sp.h \ netlink/xfrm/template.h if ENABLE_CLI nobase_libnlinclude_HEADERS += \ netlink/cli/addr.h \ netlink/cli/class.h \ netlink/cli/cls.h \ netlink/cli/ct.h \ netlink/cli/exp.h \ netlink/cli/link.h \ netlink/cli/neigh.h \ netlink/cli/qdisc.h \ netlink/cli/route.h \ netlink/cli/rule.h \ netlink/cli/tc.h \ netlink/cli/utils.h endif noinst_HEADERS = \ linux-private/linux/fib_rules.h \ linux-private/linux/genetlink.h \ linux-private/linux/gen_stats.h \ linux-private/linux/if_addr.h \ linux-private/linux/if_arp.h \ linux-private/linux/if_ether.h \ linux-private/linux/if.h \ linux-private/linux/if_bridge.h \ linux-private/linux/if_link.h \ linux-private/linux/if_macsec.h \ linux-private/linux/if_tunnel.h \ linux-private/linux/if_vlan.h \ linux-private/linux/inet_diag.h \ linux-private/linux/ip.h \ linux-private/linux/ip_mp_alg.h \ linux-private/linux/ipv6.h \ linux-private/linux/can/netlink.h \ linux-private/linux/neighbour.h \ linux-private/linux/netfilter.h \ linux-private/linux/netfilter/nf_conntrack_common.h \ linux-private/linux/netfilter/nfnetlink_compat.h \ linux-private/linux/netfilter/nfnetlink_conntrack.h \ linux-private/linux/netfilter/nfnetlink.h \ linux-private/linux/netfilter/nfnetlink_log.h \ linux-private/linux/netfilter/nfnetlink_queue.h \ linux-private/linux/netlink.h \ linux-private/linux/pkt_cls.h \ linux-private/linux/sock_diag.h \ linux-private/linux/socket.h \ linux-private/linux/tc_act/tc_mirred.h \ linux-private/linux/tc_act/tc_skbedit.h \ linux-private/linux/tc_act/tc_gact.h \ linux-private/linux/pkt_sched.h \ linux-private/linux/rtnetlink.h \ linux-private/linux/snmp.h \ linux-private/linux/veth.h \ linux-private/linux/xfrm.h \ linux-private/linux/tc_ematch/tc_em_meta.h \ netlink-private/genl.h \ netlink-private/netlink.h \ netlink-private/socket.h \ netlink-private/tc.h \ netlink-private/types.h \ netlink-private/utils.h \ netlink-private/cache-api.h \ netlink-private/object-api.h \ netlink-private/route/link/api.h \ netlink-private/route/link/sriov.h \ netlink-private/route/tc-api.h libnl-3.2.29/include/netlink-private/0000755000175000017500000000000013031473756014460 500000000000000libnl-3.2.29/include/netlink-private/utils.h0000644000175000017500000000163613024561717015714 00000000000000/* * netlink-private/utils.h Local Utility Functions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_UTILS_PRIV_H_ #define NETLINK_UTILS_PRIV_H_ #include #if __BYTE_ORDER == __BIG_ENDIAN #define ntohll(x) (x) #elif __BYTE_ORDER == __LITTLE_ENDIAN #define ntohll(x) bswap_64((x)) #endif #define htonll(x) ntohll(x) extern const char * nl_strerror_l(int err); /* internal macro to calculate the size of a struct @type up to (and including) @field. * this will be used for .minlen policy fields, so that we require only a field of up * to the given size. */ #define _nl_offsetofend(type, field) (offsetof (type, field) + sizeof (((type *) NULL)->field)) #endif libnl-3.2.29/include/netlink-private/types.h0000644000175000017500000006363613023014600015707 00000000000000/* * netlink-private/types.h Netlink Types (Private) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf * Copyright (c) 2013 Sassano Systems LLC */ #ifndef NETLINK_LOCAL_TYPES_H_ #define NETLINK_LOCAL_TYPES_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #define NL_SOCK_PASSCRED (1<<1) #define NL_OWN_PORT (1<<2) #define NL_MSG_PEEK (1<<3) #define NL_MSG_PEEK_EXPLICIT (1<<4) #define NL_NO_AUTO_ACK (1<<5) #define NL_MSG_CRED_PRESENT 1 struct nl_cache_ops; struct nl_sock; struct nl_object; struct nl_hash_table; struct nl_vf_vlans; struct nl_cb { nl_recvmsg_msg_cb_t cb_set[NL_CB_TYPE_MAX+1]; void * cb_args[NL_CB_TYPE_MAX+1]; nl_recvmsg_err_cb_t cb_err; void * cb_err_arg; /** May be used to replace nl_recvmsgs with your own implementation * in all internal calls to nl_recvmsgs. */ int (*cb_recvmsgs_ow)(struct nl_sock *, struct nl_cb *); /** Overwrite internal calls to nl_recv, must return the number of * octets read and allocate a buffer for the received data. */ int (*cb_recv_ow)(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **); /** Overwrites internal calls to nl_send, must send the netlink * message. */ int (*cb_send_ow)(struct nl_sock *, struct nl_msg *); int cb_refcnt; /** indicates the callback that is currently active */ enum nl_cb_type cb_active; }; struct nl_sock { struct sockaddr_nl s_local; struct sockaddr_nl s_peer; int s_fd; int s_proto; unsigned int s_seq_next; unsigned int s_seq_expect; int s_flags; struct nl_cb * s_cb; size_t s_bufsize; }; struct nl_cache { struct nl_list_head c_items; int c_nitems; int c_iarg1; int c_iarg2; int c_refcnt; unsigned int c_flags; struct nl_hash_table * hashtable; struct nl_cache_ops * c_ops; }; struct nl_cache_assoc { struct nl_cache * ca_cache; change_func_t ca_change; change_func_v2_t ca_change_v2; void * ca_change_data; }; struct nl_cache_mngr { int cm_protocol; int cm_flags; int cm_nassocs; struct nl_sock * cm_sock; struct nl_sock * cm_sync_sock; struct nl_cache_assoc * cm_assocs; }; struct nl_parser_param; #define LOOSE_COMPARISON 1 #define ID_COMPARISON 2 #define NL_OBJ_MARK 1 struct nl_data { size_t d_size; void * d_data; }; struct nl_addr { int a_family; unsigned int a_maxsize; unsigned int a_len; int a_prefixlen; int a_refcnt; char a_addr[0]; }; struct nl_msg { int nm_protocol; int nm_flags; struct sockaddr_nl nm_src; struct sockaddr_nl nm_dst; struct ucred nm_creds; struct nlmsghdr * nm_nlh; size_t nm_size; int nm_refcnt; }; struct rtnl_link_map { uint64_t lm_mem_start; uint64_t lm_mem_end; uint64_t lm_base_addr; uint16_t lm_irq; uint8_t lm_dma; uint8_t lm_port; }; struct rtnl_link_vf { struct nl_list_head vf_list; int ce_refcnt; uint32_t ce_mask; uint32_t vf_index; uint64_t vf_guid_node; uint64_t vf_guid_port; uint32_t vf_linkstate; struct nl_addr * vf_lladdr; uint32_t vf_max_tx_rate; uint32_t vf_min_tx_rate; uint32_t vf_rate; uint32_t vf_rss_query_en; uint32_t vf_spoofchk; uint64_t vf_stats[RTNL_LINK_VF_STATS_MAX+1]; uint32_t vf_trust; struct nl_vf_vlans * vf_vlans; }; #define IFQDISCSIZ 32 struct rtnl_link { NLHDR_COMMON char l_name[IFNAMSIZ]; uint32_t l_family; uint32_t l_arptype; uint32_t l_index; uint32_t l_flags; uint32_t l_change; uint32_t l_mtu; uint32_t l_link; int32_t l_link_netnsid; uint32_t l_txqlen; uint32_t l_weight; uint32_t l_master; struct nl_addr * l_addr; struct nl_addr * l_bcast; char l_qdisc[IFQDISCSIZ]; struct rtnl_link_map l_map; uint64_t l_stats[RTNL_LINK_STATS_MAX+1]; uint32_t l_flag_mask; uint32_t l_num_vf; uint8_t l_operstate; uint8_t l_linkmode; /* 2 byte hole */ char * l_info_kind; struct rtnl_link_info_ops * l_info_ops; void * l_af_data[AF_MAX]; void * l_info; char * l_ifalias; uint32_t l_promiscuity; uint32_t l_num_tx_queues; uint32_t l_num_rx_queues; uint32_t l_gso_max_segs; uint32_t l_gso_max_size; uint32_t l_group; uint8_t l_carrier; /* 3 byte hole */ uint32_t l_carrier_changes; struct rtnl_link_af_ops * l_af_ops; struct nl_data * l_phys_port_id; char l_phys_port_name[IFNAMSIZ]; struct nl_data * l_phys_switch_id; int l_ns_fd; pid_t l_ns_pid; struct rtnl_link_vf * l_vf_list; }; struct rtnl_ncacheinfo { uint32_t nci_confirmed; /**< Time since neighbour validty was last confirmed */ uint32_t nci_used; /**< Time since neighbour entry was last ued */ uint32_t nci_updated; /**< Time since last update */ uint32_t nci_refcnt; /**< Reference counter */ }; struct rtnl_neigh { NLHDR_COMMON uint32_t n_family; uint32_t n_ifindex; uint16_t n_state; uint8_t n_flags; uint8_t n_type; struct nl_addr *n_lladdr; struct nl_addr *n_dst; uint32_t n_probes; struct rtnl_ncacheinfo n_cacheinfo; uint32_t n_state_mask; uint32_t n_flag_mask; uint32_t n_master; uint16_t n_vlan; }; struct rtnl_addr_cacheinfo { /* Preferred lifetime in seconds, ticking from when the message gets constructed */ uint32_t aci_prefered; /* Valid lifetime in seconds, ticking from when the message gets constructed */ uint32_t aci_valid; /* Timestamp of creation in 1/100s since boottime, clock_gettime(CLOCK_MONOTONIC) */ uint32_t aci_cstamp; /* Timestamp of last update in 1/100s since boottime, clock_gettime(CLOCK_MONOTONIC) */ uint32_t aci_tstamp; }; struct rtnl_addr { NLHDR_COMMON uint8_t a_family; uint8_t a_prefixlen; uint8_t a_scope; uint32_t a_flags; uint32_t a_ifindex; struct nl_addr *a_peer; struct nl_addr *a_local; struct nl_addr *a_bcast; struct nl_addr *a_anycast; struct nl_addr *a_multicast; struct rtnl_addr_cacheinfo a_cacheinfo; char a_label[IFNAMSIZ]; uint32_t a_flag_mask; struct rtnl_link *a_link; }; struct rtnl_nexthop { uint8_t rtnh_flags; uint8_t rtnh_flag_mask; uint8_t rtnh_weight; /* 1 byte spare */ uint32_t rtnh_ifindex; struct nl_addr * rtnh_gateway; uint32_t ce_mask; /* HACK to support attr macros */ struct nl_list_head rtnh_list; uint32_t rtnh_realms; }; struct rtnl_route { NLHDR_COMMON uint8_t rt_family; uint8_t rt_dst_len; uint8_t rt_src_len; uint8_t rt_tos; uint8_t rt_protocol; uint8_t rt_scope; uint8_t rt_type; uint8_t rt_nmetrics; uint32_t rt_flags; struct nl_addr * rt_dst; struct nl_addr * rt_src; uint32_t rt_table; uint32_t rt_iif; uint32_t rt_prio; uint32_t rt_metrics[RTAX_MAX]; uint32_t rt_metrics_mask; uint32_t rt_nr_nh; struct nl_addr * rt_pref_src; struct nl_list_head rt_nexthops; struct rtnl_rtcacheinfo rt_cacheinfo; uint32_t rt_flag_mask; }; struct rtnl_rule { NLHDR_COMMON uint8_t r_family; uint8_t r_action; uint8_t r_dsfield; /* ipv4 only */ uint8_t r_unused; uint32_t r_table; uint32_t r_flags; uint32_t r_prio; uint32_t r_mark; uint32_t r_mask; uint32_t r_goto; uint32_t r_flow; /* ipv4 only */ struct nl_addr *r_src; struct nl_addr *r_dst; char r_iifname[IFNAMSIZ]; char r_oifname[IFNAMSIZ]; }; struct rtnl_neightbl_parms { /** * Interface index of the device this parameter set is assigned * to or 0 for the default set. */ uint32_t ntp_ifindex; /** * Number of references to this parameter set. */ uint32_t ntp_refcnt; /** * Queue length for pending arp requests, i.e. the number of * packets which are accepted from other layers while the * neighbour address is still being resolved */ uint32_t ntp_queue_len; /** * Number of requests to send to the user level ARP daemon. * Specify 0 to disable. */ uint32_t ntp_app_probes; /** * Maximum number of retries for unicast solicitation. */ uint32_t ntp_ucast_probes; /** * Maximum number of retries for multicast solicitation. */ uint32_t ntp_mcast_probes; /** * Base value in milliseconds to ompute reachable time, see RFC2461. */ uint64_t ntp_base_reachable_time; /** * Actual reachable time (read-only) */ uint64_t ntp_reachable_time; /* secs */ /** * The time in milliseconds between retransmitted Neighbor * Solicitation messages. */ uint64_t ntp_retrans_time; /** * Interval in milliseconds to check for stale neighbour * entries. */ uint64_t ntp_gc_stale_time; /* secs */ /** * Delay in milliseconds for the first time probe if * the neighbour is reachable. */ uint64_t ntp_probe_delay; /* secs */ /** * Maximum delay in milliseconds of an answer to a neighbour * solicitation message. */ uint64_t ntp_anycast_delay; /** * Minimum age in milliseconds before a neighbour entry * may be replaced. */ uint64_t ntp_locktime; /** * Delay in milliseconds before answering to an ARP request * for which a proxy ARP entry exists. */ uint64_t ntp_proxy_delay; /** * Queue length for the delayed proxy arp requests. */ uint32_t ntp_proxy_qlen; /** * Mask of available parameter attributes */ uint32_t ntp_mask; }; #define NTBLNAMSIZ 32 /** * Neighbour table * @ingroup neightbl */ struct rtnl_neightbl { NLHDR_COMMON char nt_name[NTBLNAMSIZ]; uint32_t nt_family; uint32_t nt_gc_thresh1; uint32_t nt_gc_thresh2; uint32_t nt_gc_thresh3; uint64_t nt_gc_interval; struct ndt_config nt_config; struct rtnl_neightbl_parms nt_parms; struct ndt_stats nt_stats; }; struct rtnl_ratespec { uint8_t rs_cell_log; uint16_t rs_overhead; int16_t rs_cell_align; uint16_t rs_mpu; uint32_t rs_rate; }; struct rtnl_tstats { struct { uint64_t bytes; uint64_t packets; } tcs_basic; struct { uint32_t bps; uint32_t pps; } tcs_rate_est; struct { uint32_t qlen; uint32_t backlog; uint32_t drops; uint32_t requeues; uint32_t overlimits; } tcs_queue; }; #define TCKINDSIZ 32 #define NL_TC_GENERIC(pre) \ NLHDR_COMMON \ uint32_t pre ##_family; \ uint32_t pre ##_ifindex; \ uint32_t pre ##_handle; \ uint32_t pre ##_parent; \ uint32_t pre ##_info; \ uint32_t pre ##_mtu; \ uint32_t pre ##_mpu; \ uint32_t pre ##_overhead; \ uint32_t pre ##_linktype; \ char pre ##_kind[TCKINDSIZ]; \ struct nl_data * pre ##_opts; \ uint64_t pre ##_stats[RTNL_TC_STATS_MAX+1]; \ struct nl_data * pre ##_xstats; \ struct nl_data * pre ##_subdata; \ struct rtnl_link * pre ##_link; \ struct rtnl_tc_ops * pre ##_ops; \ enum rtnl_tc_type pre ##_type struct rtnl_tc { NL_TC_GENERIC(tc); }; struct rtnl_qdisc { NL_TC_GENERIC(q); }; struct rtnl_class { NL_TC_GENERIC(c); }; struct rtnl_cls { NL_TC_GENERIC(c); uint16_t c_prio; uint16_t c_protocol; }; struct rtnl_act { NL_TC_GENERIC(c); struct rtnl_act * a_next; }; struct rtnl_mirred { struct tc_mirred m_parm; }; struct rtnl_skbedit { struct tc_skbedit s_parm; uint32_t s_flags; uint32_t s_mark; uint32_t s_prio; uint16_t s_queue_mapping; }; struct rtnl_gact { struct tc_gact g_parm; }; struct rtnl_u32 { uint32_t cu_divisor; uint32_t cu_hash; uint32_t cu_classid; uint32_t cu_link; struct nl_data * cu_pcnt; struct nl_data * cu_selector; struct nl_data * cu_mark; struct rtnl_act* cu_act; struct nl_data * cu_police; char cu_indev[IFNAMSIZ]; int cu_mask; }; struct rtnl_cgroup { struct rtnl_ematch_tree *cg_ematch; int cg_mask; }; struct rtnl_fw { uint32_t cf_classid; struct nl_data * cf_act; struct nl_data * cf_police; char cf_indev[IFNAMSIZ]; uint32_t cf_fwmask; int cf_mask; }; struct rtnl_ematch { uint16_t e_id; uint16_t e_kind; uint16_t e_flags; uint16_t e_index; size_t e_datalen; struct nl_list_head e_childs; struct nl_list_head e_list; struct rtnl_ematch_ops *e_ops; void * e_data; }; struct rtnl_ematch_tree { uint16_t et_progid; struct nl_list_head et_list; }; struct rtnl_dsmark_qdisc { uint16_t qdm_indices; uint16_t qdm_default_index; uint32_t qdm_set_tc_index; uint32_t qdm_mask; }; struct rtnl_dsmark_class { uint8_t cdm_bmask; uint8_t cdm_value; uint32_t cdm_mask; }; struct rtnl_fifo { uint32_t qf_limit; uint32_t qf_mask; }; struct rtnl_prio { uint32_t qp_bands; uint8_t qp_priomap[TC_PRIO_MAX+1]; uint32_t qp_mask; }; struct rtnl_tbf { uint32_t qt_limit; struct rtnl_ratespec qt_rate; uint32_t qt_rate_bucket; uint32_t qt_rate_txtime; struct rtnl_ratespec qt_peakrate; uint32_t qt_peakrate_bucket; uint32_t qt_peakrate_txtime; uint32_t qt_mask; }; struct rtnl_sfq { uint32_t qs_quantum; uint32_t qs_perturb; uint32_t qs_limit; uint32_t qs_divisor; uint32_t qs_flows; uint32_t qs_mask; }; struct rtnl_netem_corr { uint32_t nmc_delay; uint32_t nmc_loss; uint32_t nmc_duplicate; }; struct rtnl_netem_reo { uint32_t nmro_probability; uint32_t nmro_correlation; }; struct rtnl_netem_crpt { uint32_t nmcr_probability; uint32_t nmcr_correlation; }; struct rtnl_netem_dist { int16_t * dist_data; size_t dist_size; }; struct rtnl_netem { uint32_t qnm_latency; uint32_t qnm_limit; uint32_t qnm_loss; uint32_t qnm_gap; uint32_t qnm_duplicate; uint32_t qnm_jitter; uint32_t qnm_mask; struct rtnl_netem_corr qnm_corr; struct rtnl_netem_reo qnm_ro; struct rtnl_netem_crpt qnm_crpt; struct rtnl_netem_dist qnm_dist; }; struct rtnl_htb_qdisc { uint32_t qh_rate2quantum; uint32_t qh_defcls; uint32_t qh_mask; uint32_t qh_direct_pkts; }; struct rtnl_htb_class { uint32_t ch_prio; struct rtnl_ratespec ch_rate; struct rtnl_ratespec ch_ceil; uint32_t ch_rbuffer; uint32_t ch_cbuffer; uint32_t ch_quantum; uint32_t ch_mask; uint32_t ch_level; }; struct rtnl_cbq { struct tc_cbq_lssopt cbq_lss; struct tc_ratespec cbq_rate; struct tc_cbq_wrropt cbq_wrr; struct tc_cbq_ovl cbq_ovl; struct tc_cbq_fopt cbq_fopt; struct tc_cbq_police cbq_police; }; struct rtnl_red { uint32_t qr_limit; uint32_t qr_qth_min; uint32_t qr_qth_max; uint8_t qr_flags; uint8_t qr_wlog; uint8_t qr_plog; uint8_t qr_scell_log; uint32_t qr_mask; }; struct rtnl_plug { int action; uint32_t limit; }; struct rtnl_fq_codel { int fq_limit; uint32_t fq_target; uint32_t fq_interval; int fq_flows; uint32_t fq_quantum; int fq_ecn; uint32_t fq_mask; }; struct rtnl_hfsc_qdisc { uint32_t qh_defcls; uint32_t qh_mask; }; struct rtnl_hfsc_class { struct tc_service_curve ch_rsc; struct tc_service_curve ch_fsc; struct tc_service_curve ch_usc; uint32_t ch_mask; }; struct flnl_request { NLHDR_COMMON struct nl_addr * lr_addr; uint32_t lr_fwmark; uint8_t lr_tos; uint8_t lr_scope; uint8_t lr_table; }; struct flnl_result { NLHDR_COMMON struct flnl_request * fr_req; uint8_t fr_table_id; uint8_t fr_prefixlen; uint8_t fr_nh_sel; uint8_t fr_type; uint8_t fr_scope; uint32_t fr_error; }; #define GENL_OP_HAS_POLICY 1 #define GENL_OP_HAS_DOIT 2 #define GENL_OP_HAS_DUMPIT 4 struct genl_family_op { uint32_t o_id; uint32_t o_flags; struct nl_list_head o_list; }; struct genl_family_grp { struct genl_family *family; /* private */ struct nl_list_head list; /* private */ char name[GENL_NAMSIZ]; u_int32_t id; }; struct genl_family { NLHDR_COMMON uint16_t gf_id; char gf_name[GENL_NAMSIZ]; uint32_t gf_version; uint32_t gf_hdrsize; uint32_t gf_maxattr; struct nl_list_head gf_ops; struct nl_list_head gf_mc_grps; }; union nfnl_ct_proto { struct { uint16_t src; uint16_t dst; } port; struct { uint16_t id; uint8_t type; uint8_t code; } icmp; }; struct nfnl_ct_dir { struct nl_addr * src; struct nl_addr * dst; union nfnl_ct_proto proto; uint64_t packets; uint64_t bytes; }; union nfnl_ct_protoinfo { struct { uint8_t state; } tcp; }; struct nfnl_ct { NLHDR_COMMON uint8_t ct_family; uint8_t ct_proto; union nfnl_ct_protoinfo ct_protoinfo; uint32_t ct_status; uint32_t ct_status_mask; uint32_t ct_timeout; uint32_t ct_mark; uint32_t ct_use; uint32_t ct_id; uint16_t ct_zone; struct nfnl_ct_dir ct_orig; struct nfnl_ct_dir ct_repl; struct nfnl_ct_timestamp ct_tstamp; }; union nfnl_exp_protodata { struct { uint16_t src; uint16_t dst; } port; struct { uint16_t id; uint8_t type; uint8_t code; } icmp; }; // Allow for different master/expect l4 protocols struct nfnl_exp_proto { uint8_t l4protonum; union nfnl_exp_protodata l4protodata; }; struct nfnl_exp_dir { struct nl_addr * src; struct nl_addr * dst; struct nfnl_exp_proto proto; }; struct nfnl_exp { NLHDR_COMMON uint8_t exp_family; uint32_t exp_timeout; uint32_t exp_id; uint16_t exp_zone; uint32_t exp_class; uint32_t exp_flags; char * exp_helper_name; char * exp_fn; uint8_t exp_nat_dir; struct nfnl_exp_dir exp_expect; struct nfnl_exp_dir exp_master; struct nfnl_exp_dir exp_mask; struct nfnl_exp_dir exp_nat; }; struct nfnl_log { NLHDR_COMMON uint16_t log_group; uint8_t log_copy_mode; uint32_t log_copy_range; uint32_t log_flush_timeout; uint32_t log_alloc_size; uint32_t log_queue_threshold; uint32_t log_flags; uint32_t log_flag_mask; }; struct nfnl_log_msg { NLHDR_COMMON uint8_t log_msg_family; uint8_t log_msg_hook; uint16_t log_msg_hwproto; uint32_t log_msg_mark; struct timeval log_msg_timestamp; uint32_t log_msg_indev; uint32_t log_msg_outdev; uint32_t log_msg_physindev; uint32_t log_msg_physoutdev; uint8_t log_msg_hwaddr[8]; int log_msg_hwaddr_len; void * log_msg_payload; int log_msg_payload_len; char * log_msg_prefix; uint32_t log_msg_uid; uint32_t log_msg_gid; uint32_t log_msg_seq; uint32_t log_msg_seq_global; }; struct nfnl_queue { NLHDR_COMMON uint16_t queue_group; uint32_t queue_maxlen; uint32_t queue_copy_range; uint8_t queue_copy_mode; }; struct nfnl_queue_msg { NLHDR_COMMON uint16_t queue_msg_group; uint8_t queue_msg_family; uint8_t queue_msg_hook; uint16_t queue_msg_hwproto; uint32_t queue_msg_packetid; uint32_t queue_msg_mark; struct timeval queue_msg_timestamp; uint32_t queue_msg_indev; uint32_t queue_msg_outdev; uint32_t queue_msg_physindev; uint32_t queue_msg_physoutdev; uint8_t queue_msg_hwaddr[8]; int queue_msg_hwaddr_len; void * queue_msg_payload; int queue_msg_payload_len; uint32_t queue_msg_verdict; }; struct ematch_quoted { char * data; size_t len; int index; }; struct idiagnl_meminfo { NLHDR_COMMON uint32_t idiag_rmem; uint32_t idiag_wmem; uint32_t idiag_fmem; uint32_t idiag_tmem; }; struct idiagnl_vegasinfo { NLHDR_COMMON uint32_t tcpv_enabled; uint32_t tcpv_rttcnt; uint32_t tcpv_rtt; uint32_t tcpv_minrtt; }; struct idiagnl_msg { NLHDR_COMMON uint8_t idiag_family; uint8_t idiag_state; uint8_t idiag_timer; uint8_t idiag_retrans; uint16_t idiag_sport; uint16_t idiag_dport; struct nl_addr * idiag_src; struct nl_addr * idiag_dst; uint32_t idiag_ifindex; uint32_t idiag_expires; uint32_t idiag_rqueue; uint32_t idiag_wqueue; uint32_t idiag_uid; uint32_t idiag_inode; uint8_t idiag_tos; uint8_t idiag_tclass; uint8_t idiag_shutdown; char * idiag_cong; struct idiagnl_meminfo * idiag_meminfo; struct idiagnl_vegasinfo * idiag_vegasinfo; struct tcp_info idiag_tcpinfo; uint32_t idiag_skmeminfo[SK_MEMINFO_VARS]; }; struct idiagnl_req { NLHDR_COMMON uint8_t idiag_family; uint8_t idiag_ext; struct nl_addr * idiag_src; struct nl_addr * idiag_dst; uint32_t idiag_ifindex; uint32_t idiag_states; uint32_t idiag_dbs; }; // XFRM related definitions /* Selector, used as selector both on policy rules (SPD) and SAs. */ struct xfrmnl_sel { uint32_t refcnt; struct nl_addr* daddr; struct nl_addr* saddr; uint16_t dport; uint16_t dport_mask; uint16_t sport; uint16_t sport_mask; uint16_t family; uint8_t prefixlen_d; uint8_t prefixlen_s; uint8_t proto; int32_t ifindex; uint32_t user; }; /* Lifetime configuration, used for both policy rules (SPD) and SAs. */ struct xfrmnl_ltime_cfg { uint32_t refcnt; uint64_t soft_byte_limit; uint64_t hard_byte_limit; uint64_t soft_packet_limit; uint64_t hard_packet_limit; uint64_t soft_add_expires_seconds; uint64_t hard_add_expires_seconds; uint64_t soft_use_expires_seconds; uint64_t hard_use_expires_seconds; }; /* Current lifetime, used for both policy rules (SPD) and SAs. */ struct xfrmnl_lifetime_cur { uint64_t bytes; uint64_t packets; uint64_t add_time; uint64_t use_time; }; struct xfrmnl_replay_state { uint32_t oseq; uint32_t seq; uint32_t bitmap; }; struct xfrmnl_replay_state_esn { uint32_t bmp_len; uint32_t oseq; uint32_t seq; uint32_t oseq_hi; uint32_t seq_hi; uint32_t replay_window; uint32_t bmp[0]; }; struct xfrmnl_mark { uint32_t v; /* value */ uint32_t m; /* mask */ }; /* XFRM AE related definitions */ struct xfrmnl_sa_id { struct nl_addr* daddr; uint32_t spi; uint16_t family; uint8_t proto; }; struct xfrmnl_ae { NLHDR_COMMON struct xfrmnl_sa_id sa_id; struct nl_addr* saddr; uint32_t flags; uint32_t reqid; struct xfrmnl_mark mark; struct xfrmnl_lifetime_cur lifetime_cur; uint32_t replay_maxage; uint32_t replay_maxdiff; struct xfrmnl_replay_state replay_state; struct xfrmnl_replay_state_esn* replay_state_esn; }; /* XFRM SA related definitions */ struct xfrmnl_id { struct nl_addr* daddr; uint32_t spi; uint8_t proto; }; struct xfrmnl_stats { uint32_t replay_window; uint32_t replay; uint32_t integrity_failed; }; struct xfrmnl_algo_aead { char alg_name[64]; uint32_t alg_key_len; /* in bits */ uint32_t alg_icv_len; /* in bits */ char alg_key[0]; }; struct xfrmnl_algo_auth { char alg_name[64]; uint32_t alg_key_len; /* in bits */ uint32_t alg_trunc_len; /* in bits */ char alg_key[0]; }; struct xfrmnl_algo { char alg_name[64]; uint32_t alg_key_len; /* in bits */ char alg_key[0]; }; struct xfrmnl_encap_tmpl { uint16_t encap_type; uint16_t encap_sport; uint16_t encap_dport; struct nl_addr* encap_oa; }; struct xfrmnl_sa { NLHDR_COMMON struct xfrmnl_sel* sel; struct xfrmnl_id id; struct nl_addr* saddr; struct xfrmnl_ltime_cfg* lft; struct xfrmnl_lifetime_cur curlft; struct xfrmnl_stats stats; uint32_t seq; uint32_t reqid; uint16_t family; uint8_t mode; /* XFRM_MODE_xxx */ uint8_t replay_window; uint8_t flags; struct xfrmnl_algo_aead* aead; struct xfrmnl_algo_auth* auth; struct xfrmnl_algo* crypt; struct xfrmnl_algo* comp; struct xfrmnl_encap_tmpl* encap; uint32_t tfcpad; struct nl_addr* coaddr; struct xfrmnl_mark mark; struct xfrmnl_user_sec_ctx* sec_ctx; uint32_t replay_maxage; uint32_t replay_maxdiff; struct xfrmnl_replay_state replay_state; struct xfrmnl_replay_state_esn* replay_state_esn; uint8_t hard; }; struct xfrmnl_usersa_flush { uint8_t proto; }; /* XFRM SP related definitions */ struct xfrmnl_userpolicy_id { struct xfrmnl_sel sel; uint32_t index; uint8_t dir; }; struct xfrmnl_user_sec_ctx { uint16_t len; uint16_t exttype; uint8_t ctx_alg; uint8_t ctx_doi; uint16_t ctx_len; char ctx[0]; }; struct xfrmnl_userpolicy_type { uint8_t type; uint16_t reserved1; uint16_t reserved2; }; struct xfrmnl_user_tmpl { struct xfrmnl_id id; uint16_t family; struct nl_addr* saddr; uint32_t reqid; uint8_t mode; uint8_t share; uint8_t optional; uint32_t aalgos; uint32_t ealgos; uint32_t calgos; struct nl_list_head utmpl_list; }; struct xfrmnl_sp { NLHDR_COMMON struct xfrmnl_sel* sel; struct xfrmnl_ltime_cfg* lft; struct xfrmnl_lifetime_cur curlft; uint32_t priority; uint32_t index; uint8_t dir; uint8_t action; uint8_t flags; uint8_t share; struct xfrmnl_user_sec_ctx* sec_ctx; struct xfrmnl_userpolicy_type uptype; uint32_t nr_user_tmpl; struct nl_list_head usertmpl_list; struct xfrmnl_mark mark; }; #endif libnl-3.2.29/include/netlink-private/genl.h0000644000175000017500000000110513023014600015447 00000000000000/* * netlink-private/genl.h Local Generic Netlink Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_GENL_PRIV_H_ #define NETLINK_GENL_PRIV_H_ #include #include #define GENL_HDRSIZE(hdrlen) (GENL_HDRLEN + (hdrlen)) extern int genl_resolve_id(struct genl_ops *ops); #endif libnl-3.2.29/include/netlink-private/tc.h0000644000175000017500000000247613023014600015144 00000000000000/* * netlink-private/tc.h Local Traffic Control Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_TC_PRIV_H_ #define NETLINK_TC_PRIV_H_ #include #ifdef __cplusplus extern "C" { #endif #define TCA_ATTR_HANDLE 0x0001 #define TCA_ATTR_PARENT 0x0002 #define TCA_ATTR_IFINDEX 0x0004 #define TCA_ATTR_KIND 0x0008 #define TCA_ATTR_FAMILY 0x0010 #define TCA_ATTR_INFO 0x0020 #define TCA_ATTR_OPTS 0x0040 #define TCA_ATTR_STATS 0x0080 #define TCA_ATTR_XSTATS 0x0100 #define TCA_ATTR_LINK 0x0200 #define TCA_ATTR_MTU 0x0400 #define TCA_ATTR_MPU 0x0800 #define TCA_ATTR_OVERHEAD 0x1000 #define TCA_ATTR_LINKTYPE 0x2000 #define TCA_ATTR_MAX TCA_ATTR_LINKTYPE extern int tca_parse(struct nlattr **, int, struct rtnl_tc *, struct nla_policy *); #define RTNL_TC_RTABLE_SIZE 256 extern int rtnl_tc_build_rate_table(struct rtnl_tc *tc, struct rtnl_ratespec *, uint32_t *); static inline void *tca_xstats(struct rtnl_tc *tca) { return tca->tc_xstats->d_data; } extern struct nl_af_group tc_groups[]; #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink-private/socket.h0000644000175000017500000000144513023014600016021 00000000000000/* * netlink-private/socket.h Private declarations for socket * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Thomas Graf */ #ifndef NETLINK_SOCKET_PRIV_H_ #define NETLINK_SOCKET_PRIV_H_ #include #ifdef __cplusplus extern "C" { #endif int _nl_socket_is_local_port_unspecified (struct nl_sock *sk); uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other); void _nl_socket_used_ports_release_all(const uint32_t *used_ports); void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink-private/object-api.h0000644000175000017500000002507013023014600016546 00000000000000/* * netlink-private/object-api.c Object API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_OBJECT_API_H_ #define NETLINK_OBJECT_API_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @ingroup object * @defgroup object_api Object API * @brief * * @par 1) Object Definition * @code * // Define your object starting with the common object header * struct my_obj { * NLHDR_COMMON * int my_data; * }; * * // Fill out the object operations structure * struct nl_object_ops my_ops = { * .oo_name = "my_obj", * .oo_size = sizeof(struct my_obj), * }; * * // At this point the object can be allocated, you may want to provide a * // separate _alloc() function to ease allocting objects of this kind. * struct nl_object *obj = nl_object_alloc(&my_ops); * * // And release it again... * nl_object_put(obj); * @endcode * * @par 2) Allocating additional data * @code * // You may require to allocate additional data and store it inside * // object, f.e. assuming there is a field `ptr'. * struct my_obj { * NLHDR_COMMON * void * ptr; * }; * * // And at some point you may assign allocated data to this field: * my_obj->ptr = calloc(1, ...); * * // In order to not introduce any memory leaks you have to release * // this data again when the last reference is given back. * static void my_obj_free_data(struct nl_object *obj) * { * struct my_obj *my_obj = nl_object_priv(obj); * * free(my_obj->ptr); * } * * // Also when the object is cloned, you must ensure for your pointer * // stay valid even if one of the clones is freed by either making * // a clone as well or increase the reference count. * static int my_obj_clone(struct nl_object *src, struct nl_object *dst) * { * struct my_obj *my_src = nl_object_priv(src); * struct my_obj *my_dst = nl_object_priv(dst); * * if (src->ptr) { * dst->ptr = calloc(1, ...); * memcpy(dst->ptr, src->ptr, ...); * } * } * * struct nl_object_ops my_ops = { * ... * .oo_free_data = my_obj_free_data, * .oo_clone = my_obj_clone, * }; * @endcode * * @par 3) Object Dumping * @code * static int my_obj_dump_detailed(struct nl_object *obj, * struct nl_dump_params *params) * { * struct my_obj *my_obj = nl_object_priv(obj); * * // It is absolutely essential to use nl_dump() when printing * // any text to make sure the dumping parameters are respected. * nl_dump(params, "Obj Integer: %d\n", my_obj->my_int); * * // Before we can dump the next line, make sure to prefix * // this line correctly. * nl_new_line(params); * * // You may also split a line into multiple nl_dump() calls. * nl_dump(params, "String: %s ", my_obj->my_string); * nl_dump(params, "String-2: %s\n", my_obj->another_string); * } * * struct nl_object_ops my_ops = { * ... * .oo_dump[NL_DUMP_FULL] = my_obj_dump_detailed, * }; * @endcode * * @par 4) Object Attributes * @code * // The concept of object attributes is optional but can ease the typical * // case of objects that have optional attributes, e.g. a route may have a * // nexthop assigned but it is not required to. * * // The first step to define your object specific bitmask listing all * // attributes * #define MY_ATTR_FOO (1<<0) * #define MY_ATTR_BAR (1<<1) * * // Bit 31 for attributes is reserved for 32-bit API. * * // When assigning an optional attribute to the object, make sure * // to mark its availability. * my_obj->foo = 123123; * my_obj->ce_mask |= MY_ATTR_FOO; * * // At any time you may use this mask to check for the availability * // of the attribute, e.g. while dumping * if (my_obj->ce_mask & MY_ATTR_FOO) * nl_dump(params, "foo %d ", my_obj->foo); * * // One of the big advantages of this concept is that it allows for * // standardized comparisons which make it trivial for caches to * // identify unique objects by use of unified comparison functions. * // In order for it to work, your object implementation must provide * // a comparison function and define a list of attributes which * // combined together make an object unique. * * static int my_obj_compare(struct nl_object *_a, struct nl_object *_b, * uint32_t attrs, int flags) * { * struct my_obj *a = nl_object_priv(_a): * struct my_obj *b = nl_object_priv(_b): * int diff = 0; * * // We help ourselves in defining our own DIFF macro which will * // call ATTR_DIFF() on both objects which will make sure to only * // compare the attributes if required. * #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR) * * // Call our own diff macro for each attribute to build a bitmask * // representing the attributes which mismatch. * diff |= MY_DIFF(FOO, a->foo != b->foo) * diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar)) * * return diff; * } * * // In order to identify identical objects with differing attributes * // you must specify the attributes required to uniquely identify * // your object. Make sure to not include too many attributes, this * // list is used when caches look for an old version of an object. * struct nl_object_ops my_ops = { * ... * .oo_id_attrs = MY_ATTR_FOO, * .oo_compare = my_obj_compare, * }; * @endcode * @{ */ /** * Common Object Header * * This macro must be included as first member in every object * definition to allow objects to be cached. */ #define NLHDR_COMMON \ int ce_refcnt; \ struct nl_object_ops * ce_ops; \ struct nl_cache * ce_cache; \ struct nl_list_head ce_list; \ int ce_msgtype; \ int ce_flags; \ uint64_t ce_mask; struct nl_object { NLHDR_COMMON }; /** * Return true if attribute is available in both objects * @arg A an object * @arg B another object * @arg ATTR attribute bit * * @return True if the attribute is available, otherwise false is returned. */ #define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR)) /** * Return true if attribute is available in only one of both objects * @arg A an object * @arg B another object * @arg ATTR attribute bit * * @return True if the attribute is available in only one of both objects, * otherwise false is returned. */ #define AVAILABLE_MISMATCH(A, B, ATTR) (((A)->ce_mask ^ (B)->ce_mask) & (ATTR)) /** * Return true if attributes mismatch * @arg A an object * @arg B another object * @arg ATTR attribute bit * @arg EXPR Comparison expression * * This function will check if the attribute in question is available * in both objects, if not this will count as a mismatch. * * If available the function will execute the expression which must * return true if the attributes mismatch. * * @return True if the attribute mismatch, or false if they match. */ #define ATTR_MISMATCH(A, B, ATTR, EXPR) (AVAILABLE_MISMATCH(A, B, ATTR) || \ (AVAILABLE(A, B, ATTR) && (EXPR))) /** * Return attribute bit if attribute does not match * @arg LIST list of attributes to be compared * @arg ATTR attribute bit * @arg A an object * @arg B another object * @arg EXPR Comparison expression * * This function will check if the attribute in question is available * in both objects, if not this will count as a mismatch. * * If available the function will execute the expression which must * return true if the attributes mismatch. * * In case the attributes mismatch, the attribute is returned, otherwise * 0 is returned. * * @code * diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo); * @endcode */ #define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \ ({ uint64_t diff = 0; \ if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \ diff = ATTR; \ diff; }) /** * Object Operations */ struct nl_object_ops { /** * Unique name of object type * * Must be in the form family/name, e.g. "route/addr" */ char * oo_name; /** Size of object including its header */ size_t oo_size; /* List of attributes needed to uniquely identify the object */ uint32_t oo_id_attrs; /** * Constructor function * * Will be called when a new object of this type is allocated. * Can be used to initialize members such as lists etc. */ void (*oo_constructor)(struct nl_object *); /** * Destructor function * * Will be called when an object is freed. Must free all * resources which may have been allocated as part of this * object. */ void (*oo_free_data)(struct nl_object *); /** * Cloning function * * Will be called when an object needs to be cloned. Please * note that the generic object code will make an exact * copy of the object first, therefore you only need to take * care of members which require reference counting etc. * * May return a negative error code to abort cloning. */ int (*oo_clone)(struct nl_object *, struct nl_object *); /** * Dumping functions * * Will be called when an object is dumped. The implementations * have to use nl_dump(), nl_dump_line(), and nl_new_line() to * dump objects. * * The functions must return the number of lines printed. */ void (*oo_dump[NL_DUMP_MAX+1])(struct nl_object *, struct nl_dump_params *); /** * Comparison function * * Will be called when two objects of the same type are * compared. It takes the two objects in question, an object * specific bitmask defining which attributes should be * compared and flags to control the behaviour. * * The function must return a bitmask with the relevant bit * set for each attribute that mismatches. */ uint64_t (*oo_compare)(struct nl_object *, struct nl_object *, uint64_t, int); /** * update function * * Will be called when the object given by first argument * needs to be updated with the contents of the second object * * The function must return 0 for success and error for failure * to update. In case of failure its assumed that the original * object is not touched */ int (*oo_update)(struct nl_object *, struct nl_object *); /** * Hash Key generator function * * When called returns a hash key for the object being * referenced. This key will be used by higher level hash functions * to build association lists. Each object type gets to specify * it's own key formulation */ void (*oo_keygen)(struct nl_object *, uint32_t *, uint32_t); char *(*oo_attrs2str)(int, char *, size_t); /** * Get key attributes by family function */ uint32_t (*oo_id_attrs_get)(struct nl_object *); }; /** @} */ #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink-private/netlink.h0000644000175000017500000001524713023014600016202 00000000000000/* * netlink-private/netlink.h Local Netlink Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_LOCAL_H_ #define NETLINK_LOCAL_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef SOL_NETLINK #define SOL_NETLINK 270 #endif #include /* local header copies */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef DISABLE_PTHREADS #include #endif #include #include #include #include #include #include #include #define NSEC_PER_SEC 1000000000L struct trans_tbl { uint64_t i; const char *a; }; #define __ADD(id, name) { .i = id, .a = #name } struct trans_list { int i; char *a; struct nl_list_head list; }; #ifdef NL_DEBUG #define NL_DBG(LVL,FMT,ARG...) \ do { \ if (LVL <= nl_debug) { \ int _errsv = errno; \ fprintf(stderr, \ "DBG<" #LVL ">%20s:%-4u %s: " FMT, \ __FILE__, __LINE__, \ __PRETTY_FUNCTION__, ##ARG); \ errno = _errsv; \ } \ } while (0) #else /* NL_DEBUG */ #define NL_DBG(LVL,FMT,ARG...) do { } while(0) #endif /* NL_DEBUG */ #define BUG() \ do { \ fprintf(stderr, "BUG at file position %s:%d:%s\n", \ __FILE__, __LINE__, __PRETTY_FUNCTION__); \ assert(0); \ } while (0) #define BUG_ON(condition) \ do { \ if (condition) \ BUG(); \ } while (0) #define APPBUG(msg) \ do { \ fprintf(stderr, "APPLICATION BUG: %s:%d:%s: %s\n", \ __FILE__, __LINE__, __PRETTY_FUNCTION__, msg); \ assert(0); \ } while(0) extern int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)); extern int __trans_list_add(int, const char *, struct nl_list_head *); extern void __trans_list_clear(struct nl_list_head *); extern char *__type2str(int, char *, size_t, const struct trans_tbl *, size_t); extern int __str2type(const char *, const struct trans_tbl *, size_t); extern char *__list_type2str(int, char *, size_t, struct nl_list_head *); extern int __list_str2type(const char *, struct nl_list_head *); extern char *__flags2str(int, char *, size_t, const struct trans_tbl *, size_t); extern int __str2flags(const char *, const struct trans_tbl *, size_t); extern void dump_from_ops(struct nl_object *, struct nl_dump_params *); extern struct rtnl_link *link_lookup(struct nl_cache *cache, int ifindex); static inline int nl_cb_call(struct nl_cb *cb, enum nl_cb_type type, struct nl_msg *msg) { int ret; cb->cb_active = type; ret = cb->cb_set[type](msg, cb->cb_args[type]); cb->cb_active = __NL_CB_TYPE_MAX; return ret; } #define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) /* This is also defined in stddef.h */ #ifndef offsetof #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif #define __init __attribute__ ((constructor)) #define __exit __attribute__ ((destructor)) #undef __deprecated #define __deprecated __attribute__ ((deprecated)) #define min(x,y) ({ \ typeof(x) _x = (x); \ typeof(y) _y = (y); \ (void) (&_x == &_y); \ _x < _y ? _x : _y; }) #define max(x,y) ({ \ typeof(x) _x = (x); \ typeof(y) _y = (y); \ (void) (&_x == &_y); \ _x > _y ? _x : _y; }) #define min_t(type,x,y) \ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) #define max_t(type,x,y) \ ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) extern int nl_cache_parse(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *); static inline void rtnl_copy_ratespec(struct rtnl_ratespec *dst, struct tc_ratespec *src) { dst->rs_cell_log = src->cell_log; dst->rs_overhead = src->overhead; dst->rs_cell_align = src->cell_align; dst->rs_mpu = src->mpu; dst->rs_rate = src->rate; } static inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst, struct rtnl_ratespec *src) { dst->cell_log = src->rs_cell_log; dst->overhead = src->rs_overhead; dst->cell_align = src->rs_cell_align; dst->mpu = src->rs_mpu; dst->rate = src->rs_rate; } static inline const char *nl_cache_name(struct nl_cache *cache) { return cache->c_ops ? cache->c_ops->co_name : "unknown"; } #define GENL_FAMILY(id, name) \ { \ { id, NL_ACT_UNSPEC, name }, \ END_OF_MSGTYPES_LIST, \ } static inline int wait_for_ack(struct nl_sock *sk) { if (sk->s_flags & NL_NO_AUTO_ACK) return 0; else return nl_wait_for_ack(sk); } static inline int build_sysconf_path(char **strp, const char *filename) { char *sysconfdir; sysconfdir = getenv("NLSYSCONFDIR"); if (!sysconfdir) sysconfdir = SYSCONFDIR; return asprintf(strp, "%s/%s", sysconfdir, filename); } #ifndef DISABLE_PTHREADS #define NL_LOCK(NAME) pthread_mutex_t (NAME) = PTHREAD_MUTEX_INITIALIZER #define NL_RW_LOCK(NAME) pthread_rwlock_t (NAME) = PTHREAD_RWLOCK_INITIALIZER static inline void nl_lock(pthread_mutex_t *lock) { pthread_mutex_lock(lock); } static inline void nl_unlock(pthread_mutex_t *lock) { pthread_mutex_unlock(lock); } static inline void nl_read_lock(pthread_rwlock_t *lock) { pthread_rwlock_rdlock(lock); } static inline void nl_read_unlock(pthread_rwlock_t *lock) { pthread_rwlock_unlock(lock); } static inline void nl_write_lock(pthread_rwlock_t *lock) { pthread_rwlock_wrlock(lock); } static inline void nl_write_unlock(pthread_rwlock_t *lock) { pthread_rwlock_unlock(lock); } #else #define NL_LOCK(NAME) int __unused_lock_ ##NAME __attribute__((unused)) #define NL_RW_LOCK(NAME) int __unused_lock_ ##NAME __attribute__((unused)) #define nl_lock(LOCK) do { } while(0) #define nl_unlock(LOCK) do { } while(0) #define nl_read_lock(LOCK) do { } while(0) #define nl_read_unlock(LOCK) do { } while(0) #define nl_write_lock(LOCK) do { } while(0) #define nl_write_unlock(LOCK) do { } while(0) #endif #endif libnl-3.2.29/include/netlink-private/cache-api.h0000644000175000017500000001633313023014600016345 00000000000000/* * netlink-private/cache-api.h Caching API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_CACHE_API_H_ #define NETLINK_CACHE_API_H_ #include #include #ifdef __cplusplus extern "C" { #endif /** * @ingroup cache * @defgroup cache_api Cache Implementation * @brief * * @par 1) Cache Definition * @code * struct nl_cache_ops my_cache_ops = { * .co_name = "route/link", * .co_protocol = NETLINK_ROUTE, * .co_hdrsize = sizeof(struct ifinfomsg), * .co_obj_ops = &my_obj_ops, * }; * @endcode * * @par 2) * @code * // The simplest way to fill a cache is by providing a request-update * // function which must trigger a complete dump on the kernel-side of * // whatever the cache covers. * static int my_request_update(struct nl_cache *cache, * struct nl_sock *socket) * { * // In this example, we request a full dump of the interface table * return nl_rtgen_request(socket, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP); * } * * // The resulting netlink messages sent back will be fed into a message * // parser one at a time. The message parser has to extract all relevant * // information from the message and create an object reflecting the * // contents of the message and pass it on to the parser callback function * // provide which will add the object to the cache. * static int my_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, * struct nlmsghdr *nlh, struct nl_parser_param *pp) * { * struct my_obj *obj; * * obj = my_obj_alloc(); * obj->ce_msgtype = nlh->nlmsg_type; * * // Parse the netlink message and continue creating the object. * * err = pp->pp_cb((struct nl_object *) obj, pp); * if (err < 0) * goto errout; * } * * struct nl_cache_ops my_cache_ops = { * ... * .co_request_update = my_request_update, * .co_msg_parser = my_msg_parser, * }; * @endcode * * @par 3) Notification based Updates * @code * // Caches can be kept up-to-date based on notifications if the kernel * // sends out notifications whenever an object is added/removed/changed. * // * // It is trivial to support this, first a list of groups needs to be * // defined which are required to join in order to receive all necessary * // notifications. The groups are separated by address family to support * // the common situation where a separate group is used for each address * // family. If there is only one group, simply specify AF_UNSPEC. * static struct nl_af_group addr_groups[] = { * { AF_INET, RTNLGRP_IPV4_IFADDR }, * { AF_INET6, RTNLGRP_IPV6_IFADDR }, * { END_OF_GROUP_LIST }, * }; * * // In order for the caching system to know the meaning of each message * // type it requires a table which maps each supported message type to * // a cache action, e.g. RTM_NEWADDR means address has been added or * // updated, RTM_DELADDR means address has been removed. * static struct nl_cache_ops rtnl_addr_ops = { * ... * .co_msgtypes = { * { RTM_NEWADDR, NL_ACT_NEW, "new" }, * { RTM_DELADDR, NL_ACT_DEL, "del" }, * { RTM_GETADDR, NL_ACT_GET, "get" }, * END_OF_MSGTYPES_LIST, * }, * .co_groups = addr_groups, * }; * * // It is now possible to keep the cache up-to-date using the cache manager. * @endcode * @{ */ #define END_OF_MSGTYPES_LIST { -1, -1, NULL } /** * Message type to cache action association */ struct nl_msgtype { /** Netlink message type */ int mt_id; /** Cache action to take */ int mt_act; /** Name of operation for human-readable printing */ char * mt_name; }; /** * Address family to netlink group association */ struct nl_af_group { /** Address family */ int ag_family; /** Netlink group identifier */ int ag_group; }; #define END_OF_GROUP_LIST AF_UNSPEC, 0 /** * Parser parameters * * This structure is used to configure what kind of parser to use * when parsing netlink messages to create objects. */ struct nl_parser_param { /** Function to parse netlink messages into objects */ int (*pp_cb)(struct nl_object *, struct nl_parser_param *); /** Arbitary argument to be passed to the parser */ void * pp_arg; }; /** * Cache Operations * * This structure defines the characterstics of a cache type. It contains * pointers to functions which implement the specifics of the object type * the cache can hold. */ struct nl_cache_ops { /** Name of cache type (must be unique) */ char * co_name; /** Size of family specific netlink header */ int co_hdrsize; /** Netlink protocol */ int co_protocol; /** cache object hash size **/ int co_hash_size; /** cache flags */ unsigned int co_flags; /** Reference counter */ unsigned int co_refcnt; /** Group definition */ struct nl_af_group * co_groups; /** * Called whenever an update of the cache is required. Must send * a request message to the kernel requesting a complete dump. */ int (*co_request_update)(struct nl_cache *, struct nl_sock *); /** * Called whenever a message was received that needs to be parsed. * Must parse the message and call the paser callback function * (nl_parser_param) provided via the argument. */ int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *); /** * The function registered under this callback is called after a * netlink notification associated with this cache type has been * parsed into an object and is being considered for inclusio into * the specified cache. * * The purpose of this function is to filter out notifications * which should be ignored when updating caches. * * The function must return NL_SKIP to prevent the object from * being included, or NL_OK to include it. * * @code * int my_filter(struct nl_cache *cache, struct nl_object *obj) * { * if (reason_to_not_include_obj(obj)) * return NL_SKIP; * * return NL_OK; * } * @endcode */ int (*co_event_filter)(struct nl_cache *, struct nl_object *obj); /** * The function registered under this callback is called when an * object formed from a notification event needs to be included in * a cache. * * For each modified object, the change callback \c change_cb must * be called with the \c data argument provided. * * If no function is registered, the function nl_cache_include() * will be used for this purpose. * * @see nl_cache_include() */ int (*co_include_event)(struct nl_cache *cache, struct nl_object *obj, change_func_t change_cb, change_func_v2_t change_cb_v2, void *data); void (*reserved_1)(void); void (*reserved_2)(void); void (*reserved_3)(void); void (*reserved_4)(void); void (*reserved_5)(void); void (*reserved_6)(void); void (*reserved_7)(void); void (*reserved_8)(void); /** Object operations */ struct nl_object_ops * co_obj_ops; /** Internal, do not touch! */ struct nl_cache_ops *co_next; struct nl_cache *co_major_cache; struct genl_ops * co_genl; /* Message type definition */ struct nl_msgtype co_msgtypes[]; }; /** @} */ #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink-private/route/0000755000175000017500000000000013031473756015616 500000000000000libnl-3.2.29/include/netlink-private/route/link/0000755000175000017500000000000013031473756016553 500000000000000libnl-3.2.29/include/netlink-private/route/link/api.h0000644000175000017500000001534413023014600017400 00000000000000/* * netlink-private/route/link/api.h Link Modules API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_LINK_API_H_ #define NETLINK_LINK_API_H_ #include #ifdef __cplusplus extern "C" { #endif /** * @ingroup link_api * * Available operations to modules implementing a link info type. */ struct rtnl_link_info_ops { /** Name of link info type, must match name on kernel side */ char * io_name; /** Reference count, DO NOT MODIFY */ int io_refcnt; /** Called to assign an info type to a link. * Has to allocate enough resources to hold attributes. Can * use link->l_info to store a pointer. */ int (*io_alloc)(struct rtnl_link *); /** Called to parse the link info attribute. * Must parse the attribute and assign all values to the link. */ int (*io_parse)(struct rtnl_link *, struct nlattr *, struct nlattr *); /** Called when the link object is dumped. * Must dump the info type specific attributes. */ void (*io_dump[NL_DUMP_MAX+1])(struct rtnl_link *, struct nl_dump_params *); /** Called when a link object is cloned. * Must clone all info type specific attributes. */ int (*io_clone)(struct rtnl_link *, struct rtnl_link *); /** Called when construction a link netlink message. * Must append all info type specific attributes to the message. */ int (*io_put_attrs)(struct nl_msg *, struct rtnl_link *); /** Called to release all resources previously allocated * in either io_alloc() or io_parse(). */ void (*io_free)(struct rtnl_link *); /** Called to compare link info parameters between two links. */ int (*io_compare)(struct rtnl_link *, struct rtnl_link *, int flags); struct nl_list_head io_list; }; extern struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *); extern void rtnl_link_info_ops_put(struct rtnl_link_info_ops *); extern int rtnl_link_register_info(struct rtnl_link_info_ops *); extern int rtnl_link_unregister_info(struct rtnl_link_info_ops *); /** * @ingroup link_api * * Available operations to modules implementing a link address family. */ struct rtnl_link_af_ops { /** The address family this operations set implements */ const unsigned int ao_family; /** Number of users of this operations, DO NOT MODIFY. */ int ao_refcnt; /** Validation policy for IFLA_PROTINFO attribute. This pointer * can be set to a nla_policy structure describing the minimal * requirements the attribute must meet. Failure of meeting these * requirements will result in a parsing error. */ const struct nla_policy *ao_protinfo_policy; /** Called after address family has been assigned to link. Must * allocate data buffer to hold address family specific data and * store it in link->l_af_data. */ void * (*ao_alloc)(struct rtnl_link *); /** Called when the link is cloned, must allocate a clone of the * address family specific buffer and return it. */ void * (*ao_clone)(struct rtnl_link *, void *); /** Called when the link gets freed. Must free all allocated data */ void (*ao_free)(struct rtnl_link *, void *); /** Called if a IFLA_PROTINFO attribute needs to be parsed. Typically * stores the parsed data in the address family specific buffer. */ int (*ao_parse_protinfo)(struct rtnl_link *, struct nlattr *, void *); /** Called if a IFLA_AF_SPEC attribute needs to be parsed. Typically * stores the parsed data in the address family specific buffer. */ int (*ao_parse_af)(struct rtnl_link *, struct nlattr *, void *); /** Called if a link message is sent to the kernel. Must append the * link address family specific attributes to the message. */ int (*ao_fill_af)(struct rtnl_link *, struct nl_msg *msg, void *); /** Called if the full IFLA_AF_SPEC data needs to be parsed. Typically * stores the parsed data in the address family specific buffer. */ int (*ao_parse_af_full)(struct rtnl_link *, struct nlattr *, void *); /** Called for GETLINK message to the kernel. Used to append * link address family specific attributes to the request message. */ int (*ao_get_af)(struct nl_msg *msg, uint32_t *ext_filter_mask); /** Dump address family specific link attributes */ void (*ao_dump[NL_DUMP_MAX+1])(struct rtnl_link *, struct nl_dump_params *, void *); /** Comparison function * * Will be called when two links are compared for their af data. It * takes two link objects in question, an object specific bitmask * defining which attributes should be compared and flags to control * the behaviour * * The function must return a bitmask with the relevant bit set for * each attribute that mismatches */ int (*ao_compare)(struct rtnl_link *, struct rtnl_link *, int, uint32_t, int); /* RTM_NEWLINK override * * Called if a change link request is set to the kernel. If this is set * to anything other than zero, RTM_NEWLINK will be overriden with * RTM_SETLINK when rtnl_link_build_change_request() is called. */ const int ao_override_rtm; /** Called if a link message is sent to the kernel. Must append the * link protocol specific attributes to the message. (IFLA_PROTINFO) */ int (*ao_fill_pi)(struct rtnl_link *, struct nl_msg *msg, void *); /** PROTINFO type * * Called if a link message is sent to the kernel. If this is set, * the default IFLA_PROTINFO is bitmasked with what is specified * here. (eg. NLA_F_NESTED) */ const int ao_fill_pi_flags; /** IFLA_AF_SPEC nesting override * * Called if a link message is sent to the kernel. If this is set, * the AF specific nest is not created. Instead, AF specific attributes * are nested directly in the IFLA_AF_SPEC attribute. */ const int ao_fill_af_no_nest; }; extern struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(unsigned int); extern void rtnl_link_af_ops_put(struct rtnl_link_af_ops *); extern void * rtnl_link_af_alloc(struct rtnl_link *, const struct rtnl_link_af_ops *); extern void * rtnl_link_af_data(const struct rtnl_link *, const struct rtnl_link_af_ops *); extern int rtnl_link_af_register(struct rtnl_link_af_ops *); extern int rtnl_link_af_unregister(struct rtnl_link_af_ops *); extern int rtnl_link_af_data_compare(struct rtnl_link *a, struct rtnl_link *b, int family); extern int rtnl_link_info_data_compare(struct rtnl_link *a, struct rtnl_link *b, int flags); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink-private/route/link/sriov.h0000644000175000017500000000211113023014600017755 00000000000000/* * include/netlink-private/route/link/sriov.h SRIOV VF Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Intel Corp. All rights reserved. * Copyright (c) 2016 Jef Oliver */ #ifndef NETLINK_PRIV_LINK_SRIOV_H_ #define NETLINK_PRIV_LINK_SRIOV_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_link_sriov_clone(struct rtnl_link *, struct rtnl_link *); extern void rtnl_link_sriov_dump_details(struct rtnl_link *, struct nl_dump_params *); extern void rtnl_link_sriov_dump_stats(struct rtnl_link *, struct nl_dump_params *); extern int rtnl_link_sriov_fill_vflist(struct nl_msg *, struct rtnl_link *); extern void rtnl_link_sriov_free_data(struct rtnl_link *); extern int rtnl_link_sriov_parse_vflist(struct rtnl_link *, struct nlattr **); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink-private/route/tc-api.h0000644000175000017500000000630013023014600017037 00000000000000/* * netlink-private/route/tc-api.h Traffic Control API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2011-2013 Thomas Graf */ #ifndef NETLINK_TC_API_H_ #define NETLINK_TC_API_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * Traffic control object operations * @ingroup tc * * This structure holds function pointers and settings implementing * the features of each traffic control object implementation. */ struct rtnl_tc_ops { /** * Name of traffic control module */ char *to_kind; /** * Type of traffic control object */ enum rtnl_tc_type to_type; /** * Size of private data */ size_t to_size; /** * Dump callbacks */ void (*to_dump[NL_DUMP_MAX+1])(struct rtnl_tc *, void *, struct nl_dump_params *); /** * Used to fill the contents of TCA_OPTIONS */ int (*to_msg_fill)(struct rtnl_tc *, void *, struct nl_msg *); /** * Uesd to to fill tc related messages, unlike with to_msg_fill, * the contents is not encapsulated with a TCA_OPTIONS nested * attribute. */ int (*to_msg_fill_raw)(struct rtnl_tc *, void *, struct nl_msg *); /** * TCA_OPTIONS message parser */ int (*to_msg_parser)(struct rtnl_tc *, void *); /** * Called before a tc object is destroyed */ void (*to_free_data)(struct rtnl_tc *, void *); /** * Called whenever a classifier object needs to be cloned */ int (*to_clone)(void *, void *); /** * Internal, don't touch */ struct nl_list_head to_list; }; struct rtnl_tc_type_ops { enum rtnl_tc_type tt_type; char *tt_dump_prefix; /** * Dump callbacks */ void (*tt_dump[NL_DUMP_MAX+1])(struct rtnl_tc *, struct nl_dump_params *); }; extern int rtnl_tc_msg_parse(struct nlmsghdr *, struct rtnl_tc *); extern int rtnl_tc_msg_build(struct rtnl_tc *, int, int, struct nl_msg **); extern void rtnl_tc_free_data(struct nl_object *); extern int rtnl_tc_clone(struct nl_object *, struct nl_object *); extern void rtnl_tc_dump_line(struct nl_object *, struct nl_dump_params *); extern void rtnl_tc_dump_details(struct nl_object *, struct nl_dump_params *); extern void rtnl_tc_dump_stats(struct nl_object *, struct nl_dump_params *); extern uint64_t rtnl_tc_compare(struct nl_object *, struct nl_object *, uint64_t, int); void * rtnl_tc_data_peek(struct rtnl_tc *tc); extern void * rtnl_tc_data(struct rtnl_tc *); extern void * rtnl_tc_data_check(struct rtnl_tc *, struct rtnl_tc_ops *, int *); extern struct rtnl_tc_ops * rtnl_tc_lookup_ops(enum rtnl_tc_type, const char *); extern struct rtnl_tc_ops * rtnl_tc_get_ops(struct rtnl_tc *); extern int rtnl_tc_register(struct rtnl_tc_ops *); extern void rtnl_tc_unregister(struct rtnl_tc_ops *); extern void rtnl_tc_type_register(struct rtnl_tc_type_ops *); extern void rtnl_tc_type_unregister(struct rtnl_tc_type_ops *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/0000755000175000017500000000000013031473756013010 500000000000000libnl-3.2.29/include/netlink/data.h0000644000175000017500000000201013023014600013757 00000000000000/* * netlink/data.h Abstract Data * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_DATA_H_ #define NETLINK_DATA_H_ #include #ifdef __cplusplus extern "C" { #endif struct nl_data; /* General */ extern struct nl_data * nl_data_alloc(const void *, size_t); extern struct nl_data * nl_data_alloc_attr(const struct nlattr *); extern struct nl_data * nl_data_clone(const struct nl_data *); extern int nl_data_append(struct nl_data *, const void *, size_t); extern void nl_data_free(struct nl_data *); /* Access Functions */ extern void * nl_data_get(const struct nl_data *); extern size_t nl_data_get_size(const struct nl_data *); /* Misc */ extern int nl_data_cmp(const struct nl_data *, const struct nl_data *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/msg.h0000644000175000017500000001053713023014600013651 00000000000000/* * netlink/msg.c Netlink Messages Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_MSG_H_ #define NETLINK_MSG_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif #define NL_DONTPAD 0 /** * @ingroup msg * @brief * Will cause the netlink port to be set to the port assigned to * the netlink icoket ust before sending the message off. * * @note Requires the use of nl_send_auto()! */ #define NL_AUTO_PORT 0 #define NL_AUTO_PID NL_AUTO_PORT /** * @ingroup msg * @brief * May be used to refer to a sequence number which should be * automatically set just before sending the message off. * * @note Requires the use of nl_send_auto()! */ #define NL_AUTO_SEQ 0 struct nl_msg; struct nl_tree; struct ucred; extern int nlmsg_size(int); extern int nlmsg_total_size(int); extern int nlmsg_padlen(int); extern void * nlmsg_data(const struct nlmsghdr *); extern int nlmsg_datalen(const struct nlmsghdr *); extern void * nlmsg_tail(const struct nlmsghdr *); /* attribute access */ extern struct nlattr * nlmsg_attrdata(const struct nlmsghdr *, int); extern int nlmsg_attrlen(const struct nlmsghdr *, int); /* message parsing */ extern int nlmsg_valid_hdr(const struct nlmsghdr *, int); extern int nlmsg_ok(const struct nlmsghdr *, int); extern struct nlmsghdr * nlmsg_next(struct nlmsghdr *, int *); extern int nlmsg_parse(struct nlmsghdr *, int, struct nlattr **, int, struct nla_policy *); extern struct nlattr * nlmsg_find_attr(struct nlmsghdr *, int, int); extern int nlmsg_validate(struct nlmsghdr *, int, int, struct nla_policy *); extern struct nl_msg * nlmsg_alloc(void); extern struct nl_msg * nlmsg_alloc_size(size_t); extern struct nl_msg * nlmsg_alloc_simple(int, int); extern void nlmsg_set_default_size(size_t); extern struct nl_msg * nlmsg_inherit(struct nlmsghdr *); extern struct nl_msg * nlmsg_convert(struct nlmsghdr *); extern void * nlmsg_reserve(struct nl_msg *, size_t, int); extern int nlmsg_append(struct nl_msg *, void *, size_t, int); extern int nlmsg_expand(struct nl_msg *, size_t); extern struct nlmsghdr * nlmsg_put(struct nl_msg *, uint32_t, uint32_t, int, int, int); extern struct nlmsghdr * nlmsg_hdr(struct nl_msg *); extern void nlmsg_get(struct nl_msg *); extern void nlmsg_free(struct nl_msg *); /* attribute modification */ extern void nlmsg_set_proto(struct nl_msg *, int); extern int nlmsg_get_proto(struct nl_msg *); extern size_t nlmsg_get_max_size(struct nl_msg *); extern void nlmsg_set_src(struct nl_msg *, struct sockaddr_nl *); extern struct sockaddr_nl *nlmsg_get_src(struct nl_msg *); extern void nlmsg_set_dst(struct nl_msg *, struct sockaddr_nl *); extern struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *); extern void nlmsg_set_creds(struct nl_msg *, struct ucred *); extern struct ucred * nlmsg_get_creds(struct nl_msg *); extern char * nl_nlmsgtype2str(int, char *, size_t); extern int nl_str2nlmsgtype(const char *); extern char * nl_nlmsg_flags2str(int, char *, size_t); extern int nl_msg_parse(struct nl_msg *, void (*cb)(struct nl_object *, void *), void *); extern void nl_msg_dump(struct nl_msg *, FILE *); /** * @name Iterators * @{ */ /** * @ingroup msg * Iterate over a stream of attributes in a message * @arg pos loop counter, set to current attribute * @arg nlh netlink message header * @arg hdrlen length of family header * @arg rem initialized to len, holds bytes currently remaining in stream */ #define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \ nlmsg_attrlen(nlh, hdrlen), rem) /** * Iterate over a stream of messages * @arg pos loop counter, set to current message * @arg head head of message stream * @arg len length of message stream */ #define nlmsg_for_each(pos, head, len) \ for (int rem = len, pos = head; \ nlmsg_ok(pos, rem); \ pos = nlmsg_next(pos, &rem)) #define nlmsg_for_each_msg(pos, head, len, rem) \ nlmsg_for_each(pos, head, len) /** @} */ #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/cli/0000755000175000017500000000000013031473756013557 500000000000000libnl-3.2.29/include/netlink/cli/qdisc.h0000644000175000017500000000114113023014600014724 00000000000000/* * netlink/cli/qdisc.h CLI QDisc Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2011 Thomas Graf */ #ifndef __NETLINK_CLI_QDISC_H_ #define __NETLINK_CLI_QDISC_H_ #include #define nl_cli_qdisc_alloc_cache(sk) \ nl_cli_alloc_cache((sk), "queueing disciplines", \ rtnl_qdisc_alloc_cache) extern struct rtnl_qdisc *nl_cli_qdisc_alloc(void); #endif libnl-3.2.29/include/netlink/cli/class.h0000644000175000017500000000110513023014600014726 00000000000000/* * netlink/cli/class.h CLI Class Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #ifndef __NETLINK_CLI_CLASS_H_ #define __NETLINK_CLI_CLASS_H_ #include #include extern struct rtnl_class *nl_cli_class_alloc(void); extern struct nl_cache *nl_cli_class_alloc_cache(struct nl_sock *, int); #endif libnl-3.2.29/include/netlink/cli/cls.h0000644000175000017500000000135613023014600014412 00000000000000/* * netlink/cli/cls.h CLI Classifier Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #ifndef __NETLINK_CLI_CLS_H_ #define __NETLINK_CLI_CLS_H_ #include #include extern struct rtnl_cls * nl_cli_cls_alloc(void); extern struct nl_cache * nl_cli_cls_alloc_cache(struct nl_sock *, int, uint32_t); extern void nl_cli_cls_parse_proto(struct rtnl_cls *, char *); extern struct rtnl_ematch_tree *nl_cli_cls_parse_ematch(struct rtnl_cls *, char *); #endif libnl-3.2.29/include/netlink/cli/addr.h0000644000175000017500000000224613023014600014542 00000000000000/* * netlink/cli/addr.h CLI Address Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ #ifndef __NETLINK_CLI_ADDR_H_ #define __NETLINK_CLI_ADDR_H_ #include #define nl_cli_addr_alloc_cache(sk) \ nl_cli_alloc_cache((sk), "address", rtnl_addr_alloc_cache) extern struct rtnl_addr *nl_cli_addr_alloc(void); extern void nl_cli_addr_parse_family(struct rtnl_addr *, char *); extern void nl_cli_addr_parse_local(struct rtnl_addr *, char *); extern void nl_cli_addr_parse_dev(struct rtnl_addr *, struct nl_cache *,char *); extern void nl_cli_addr_parse_label(struct rtnl_addr *, char *); extern void nl_cli_addr_parse_peer(struct rtnl_addr *, char *); extern void nl_cli_addr_parse_scope(struct rtnl_addr *, char *); extern void nl_cli_addr_parse_broadcast(struct rtnl_addr *, char *); extern void nl_cli_addr_parse_preferred(struct rtnl_addr *, char *); extern void nl_cli_addr_parse_valid(struct rtnl_addr *, char *); #endif libnl-3.2.29/include/netlink/cli/neigh.h0000644000175000017500000000173713023014600014726 00000000000000/* * netlink/cli/neighbour.h CLI Neighbour Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ #ifndef __NETLINK_CLI_NEIGH_H_ #define __NETLINK_CLI_NEIGH_H_ #include #define nl_cli_neigh_alloc_cache(sk) \ nl_cli_alloc_cache_flags((sk), "neighbour", NL_CACHE_AF_ITER, \ rtnl_neigh_alloc_cache_flags) extern struct rtnl_neigh *nl_cli_neigh_alloc(void); extern void nl_cli_neigh_parse_dst(struct rtnl_neigh *, char *); extern void nl_cli_neigh_parse_lladdr(struct rtnl_neigh *, char *); extern void nl_cli_neigh_parse_dev(struct rtnl_neigh *, struct nl_cache *, char *); extern void nl_cli_neigh_parse_family(struct rtnl_neigh *, char *); extern void nl_cli_neigh_parse_state(struct rtnl_neigh *, char *); #endif libnl-3.2.29/include/netlink/cli/link.h0000644000175000017500000000245513023014600014567 00000000000000/* * netlink/cli/link.h CLI Link Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2010 Thomas Graf */ #ifndef __NETLINK_CLI_LINK_H_ #define __NETLINK_CLI_LINK_H_ #include #include extern struct rtnl_link *nl_cli_link_alloc(void); extern struct nl_cache *nl_cli_link_alloc_cache_family(struct nl_sock *, int); extern struct nl_cache *nl_cli_link_alloc_cache_family_flags(struct nl_sock *, int, unsigned int); extern struct nl_cache *nl_cli_link_alloc_cache(struct nl_sock *); extern struct nl_cache *nl_cli_link_alloc_cache_flags(struct nl_sock *, unsigned int); extern void nl_cli_link_parse_family(struct rtnl_link *, char *); extern void nl_cli_link_parse_name(struct rtnl_link *, char *); extern void nl_cli_link_parse_mtu(struct rtnl_link *, char *); extern void nl_cli_link_parse_ifindex(struct rtnl_link *, char *); extern void nl_cli_link_parse_txqlen(struct rtnl_link *, char *); extern void nl_cli_link_parse_weight(struct rtnl_link *, char *); extern void nl_cli_link_parse_ifalias(struct rtnl_link *, char *); #endif libnl-3.2.29/include/netlink/cli/rule.h0000644000175000017500000000115313023014600014573 00000000000000/* * netlink/cli/rule.h CLI Routing Rule Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ #ifndef __NETLINK_CLI_RULE_H_ #define __NETLINK_CLI_RULE_H_ #include extern struct rtnl_rule *nl_cli_rule_alloc(void); extern struct nl_cache *nl_cli_rule_alloc_cache(struct nl_sock *); extern void nl_cli_rule_parse_family(struct rtnl_rule *, char *); #endif libnl-3.2.29/include/netlink/cli/utils.h0000644000175000017500000000456213023014600014773 00000000000000/* * src/utils.h Utilities * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #ifndef __NETLINK_CLI_UTILS_H_ #define __NETLINK_CLI_UTILS_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #ifndef __init #define __init __attribute__((constructor)) #endif #ifndef __exit #define __exit __attribute__((destructor)) #endif extern uint32_t nl_cli_parse_u32(const char *); extern void nl_cli_print_version(void) __attribute__((noreturn)); extern void nl_cli_fatal(int, const char *, ...) __attribute__((noreturn)); extern struct nl_addr * nl_cli_addr_parse(const char *, int); extern int nl_cli_connect(struct nl_sock *, int); extern struct nl_sock * nl_cli_alloc_socket(void); extern int nl_cli_parse_dumptype(const char *); extern int nl_cli_confirm(struct nl_object *, struct nl_dump_params *, int); extern struct nl_cache *nl_cli_alloc_cache(struct nl_sock *, const char *, int (*ac)(struct nl_sock *, struct nl_cache **)); extern struct nl_cache *nl_cli_alloc_cache_flags(struct nl_sock *, const char *, unsigned int flags, int (*ac)(struct nl_sock *, struct nl_cache **, unsigned int)); extern void nl_cli_load_module(const char *, const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/cli/route.h0000644000175000017500000000257513023014600014773 00000000000000/* * netlink/cli//route.h CLI Route Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ #ifndef __NETLINK_CLI_ROUTE_H_ #define __NETLINK_CLI_ROUTE_H_ #include extern struct rtnl_route *nl_cli_route_alloc(void); extern struct nl_cache *nl_cli_route_alloc_cache(struct nl_sock *, int); extern void nl_cli_route_parse_family(struct rtnl_route *, char *); extern void nl_cli_route_parse_dst(struct rtnl_route *, char *); extern void nl_cli_route_parse_src(struct rtnl_route *, char *); extern void nl_cli_route_parse_pref_src(struct rtnl_route *, char *); extern void nl_cli_route_parse_metric(struct rtnl_route *, char *); extern void nl_cli_route_parse_nexthop(struct rtnl_route *, char *, struct nl_cache *); extern void nl_cli_route_parse_table(struct rtnl_route *, char *); extern void nl_cli_route_parse_prio(struct rtnl_route *, char *); extern void nl_cli_route_parse_scope(struct rtnl_route *, char *); extern void nl_cli_route_parse_protocol(struct rtnl_route *, char *); extern void nl_cli_route_parse_type(struct rtnl_route *, char *); extern void nl_cli_route_parse_iif(struct rtnl_route *, char *, struct nl_cache *); #endif libnl-3.2.29/include/netlink/cli/exp.h0000644000175000017500000000337713023014600014432 00000000000000/* * netlink/cli/exp.h CLI Expectation Helper * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Rich Fought * Copyright (c) 2008-2009 Thomas Graf */ #ifndef __NETLINK_CLI_EXP_H_ #define __NETLINK_CLI_EXP_H_ #include #include extern struct nfnl_exp *nl_cli_exp_alloc(void); extern struct nl_cache *nl_cli_exp_alloc_cache(struct nl_sock *); extern void nl_cli_exp_parse_family(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_timeout(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_id(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_helper_name(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_zone(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_flags(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_class(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_nat_dir(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_fn(struct nfnl_exp *, char *); extern void nl_cli_exp_parse_src(struct nfnl_exp *, int, char *); extern void nl_cli_exp_parse_dst(struct nfnl_exp *, int, char *); extern void nl_cli_exp_parse_l4protonum(struct nfnl_exp *, int, char *); extern void nl_cli_exp_parse_src_port(struct nfnl_exp *, int, char *); extern void nl_cli_exp_parse_dst_port(struct nfnl_exp *, int, char *); extern void nl_cli_exp_parse_icmp_id(struct nfnl_exp *, int, char *); extern void nl_cli_exp_parse_icmp_type(struct nfnl_exp *, int, char *); extern void nl_cli_exp_parse_icmp_code(struct nfnl_exp *, int, char *); #endif libnl-3.2.29/include/netlink/cli/ct.h0000644000175000017500000000257413023014600014242 00000000000000/* * netlink/cli/ct.h CLI Conntrack Helper * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ #ifndef __NETLINK_CLI_CT_H_ #define __NETLINK_CLI_CT_H_ #include #include extern struct nfnl_ct *nl_cli_ct_alloc(void); extern struct nl_cache *nl_cli_ct_alloc_cache(struct nl_sock *); extern void nl_cli_ct_parse_family(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_protocol(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_mark(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_timeout(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_id(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_use(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_src(struct nfnl_ct *, int, char *); extern void nl_cli_ct_parse_dst(struct nfnl_ct *, int, char *); extern void nl_cli_ct_parse_src_port(struct nfnl_ct *, int, char *); extern void nl_cli_ct_parse_dst_port(struct nfnl_ct *, int, char *); extern void nl_cli_ct_parse_tcp_state(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_status(struct nfnl_ct *, char *); extern void nl_cli_ct_parse_zone(struct nfnl_ct *, char *); #endif libnl-3.2.29/include/netlink/cli/tc.h0000644000175000017500000000252313023014600014234 00000000000000/* * netlink/cli/tc.h CLI Traffic Control Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ #ifndef __NETLINK_CLI_TC_H_ #define __NETLINK_CLI_TC_H_ #include struct rtnl_tc_ops; extern void nl_cli_tc_parse_dev(struct rtnl_tc *, struct nl_cache *, char *); extern void nl_cli_tc_parse_parent(struct rtnl_tc *, char *); extern void nl_cli_tc_parse_handle(struct rtnl_tc *, char *, int); extern void nl_cli_tc_parse_mtu(struct rtnl_tc *, char *); extern void nl_cli_tc_parse_mpu(struct rtnl_tc *, char *); extern void nl_cli_tc_parse_overhead(struct rtnl_tc *, char *); extern void nl_cli_tc_parse_linktype(struct rtnl_tc *, char *); extern void nl_cli_tc_parse_kind(struct rtnl_tc *, char *); struct nl_cli_tc_module { const char * tm_name; enum rtnl_tc_type tm_type; struct rtnl_tc_ops * tm_ops; void (*tm_parse_argv)(struct rtnl_tc *, int, char **); struct nl_list_head tm_list; }; extern struct nl_cli_tc_module *nl_cli_tc_lookup(struct rtnl_tc_ops *); extern void nl_cli_tc_register(struct nl_cli_tc_module *); extern void nl_cli_tc_unregister(struct nl_cli_tc_module *); #endif libnl-3.2.29/include/netlink/fib_lookup/0000755000175000017500000000000013031473755015140 500000000000000libnl-3.2.29/include/netlink/fib_lookup/lookup.h0000644000175000017500000000172713023014600016526 00000000000000/* * netlink/fib_lookup/fib_lookup.h FIB Lookup * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_FIB_LOOKUP_H_ #define NETLINK_FIB_LOOKUP_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct flnl_result; extern struct flnl_result * flnl_result_alloc(void); extern void flnl_result_put(struct flnl_result *); extern struct nl_cache * flnl_result_alloc_cache(void); extern int flnl_lookup_build_request(struct flnl_request *, int, struct nl_msg **); extern int flnl_lookup(struct nl_sock *, struct flnl_request *, struct nl_cache *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/fib_lookup/request.h0000644000175000017500000000271412505607054016721 00000000000000/* * netlink/fib_lookup/request.h FIB Lookup Request * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_FIB_LOOKUP_REQUEST_H_ #define NETLINK_FIB_LOOKUP_REQUEST_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct flnl_request; #define REQUEST_CAST(ptr) ((struct flnl_request *) (ptr)) extern struct flnl_request * flnl_request_alloc(void); extern void flnl_request_set_fwmark(struct flnl_request *, uint64_t); extern uint64_t flnl_request_get_fwmark(struct flnl_request *); extern void flnl_request_set_tos(struct flnl_request *, int); extern int flnl_request_get_tos(struct flnl_request *); extern void flnl_request_set_scope(struct flnl_request *, int); extern int flnl_request_get_scope(struct flnl_request *); extern void flnl_request_set_table(struct flnl_request *, int); extern int flnl_request_get_table(struct flnl_request *); extern int flnl_request_set_addr(struct flnl_request *, struct nl_addr *); extern struct nl_addr * flnl_request_get_addr(struct flnl_request *); extern int flnl_request_cmp(struct flnl_request *, struct flnl_request *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/0000755000175000017500000000000013031473756015004 500000000000000libnl-3.2.29/include/netlink/netfilter/queue.h0000644000175000017500000000525713023014600016206 00000000000000/* * netlink/netfilter/queue.h Netfilter Queue * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy */ #ifndef NETLINK_QUEUE_H_ #define NETLINK_QUEUE_H_ #include #ifdef __cplusplus extern "C" { #endif struct nl_sock; struct nlmsghdr; struct nfnl_queue; extern struct nl_object_ops queue_obj_ops; enum nfnl_queue_copy_mode { NFNL_QUEUE_COPY_NONE, NFNL_QUEUE_COPY_META, NFNL_QUEUE_COPY_PACKET, }; /* General */ extern struct nl_sock * nfnl_queue_socket_alloc(void); extern struct nfnl_queue * nfnl_queue_alloc(void); extern void nfnl_queue_get(struct nfnl_queue *); extern void nfnl_queue_put(struct nfnl_queue *); /* Attributes */ extern void nfnl_queue_set_group(struct nfnl_queue *, uint16_t); extern int nfnl_queue_test_group(const struct nfnl_queue *); extern uint16_t nfnl_queue_get_group(const struct nfnl_queue *); extern void nfnl_queue_set_maxlen(struct nfnl_queue *, uint32_t); extern int nfnl_queue_test_maxlen(const struct nfnl_queue *); extern uint32_t nfnl_queue_get_maxlen(const struct nfnl_queue *); extern void nfnl_queue_set_copy_mode(struct nfnl_queue *, enum nfnl_queue_copy_mode); extern int nfnl_queue_test_copy_mode(const struct nfnl_queue *); extern enum nfnl_queue_copy_mode nfnl_queue_get_copy_mode(const struct nfnl_queue *); extern char * nfnl_queue_copy_mode2str(enum nfnl_queue_copy_mode, char *, size_t); extern int nfnl_queue_str2copy_mode(const char *); extern void nfnl_queue_set_copy_range(struct nfnl_queue *, uint32_t); extern int nfnl_queue_test_copy_range(const struct nfnl_queue *); extern uint32_t nfnl_queue_get_copy_range(const struct nfnl_queue *); extern int nfnl_queue_build_pf_bind(uint8_t, struct nl_msg **); extern int nfnl_queue_pf_bind(struct nl_sock *, uint8_t); extern int nfnl_queue_build_pf_unbind(uint8_t, struct nl_msg **); extern int nfnl_queue_pf_unbind(struct nl_sock *, uint8_t); extern int nfnl_queue_build_create_request(const struct nfnl_queue *, struct nl_msg **); extern int nfnl_queue_create(struct nl_sock *, const struct nfnl_queue *); extern int nfnl_queue_build_change_request(const struct nfnl_queue *, struct nl_msg **); extern int nfnl_queue_change(struct nl_sock *, const struct nfnl_queue *); extern int nfnl_queue_build_delete_request(const struct nfnl_queue *, struct nl_msg **); extern int nfnl_queue_delete(struct nl_sock *, const struct nfnl_queue *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/netfilter.h0000644000175000017500000000135613023014600017052 00000000000000/* * netlink/netfilter/netfilter.h Netfilter generic functions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008 Patrick McHardy */ #ifndef NETLINK_NETFILTER_H_ #define NETLINK_NETFILTER_H_ #include #ifdef __cplusplus extern "C" { #endif extern char * nfnl_verdict2str(unsigned int, char *, size_t); extern unsigned int nfnl_str2verdict(const char *); extern char * nfnl_inet_hook2str(unsigned int, char *, size_t); extern unsigned int nfnl_str2inet_hook(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/nfnl.h0000644000175000017500000000237113023014600016011 00000000000000/* * netlink/nfnl/nfnl.h Netfilter Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #ifndef NETLINK_NFNL_H_ #define NETLINK_NFNL_H_ #include #ifdef __cplusplus extern "C" { #endif #define NFNL_HDRLEN NLMSG_ALIGN(sizeof(struct nfgenmsg)) #define NFNLMSG_TYPE(subsys, subtype) (((subsys) << 8) | (subtype)) extern int nfnl_connect(struct nl_sock *); extern uint8_t nfnlmsg_subsys(struct nlmsghdr *); extern uint8_t nfnlmsg_subtype(struct nlmsghdr *); extern uint8_t nfnlmsg_family(struct nlmsghdr *); extern uint16_t nfnlmsg_res_id(struct nlmsghdr *); extern int nfnl_send_simple(struct nl_sock *, uint8_t, uint8_t, int, uint8_t, uint16_t); extern struct nl_msg * nfnlmsg_alloc_simple(uint8_t, uint8_t, int, uint8_t, uint16_t); extern int nfnlmsg_put(struct nl_msg *, uint32_t, uint32_t, uint8_t, uint8_t, int, uint8_t, uint16_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/log_msg.h0000644000175000017500000000736613023014600016514 00000000000000/* * netlink/netfilter/log_msg.h Netfilter Log Message * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2008 Patrick McHardy */ #ifndef NETLINK_LOG_MSG_H_ #define NETLINK_LOG_MSG_H_ #include #ifdef __cplusplus extern "C" { #endif struct nlmsghdr; struct nfnl_log_msg; extern struct nl_object_ops log_msg_obj_ops; /* General */ extern struct nfnl_log_msg *nfnl_log_msg_alloc(void); extern int nfnlmsg_log_msg_parse(struct nlmsghdr *, struct nfnl_log_msg **); extern void nfnl_log_msg_get(struct nfnl_log_msg *); extern void nfnl_log_msg_put(struct nfnl_log_msg *); extern void nfnl_log_msg_set_family(struct nfnl_log_msg *, uint8_t); extern uint8_t nfnl_log_msg_get_family(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_hwproto(struct nfnl_log_msg *, uint16_t); extern int nfnl_log_msg_test_hwproto(const struct nfnl_log_msg *); extern uint16_t nfnl_log_msg_get_hwproto(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_hook(struct nfnl_log_msg *, uint8_t); extern int nfnl_log_msg_test_hook(const struct nfnl_log_msg *); extern uint8_t nfnl_log_msg_get_hook(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_mark(struct nfnl_log_msg *, uint32_t); extern int nfnl_log_msg_test_mark(const struct nfnl_log_msg *); extern uint32_t nfnl_log_msg_get_mark(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_timestamp(struct nfnl_log_msg *, struct timeval *); extern const struct timeval *nfnl_log_msg_get_timestamp(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_indev(struct nfnl_log_msg *, uint32_t); extern uint32_t nfnl_log_msg_get_indev(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_outdev(struct nfnl_log_msg *, uint32_t); extern uint32_t nfnl_log_msg_get_outdev(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_physindev(struct nfnl_log_msg *, uint32_t); extern uint32_t nfnl_log_msg_get_physindev(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_physoutdev(struct nfnl_log_msg *, uint32_t); extern uint32_t nfnl_log_msg_get_physoutdev(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_hwaddr(struct nfnl_log_msg *, uint8_t *, int); extern const uint8_t * nfnl_log_msg_get_hwaddr(const struct nfnl_log_msg *, int *); extern int nfnl_log_msg_set_payload(struct nfnl_log_msg *, uint8_t *, int); extern const void * nfnl_log_msg_get_payload(const struct nfnl_log_msg *, int *); extern int nfnl_log_msg_set_prefix(struct nfnl_log_msg *, void *); extern const char * nfnl_log_msg_get_prefix(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_uid(struct nfnl_log_msg *, uint32_t); extern int nfnl_log_msg_test_uid(const struct nfnl_log_msg *); extern uint32_t nfnl_log_msg_get_uid(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_gid(struct nfnl_log_msg *, uint32_t); extern int nfnl_log_msg_test_gid(const struct nfnl_log_msg *); extern uint32_t nfnl_log_msg_get_gid(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_seq(struct nfnl_log_msg *, uint32_t); extern int nfnl_log_msg_test_seq(const struct nfnl_log_msg *); extern uint32_t nfnl_log_msg_get_seq(const struct nfnl_log_msg *); extern void nfnl_log_msg_set_seq_global(struct nfnl_log_msg *, uint32_t); extern int nfnl_log_msg_test_seq_global(const struct nfnl_log_msg *); extern uint32_t nfnl_log_msg_get_seq_global(const struct nfnl_log_msg *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/queue_msg.h0000644000175000017500000001075513023014600017053 00000000000000/* * netlink/netfilter/queue_msg.h Netfilter Queue Messages * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy */ #ifndef NETLINK_QUEUE_MSG_H_ #define NETLINK_QUEUE_MSG_H_ #include #ifdef __cplusplus extern "C" { #endif struct nl_sock; struct nlmsghdr; struct nfnl_queue_msg; extern struct nl_object_ops queue_msg_obj_ops; /* General */ extern struct nfnl_queue_msg * nfnl_queue_msg_alloc(void); extern int nfnlmsg_queue_msg_parse(struct nlmsghdr *, struct nfnl_queue_msg **); extern void nfnl_queue_msg_get(struct nfnl_queue_msg *); extern void nfnl_queue_msg_put(struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_group(struct nfnl_queue_msg *, uint16_t); extern int nfnl_queue_msg_test_group(const struct nfnl_queue_msg *); extern uint16_t nfnl_queue_msg_get_group(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_family(struct nfnl_queue_msg *, uint8_t); extern int nfnl_queue_msg_test_family(const struct nfnl_queue_msg *); extern uint8_t nfnl_queue_msg_get_family(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_packetid(struct nfnl_queue_msg *, uint32_t); extern int nfnl_queue_msg_test_packetid(const struct nfnl_queue_msg *); extern uint32_t nfnl_queue_msg_get_packetid(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_hwproto(struct nfnl_queue_msg *, uint16_t); extern int nfnl_queue_msg_test_hwproto(const struct nfnl_queue_msg *); extern uint16_t nfnl_queue_msg_get_hwproto(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_hook(struct nfnl_queue_msg *, uint8_t); extern int nfnl_queue_msg_test_hook(const struct nfnl_queue_msg *); extern uint8_t nfnl_queue_msg_get_hook(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_mark(struct nfnl_queue_msg *, uint32_t); extern int nfnl_queue_msg_test_mark(const struct nfnl_queue_msg *); extern uint32_t nfnl_queue_msg_get_mark(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_timestamp(struct nfnl_queue_msg *, struct timeval *); extern int nfnl_queue_msg_test_timestamp(const struct nfnl_queue_msg *); extern const struct timeval * nfnl_queue_msg_get_timestamp(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_indev(struct nfnl_queue_msg *, uint32_t); extern int nfnl_queue_msg_test_indev(const struct nfnl_queue_msg *); extern uint32_t nfnl_queue_msg_get_indev(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_outdev(struct nfnl_queue_msg *, uint32_t); extern int nfnl_queue_msg_test_outdev(const struct nfnl_queue_msg *); extern uint32_t nfnl_queue_msg_get_outdev(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_physindev(struct nfnl_queue_msg *, uint32_t); extern int nfnl_queue_msg_test_physindev(const struct nfnl_queue_msg *); extern uint32_t nfnl_queue_msg_get_physindev(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_physoutdev(struct nfnl_queue_msg *, uint32_t); extern int nfnl_queue_msg_test_physoutdev(const struct nfnl_queue_msg *); extern uint32_t nfnl_queue_msg_get_physoutdev(const struct nfnl_queue_msg *); extern void nfnl_queue_msg_set_hwaddr(struct nfnl_queue_msg *, uint8_t *, int); extern int nfnl_queue_msg_test_hwaddr(const struct nfnl_queue_msg *); extern const uint8_t * nfnl_queue_msg_get_hwaddr(const struct nfnl_queue_msg *, int *); extern int nfnl_queue_msg_set_payload(struct nfnl_queue_msg *, uint8_t *, int); extern int nfnl_queue_msg_test_payload(const struct nfnl_queue_msg *); extern const void * nfnl_queue_msg_get_payload(const struct nfnl_queue_msg *, int *); extern void nfnl_queue_msg_set_verdict(struct nfnl_queue_msg *, unsigned int); extern int nfnl_queue_msg_test_verdict(const struct nfnl_queue_msg *); extern unsigned int nfnl_queue_msg_get_verdict(const struct nfnl_queue_msg *); extern struct nl_msg * nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *); extern int nfnl_queue_msg_send_verdict(struct nl_sock *, const struct nfnl_queue_msg *); extern int nfnl_queue_msg_send_verdict_batch(struct nl_sock *, const struct nfnl_queue_msg *); extern int nfnl_queue_msg_send_verdict_payload(struct nl_sock *, const struct nfnl_queue_msg *, const void *, unsigned ); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/exp.h0000644000175000017500000001133613023014600015651 00000000000000/* * netlink/netfilter/exp.h Conntrack Expectation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2012 Rich Fought */ #ifndef NETLINK_EXP_H_ #define NETLINK_EXP_H_ #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct nfnl_exp; enum nfnl_exp_tuples { NFNL_EXP_TUPLE_EXPECT, NFNL_EXP_TUPLE_MASTER, NFNL_EXP_TUPLE_MASK, NFNL_EXP_TUPLE_NAT, NFNL_EXP_TUPLE_MAX }; extern struct nl_object_ops exp_obj_ops; extern struct nfnl_exp * nfnl_exp_alloc(void); extern int nfnl_exp_alloc_cache(struct nl_sock *, struct nl_cache **); extern int nfnlmsg_exp_group(struct nlmsghdr *); extern int nfnlmsg_exp_parse(struct nlmsghdr *, struct nfnl_exp **); extern void nfnl_exp_get(struct nfnl_exp *); extern void nfnl_exp_put(struct nfnl_exp *); extern int nfnl_exp_dump_request(struct nl_sock *); extern int nfnl_exp_build_add_request(const struct nfnl_exp *, int, struct nl_msg **); extern int nfnl_exp_add(struct nl_sock *, const struct nfnl_exp *, int); extern int nfnl_exp_build_delete_request(const struct nfnl_exp *, int, struct nl_msg **); extern int nfnl_exp_del(struct nl_sock *, const struct nfnl_exp *, int); extern int nfnl_exp_build_query_request(const struct nfnl_exp *, int, struct nl_msg **); extern int nfnl_exp_query(struct nl_sock *, const struct nfnl_exp *, int); extern void nfnl_exp_set_family(struct nfnl_exp *, uint8_t); extern uint8_t nfnl_exp_get_family(const struct nfnl_exp *); extern void nfnl_exp_set_timeout(struct nfnl_exp *, uint32_t); extern int nfnl_exp_test_timeout(const struct nfnl_exp *); extern uint32_t nfnl_exp_get_timeout(const struct nfnl_exp *); extern void nfnl_exp_set_id(struct nfnl_exp *, uint32_t); extern int nfnl_exp_test_id(const struct nfnl_exp *); extern uint32_t nfnl_exp_get_id(const struct nfnl_exp *); extern int nfnl_exp_set_helper_name(struct nfnl_exp *, void *); extern int nfnl_exp_test_helper_name(const struct nfnl_exp *); extern const char * nfnl_exp_get_helper_name(const struct nfnl_exp *); extern void nfnl_exp_set_zone(struct nfnl_exp *, uint16_t); extern int nfnl_exp_test_zone(const struct nfnl_exp *); extern uint16_t nfnl_exp_get_zone(const struct nfnl_exp *); extern void nfnl_exp_set_flags(struct nfnl_exp *, uint32_t); extern int nfnl_exp_test_flags(const struct nfnl_exp *); extern uint32_t nfnl_exp_get_flags(const struct nfnl_exp *); extern void nfnl_exp_set_class(struct nfnl_exp *, uint32_t); extern int nfnl_exp_test_class(const struct nfnl_exp *); extern uint32_t nfnl_exp_get_class(const struct nfnl_exp *); extern int nfnl_exp_set_fn(struct nfnl_exp *, void *); extern int nfnl_exp_test_fn(const struct nfnl_exp *); extern const char * nfnl_exp_get_fn(const struct nfnl_exp *); extern void nfnl_exp_set_nat_dir(struct nfnl_exp *, uint8_t); extern int nfnl_exp_test_nat_dir(const struct nfnl_exp *); extern uint8_t nfnl_exp_get_nat_dir(const struct nfnl_exp *); // The int argument specifies which nfnl_exp_dir (expect, master, mask or nat) // Expectation objects only use orig, not reply extern int nfnl_exp_set_src(struct nfnl_exp *, int, struct nl_addr *); extern int nfnl_exp_test_src(const struct nfnl_exp *, int); extern struct nl_addr * nfnl_exp_get_src(const struct nfnl_exp *, int); extern int nfnl_exp_set_dst(struct nfnl_exp *, int, struct nl_addr *); extern int nfnl_exp_test_dst(const struct nfnl_exp *, int); extern struct nl_addr * nfnl_exp_get_dst(const struct nfnl_exp *, int); extern void nfnl_exp_set_l4protonum(struct nfnl_exp *, int, uint8_t); extern int nfnl_exp_test_l4protonum(const struct nfnl_exp *, int); extern uint8_t nfnl_exp_get_l4protonum(const struct nfnl_exp *, int); extern void nfnl_exp_set_ports(struct nfnl_exp *, int, uint16_t, uint16_t); extern int nfnl_exp_test_ports(const struct nfnl_exp *, int); extern uint16_t nfnl_exp_get_src_port(const struct nfnl_exp *, int); extern uint16_t nfnl_exp_get_dst_port(const struct nfnl_exp *, int); extern void nfnl_exp_set_icmp(struct nfnl_exp *, int, uint16_t, uint8_t, uint8_t); extern int nfnl_exp_test_icmp(const struct nfnl_exp *, int); extern uint16_t nfnl_exp_get_icmp_id(const struct nfnl_exp *, int); extern uint8_t nfnl_exp_get_icmp_type(const struct nfnl_exp *, int); extern uint8_t nfnl_exp_get_icmp_code(const struct nfnl_exp *, int); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/ct.h0000644000175000017500000001230013023014600015453 00000000000000/* * netlink/netfilter/ct.h Conntrack * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #ifndef NETLINK_CT_H_ #define NETLINK_CT_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct nfnl_ct; struct nfnl_ct_timestamp { uint64_t start; uint64_t stop; }; extern struct nl_object_ops ct_obj_ops; extern struct nfnl_ct * nfnl_ct_alloc(void); extern int nfnl_ct_alloc_cache(struct nl_sock *, struct nl_cache **); extern int nfnlmsg_ct_group(struct nlmsghdr *); extern int nfnlmsg_ct_parse(struct nlmsghdr *, struct nfnl_ct **); extern void nfnl_ct_get(struct nfnl_ct *); extern void nfnl_ct_put(struct nfnl_ct *); extern int nfnl_ct_dump_request(struct nl_sock *); extern int nfnl_ct_build_add_request(const struct nfnl_ct *, int, struct nl_msg **); extern int nfnl_ct_add(struct nl_sock *, const struct nfnl_ct *, int); extern int nfnl_ct_build_delete_request(const struct nfnl_ct *, int, struct nl_msg **); extern int nfnl_ct_del(struct nl_sock *, const struct nfnl_ct *, int); extern int nfnl_ct_build_query_request(const struct nfnl_ct *, int, struct nl_msg **); extern int nfnl_ct_query(struct nl_sock *, const struct nfnl_ct *, int); extern void nfnl_ct_set_family(struct nfnl_ct *, uint8_t); extern uint8_t nfnl_ct_get_family(const struct nfnl_ct *); extern void nfnl_ct_set_proto(struct nfnl_ct *, uint8_t); extern int nfnl_ct_test_proto(const struct nfnl_ct *); extern uint8_t nfnl_ct_get_proto(const struct nfnl_ct *); extern void nfnl_ct_set_tcp_state(struct nfnl_ct *, uint8_t); extern int nfnl_ct_test_tcp_state(const struct nfnl_ct *); extern uint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *); extern char * nfnl_ct_tcp_state2str(uint8_t, char *, size_t); extern int nfnl_ct_str2tcp_state(const char *name); extern void nfnl_ct_set_status(struct nfnl_ct *, uint32_t); extern void nfnl_ct_unset_status(struct nfnl_ct *, uint32_t); extern int nfnl_ct_test_status(const struct nfnl_ct *ct); extern uint32_t nfnl_ct_get_status(const struct nfnl_ct *); extern char * nfnl_ct_status2str(int, char *, size_t); extern int nfnl_ct_str2status(const char *); extern void nfnl_ct_set_timeout(struct nfnl_ct *, uint32_t); extern int nfnl_ct_test_timeout(const struct nfnl_ct *); extern uint32_t nfnl_ct_get_timeout(const struct nfnl_ct *); extern void nfnl_ct_set_mark(struct nfnl_ct *, uint32_t); extern int nfnl_ct_test_mark(const struct nfnl_ct *); extern uint32_t nfnl_ct_get_mark(const struct nfnl_ct *); extern void nfnl_ct_set_use(struct nfnl_ct *, uint32_t); extern int nfnl_ct_test_use(const struct nfnl_ct *); extern uint32_t nfnl_ct_get_use(const struct nfnl_ct *); extern void nfnl_ct_set_id(struct nfnl_ct *, uint32_t); extern int nfnl_ct_test_id(const struct nfnl_ct *); extern uint32_t nfnl_ct_get_id(const struct nfnl_ct *); extern void nfnl_ct_set_zone(struct nfnl_ct *, uint16_t); extern int nfnl_ct_test_zone(const struct nfnl_ct *); extern uint16_t nfnl_ct_get_zone(const struct nfnl_ct *); extern int nfnl_ct_set_src(struct nfnl_ct *, int, struct nl_addr *); extern struct nl_addr * nfnl_ct_get_src(const struct nfnl_ct *, int); extern int nfnl_ct_set_dst(struct nfnl_ct *, int, struct nl_addr *); extern struct nl_addr * nfnl_ct_get_dst(const struct nfnl_ct *, int); extern void nfnl_ct_set_src_port(struct nfnl_ct *, int, uint16_t); extern int nfnl_ct_test_src_port(const struct nfnl_ct *, int); extern uint16_t nfnl_ct_get_src_port(const struct nfnl_ct *, int); extern void nfnl_ct_set_dst_port(struct nfnl_ct *, int, uint16_t); extern int nfnl_ct_test_dst_port(const struct nfnl_ct *, int); extern uint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *, int); extern void nfnl_ct_set_icmp_id(struct nfnl_ct *, int, uint16_t); extern int nfnl_ct_test_icmp_id(const struct nfnl_ct *, int); extern uint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *, int); extern void nfnl_ct_set_icmp_type(struct nfnl_ct *, int, uint8_t); extern int nfnl_ct_test_icmp_type(const struct nfnl_ct *, int); extern uint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *, int); extern void nfnl_ct_set_icmp_code(struct nfnl_ct *, int, uint8_t); extern int nfnl_ct_test_icmp_code(const struct nfnl_ct *, int); extern uint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *, int); extern void nfnl_ct_set_packets(struct nfnl_ct *, int, uint64_t); extern int nfnl_ct_test_packets(const struct nfnl_ct *, int); extern uint64_t nfnl_ct_get_packets(const struct nfnl_ct *,int); extern void nfnl_ct_set_bytes(struct nfnl_ct *, int, uint64_t); extern int nfnl_ct_test_bytes(const struct nfnl_ct *, int); extern uint64_t nfnl_ct_get_bytes(const struct nfnl_ct *, int); extern void nfnl_ct_set_timestamp(struct nfnl_ct *, uint64_t, uint64_t); extern int nfnl_ct_test_timestamp(const struct nfnl_ct *); extern const struct nfnl_ct_timestamp *nfnl_ct_get_timestamp(const struct nfnl_ct *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netfilter/log.h0000644000175000017500000000707013023014600015636 00000000000000/* * netlink/netfilter/log.h Netfilter Log * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2008 Patrick McHardy */ #ifndef NETLINK_LOG_H_ #define NETLINK_LOG_H_ #include #ifdef __cplusplus extern "C" { #endif struct nl_sock; struct nlmsghdr; struct nfnl_log; extern struct nl_object_ops log_obj_ops; enum nfnl_log_copy_mode { NFNL_LOG_COPY_NONE, NFNL_LOG_COPY_META, NFNL_LOG_COPY_PACKET, }; enum nfnl_log_flags { NFNL_LOG_FLAG_SEQ = 0x1, NFNL_LOG_FLAG_SEQ_GLOBAL = 0x2, }; /* General */ extern struct nfnl_log * nfnl_log_alloc(void); extern int nfnlmsg_log_parse(struct nlmsghdr *, struct nfnl_log **); extern void nfnl_log_get(struct nfnl_log *); extern void nfnl_log_put(struct nfnl_log *); /* Attributes */ extern void nfnl_log_set_group(struct nfnl_log *, uint16_t); extern int nfnl_log_test_group(const struct nfnl_log *); extern uint16_t nfnl_log_get_group(const struct nfnl_log *); extern void nfnl_log_set_copy_mode(struct nfnl_log *, enum nfnl_log_copy_mode); extern int nfnl_log_test_copy_mode(const struct nfnl_log *); extern enum nfnl_log_copy_mode nfnl_log_get_copy_mode(const struct nfnl_log *); extern char * nfnl_log_copy_mode2str(enum nfnl_log_copy_mode, char *, size_t); extern int nfnl_log_str2copy_mode(const char *); extern void nfnl_log_set_copy_range(struct nfnl_log *, uint32_t); extern int nfnl_log_test_copy_range(const struct nfnl_log *); extern uint32_t nfnl_log_get_copy_range(const struct nfnl_log *); extern void nfnl_log_set_flush_timeout(struct nfnl_log *, uint32_t); extern int nfnl_log_test_flush_timeout(const struct nfnl_log *); extern uint32_t nfnl_log_get_flush_timeout(const struct nfnl_log *); extern void nfnl_log_set_alloc_size(struct nfnl_log *, uint32_t); extern int nfnl_log_test_alloc_size(const struct nfnl_log *); extern uint32_t nfnl_log_get_alloc_size(const struct nfnl_log *); extern void nfnl_log_set_queue_threshold(struct nfnl_log *, uint32_t); extern int nfnl_log_test_queue_threshold(const struct nfnl_log *); extern uint32_t nfnl_log_get_queue_threshold(const struct nfnl_log *); extern void nfnl_log_set_flags(struct nfnl_log *, unsigned int); extern void nfnl_log_unset_flags(struct nfnl_log *, unsigned int); extern unsigned int nfnl_log_get_flags(const struct nfnl_log *); extern char * nfnl_log_flags2str(unsigned int, char *, size_t); extern unsigned int nfnl_log_str2flags(const char *); extern int nfnl_log_build_pf_bind(uint8_t, struct nl_msg **); extern int nfnl_log_pf_bind(struct nl_sock *, uint8_t); extern int nfnl_log_build_pf_unbind(uint8_t, struct nl_msg **); extern int nfnl_log_pf_unbind(struct nl_sock *, uint8_t); extern int nfnl_log_build_create_request(const struct nfnl_log *, struct nl_msg **); extern int nfnl_log_create(struct nl_sock *, const struct nfnl_log *); extern int nfnl_log_build_change_request(const struct nfnl_log *, struct nl_msg **); extern int nfnl_log_change(struct nl_sock *, const struct nfnl_log *); extern int nfnl_log_build_delete_request(const struct nfnl_log *, struct nl_msg **); extern int nfnl_log_delete(struct nl_sock *, const struct nfnl_log *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/version.h0000644000175000017500000000166113031473646014570 00000000000000/* * netlink/version.h Versioning Information * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2011 Thomas Graf */ #ifndef NETLINK_VERSION_H_ #define NETLINK_VERSION_H_ /* Compile Time Versioning Information */ #define LIBNL_STRING "libnl 3.2.29" #define LIBNL_VERSION "3.2.29" #define LIBNL_VER_MAJ 3 #define LIBNL_VER_MIN 2 #define LIBNL_VER_MIC 29 #define LIBNL_VER(maj,min) ((maj) << 8 | (min)) #define LIBNL_VER_NUM LIBNL_VER(LIBNL_VER_MAJ, LIBNL_VER_MIN) #define LIBNL_CURRENT 224 #define LIBNL_REVISION 0 #define LIBNL_AGE 24 /* Run-time version information */ extern const int nl_ver_num; extern const int nl_ver_maj; extern const int nl_ver_min; extern const int nl_ver_mic; #endif libnl-3.2.29/include/netlink/hashtable.h0000644000175000017500000000251013023014600015006 00000000000000/* * netlink/hashtable.h Netlink hashtable Utilities * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Cumulus Networks, Inc */ #ifndef NETLINK_HASHTABLE_H_ #define NETLINK_HASHTABLE_H_ #include #include #ifdef __cplusplus extern "C" { #endif typedef struct nl_hash_node { uint32_t key; uint32_t key_size; struct nl_object * obj; struct nl_hash_node * next; } nl_hash_node_t; typedef struct nl_hash_table { int size; nl_hash_node_t ** nodes; } nl_hash_table_t; /* Default hash table size */ #define NL_MAX_HASH_ENTRIES 1024 /* Access Functions */ extern nl_hash_table_t * nl_hash_table_alloc(int size); extern void nl_hash_table_free(nl_hash_table_t *ht); extern int nl_hash_table_add(nl_hash_table_t *ht, struct nl_object *obj); extern int nl_hash_table_del(nl_hash_table_t *ht, struct nl_object *obj); extern struct nl_object * nl_hash_table_lookup(nl_hash_table_t *ht, struct nl_object *obj); extern uint32_t nl_hash(void *k, size_t length, uint32_t initval); #ifdef __cplusplus } #endif #endif /* NETLINK_HASHTABLE_H_ */ libnl-3.2.29/include/netlink/hash.h0000644000175000017500000000367413023014600014012 00000000000000/* * This file was taken from http://ccodearchive.net/info/hash.html * Changes to the original file include cleanups and removal of unwanted code * and also code that depended on build_asert */ #ifndef CCAN_HASH_H #define CCAN_HASH_H #include #include #include /* Stolen mostly from: lookup3.c, by Bob Jenkins, May 2006, Public Domain. * * http://burtleburtle.net/bob/c/lookup3.c */ #ifdef __LITTLE_ENDIAN # define HAVE_LITTLE_ENDIAN 1 #elif __BIG_ENDIAN # define HAVE_BIG_ENDIAN 1 #else #error Unknown endianness. Failure in endian.h #endif /** * hash - fast hash of an array for internal use * @p: the array or pointer to first element * @num: the number of elements to hash * @base: the base number to roll into the hash (usually 0) * * The memory region pointed to by p is combined with the base to form * a 32-bit hash. * * This hash will have different results on different machines, so is * only useful for internal hashes (ie. not hashes sent across the * network or saved to disk). * * It may also change with future versions: it could even detect at runtime * what the fastest hash to use is. * * See also: hash64, hash_stable. * * Example: * #include * #include * #include * #include * * // Simple demonstration: idential strings will have the same hash, but * // two different strings will probably not. * int main(int argc, char *argv[]) * { * uint32_t hash1, hash2; * * if (argc != 3) * err(1, "Usage: %s ", argv[0]); * * hash1 = __nl_hash(argv[1], strlen(argv[1]), 0); * hash2 = __nl_hash(argv[2], strlen(argv[2]), 0); * printf("Hash is %s\n", hash1 == hash2 ? "same" : "different"); * return 0; * } */ #define __nl_hash(p, num, base) nl_hash_any((p), (num)*sizeof(*(p)), (base)) /* Our underlying operations. */ uint32_t nl_hash_any(const void *key, size_t length, uint32_t base); #endif /* HASH_H */ libnl-3.2.29/include/netlink/addr.h0000644000175000017500000000433013023014600013767 00000000000000/* * netlink/addr.h Abstract Address * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_ADDR_H_ #define NETLINK_ADDR_H_ #include #ifdef __cplusplus extern "C" { #endif struct nl_addr; /* Creation */ extern struct nl_addr * nl_addr_alloc(size_t); extern struct nl_addr * nl_addr_alloc_attr(const struct nlattr *, int); extern struct nl_addr * nl_addr_build(int, const void *, size_t); extern int nl_addr_parse(const char *, int, struct nl_addr **); extern struct nl_addr * nl_addr_clone(const struct nl_addr *); /* Usage Management */ extern struct nl_addr * nl_addr_get(struct nl_addr *); extern void nl_addr_put(struct nl_addr *); extern int nl_addr_shared(const struct nl_addr *); extern int nl_addr_cmp(const struct nl_addr *, const struct nl_addr *); extern int nl_addr_cmp_prefix(const struct nl_addr *, const struct nl_addr *); extern int nl_addr_iszero(const struct nl_addr *); extern int nl_addr_valid(const char *, int); extern int nl_addr_guess_family(const struct nl_addr *); extern int nl_addr_fill_sockaddr(const struct nl_addr *, struct sockaddr *, socklen_t *); extern int nl_addr_info(const struct nl_addr *, struct addrinfo **); extern int nl_addr_resolve(const struct nl_addr *, char *, size_t); /* Access Functions */ extern void nl_addr_set_family(struct nl_addr *, int); extern int nl_addr_get_family(const struct nl_addr *); extern int nl_addr_set_binary_addr(struct nl_addr *, const void *, size_t); extern void * nl_addr_get_binary_addr(const struct nl_addr *); extern unsigned int nl_addr_get_len(const struct nl_addr *); extern void nl_addr_set_prefixlen(struct nl_addr *, int); extern unsigned int nl_addr_get_prefixlen(const struct nl_addr *); /* Address Family Translations */ extern char * nl_af2str(int, char *, size_t); extern int nl_str2af(const char *); /* Translations to Strings */ extern char * nl_addr2str(const struct nl_addr *, char *, size_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/idiag/0000755000175000017500000000000013031473756014065 500000000000000libnl-3.2.29/include/netlink/idiag/msg.h0000644000175000017500000001027213023014600014722 00000000000000/* * netlink/idiag/msg.h Inetdiag Netlink Message * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #ifndef NETLINK_IDIAGNL_MSG_H_ #define NETLINK_IDIAGNL_MSG_H_ #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct idiagnl_msg; /* @deprecated: DO NOT USE this variable. */ extern struct nl_object_ops idiagnl_msg_obj_ops; extern struct idiagnl_msg * idiagnl_msg_alloc(void); extern int idiagnl_msg_alloc_cache(struct nl_sock *, int, int, struct nl_cache**); extern void idiagnl_msg_get(struct idiagnl_msg *); extern void idiagnl_msg_put(struct idiagnl_msg *); extern uint8_t idiagnl_msg_get_family(const struct idiagnl_msg *); extern void idiagnl_msg_set_family(struct idiagnl_msg *, uint8_t); extern uint8_t idiagnl_msg_get_state(const struct idiagnl_msg *); extern void idiagnl_msg_set_state(struct idiagnl_msg *, uint8_t); extern uint8_t idiagnl_msg_get_timer(const struct idiagnl_msg *); extern void idiagnl_msg_set_timer(struct idiagnl_msg *, uint8_t); extern uint8_t idiagnl_msg_get_retrans(const struct idiagnl_msg *); extern void idiagnl_msg_set_retrans(struct idiagnl_msg *, uint8_t); extern uint16_t idiagnl_msg_get_sport(struct idiagnl_msg *); extern void idiagnl_msg_set_sport(struct idiagnl_msg *, uint16_t); extern uint16_t idiagnl_msg_get_dport(struct idiagnl_msg *); extern void idiagnl_msg_set_dport(struct idiagnl_msg *, uint16_t); extern struct nl_addr * idiagnl_msg_get_src(const struct idiagnl_msg *); extern int idiagnl_msg_set_src(struct idiagnl_msg *, struct nl_addr *); extern struct nl_addr * idiagnl_msg_get_dst(const struct idiagnl_msg *); extern int idiagnl_msg_set_dst(struct idiagnl_msg *, struct nl_addr *); extern uint32_t idiagnl_msg_get_ifindex(const struct idiagnl_msg *); extern void idiagnl_msg_set_ifindex(struct idiagnl_msg *, uint32_t); extern uint32_t idiagnl_msg_get_expires(const struct idiagnl_msg *); extern void idiagnl_msg_set_expires(struct idiagnl_msg *, uint32_t); extern uint32_t idiagnl_msg_get_rqueue(const struct idiagnl_msg *); extern void idiagnl_msg_set_rqueue(struct idiagnl_msg *, uint32_t); extern uint32_t idiagnl_msg_get_wqueue(const struct idiagnl_msg *); extern void idiagnl_msg_set_wqueue(struct idiagnl_msg *, uint32_t); extern uint32_t idiagnl_msg_get_uid(const struct idiagnl_msg *); extern void idiagnl_msg_set_uid(struct idiagnl_msg *, uint32_t); extern uint32_t idiagnl_msg_get_inode(const struct idiagnl_msg *); extern void idiagnl_msg_set_inode(struct idiagnl_msg *, uint32_t); extern uint8_t idiagnl_msg_get_tos(const struct idiagnl_msg *); extern void idiagnl_msg_set_tos(struct idiagnl_msg *, uint8_t); extern uint8_t idiagnl_msg_get_tclass(const struct idiagnl_msg *); extern void idiagnl_msg_set_tclass(struct idiagnl_msg *, uint8_t); extern uint8_t idiagnl_msg_get_shutdown(const struct idiagnl_msg *); extern void idiagnl_msg_set_shutdown(struct idiagnl_msg *, uint8_t); extern char * idiagnl_msg_get_cong(const struct idiagnl_msg *); extern void idiagnl_msg_set_cong(struct idiagnl_msg *, char *); extern struct idiagnl_meminfo *idiagnl_msg_get_meminfo(const struct idiagnl_msg *); extern void idiagnl_msg_set_meminfo(struct idiagnl_msg *, struct idiagnl_meminfo *); extern struct idiagnl_vegasinfo *idiagnl_msg_get_vegasinfo(const struct idiagnl_msg *); extern void idiagnl_msg_set_vegasinfo(struct idiagnl_msg *, struct idiagnl_vegasinfo *); extern struct tcp_info idiagnl_msg_get_tcpinfo(const struct idiagnl_msg *); extern void idiagnl_msg_set_tcpinfo(struct idiagnl_msg *, struct tcp_info *); extern int idiagnl_msg_parse(struct nlmsghdr *, struct idiagnl_msg **); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* NETLINK_IDIAGNL_MSG_H_ */ libnl-3.2.29/include/netlink/idiag/req.h0000644000175000017500000000404713023014600014726 00000000000000/* * netlink/idiag/req.h Inetdiag Netlink Request * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #ifndef NETLINK_IDIAGNL_REQ_H_ #define NETLINK_IDIAGNL_REQ_H_ #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct idiagnl_req; extern struct nl_object_ops idiagnl_req_obj_ops; extern struct idiagnl_req * idiagnl_req_alloc(void); extern void idiagnl_req_get(struct idiagnl_req *); extern void idiagnl_req_put(struct idiagnl_req *); extern uint8_t idiagnl_req_get_family(const struct idiagnl_req *); extern void idiagnl_req_set_family(struct idiagnl_req *, uint8_t); extern uint8_t idiagnl_req_get_ext(const struct idiagnl_req *); extern void idiagnl_req_set_ext(struct idiagnl_req *, uint8_t); extern uint32_t idiagnl_req_get_ifindex(const struct idiagnl_req *); extern void idiagnl_req_set_ifindex(struct idiagnl_req *, uint32_t); extern uint32_t idiagnl_req_get_states(const struct idiagnl_req *); extern void idiagnl_req_set_states(struct idiagnl_req *, uint32_t); extern uint32_t idiagnl_req_get_dbs(const struct idiagnl_req *); extern void idiagnl_req_set_dbs(struct idiagnl_req *, uint32_t); extern struct nl_addr * idiagnl_req_get_src(const struct idiagnl_req *); extern int idiagnl_req_set_src(struct idiagnl_req *, struct nl_addr *); extern struct nl_addr * idiagnl_req_get_dst(const struct idiagnl_req *); extern int idiagnl_req_set_dst(struct idiagnl_req *, struct nl_addr *); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* NETLINK_IDIAGNL_REQ_H_ */ libnl-3.2.29/include/netlink/idiag/idiagnl.h0000644000175000017500000001143613023014600015546 00000000000000/* * netlink/idiag/idiagnl.h Inetdiag Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #ifndef NETLINK_IDIAGNL_H_ #define NETLINK_IDIAGNL_H_ #include #include #ifdef __cplusplus extern "C" { #endif /************************************************************* * The following part contains DEPRECATED names and defines. * Don't use them. *************************************************************/ /** * Inet Diag message types * * deprecated: use TCPDIAG_GETSOCK, DCCPDIAG_GETSOCK and * INET_DIAG_GETSOCK_MAX from linux/inet_diag.h */ #define IDIAG_TCPDIAG_GETSOCK 18 #define IDIAG_DCCPDIAG_GETSOCK 19 #define IDIAG_GETSOCK_MAX 24 /** * Socket state identifiers * @ingroup idiag * @deprecated: use instead the TCP_* defines from netinet/tcp.h. */ enum { IDIAG_SS_UNKNOWN = 0, IDIAG_SS_ESTABLISHED = 1, /* TCP_ESTABLISHED */ IDIAG_SS_SYN_SENT = 2, /* TCP_SYN_SENT */ IDIAG_SS_SYN_RECV = 3, /* TCP_SYN_RECV */ IDIAG_SS_FIN_WAIT1 = 4, /* TCP_FIN_WAIT1 */ IDIAG_SS_FIN_WAIT2 = 5, /* TCP_FIN_WAIT2 */ IDIAG_SS_TIME_WAIT = 6, /* TCP_TIME_WAIT */ IDIAG_SS_CLOSE = 7, /* TCP_CLOSE */ IDIAG_SS_CLOSE_WAIT = 8, /* TCP_CLOSE_WAIT */ IDIAG_SS_LAST_ACK = 9, /* TCP_LAST_ACK */ IDIAG_SS_LISTEN = 10, /* TCP_LISTEN */ IDIAG_SS_CLOSING = 11, /* TCP_CLOSING */ IDIAG_SS_MAX = 12, }; /** * Macro to represent all socket states. * @ingroup idiag * @deprecated */ #define IDIAG_SS_ALL IDIAGNL_SS_ALL /** * Inet Diag extended attributes * @ingroup idiag * @deprecated These attributes should not be used. They mirror the * INET_DIAG_* extension flags from kernel headers. Use those instead. */ enum { IDIAG_ATTR_NONE = 0, /* INET_DIAG_NONE */ IDIAG_ATTR_MEMINFO = 1, /* INET_DIAG_MEMINFO */ IDIAG_ATTR_INFO = 2, /* INET_DIAG_INFO */ IDIAG_ATTR_VEGASINFO = 3, /* INET_DIAG_VEGASINFO */ IDIAG_ATTR_CONG = 4, /* INET_DIAG_CONG */ IDIAG_ATTR_TOS = 5, /* INET_DIAG_TOS */ IDIAG_ATTR_TCLASS = 6, /* INET_DIAG_TCLASS */ IDIAG_ATTR_SKMEMINFO = 7, /* INET_DIAG_SKMEMINFO */ IDIAG_ATTR_SHUTDOWN = 8, /* INET_DIAG_SHUTDOWN */ /* IDIAG_ATTR_MAX was wrong, because it did not correspond to * INET_DIAG_MAX. Anyway, freeze it to the previous value. */ IDIAG_ATTR_MAX = 9, IDIAG_ATTR_ALL = (1< */ #ifndef NETLINK_IDIAGNL_VEGASINFO_H_ #define NETLINK_IDIAGNL_VEGASINFO_H_ #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern struct nl_object_ops idiagnl_vegasinfo_obj_ops; extern struct idiagnl_vegasinfo * idiagnl_vegasinfo_alloc(void); extern void idiagnl_vegasinfo_get(struct idiagnl_vegasinfo *); extern void idiagnl_vegasinfo_put(struct idiagnl_vegasinfo *); extern uint32_t idiagnl_vegasinfo_get_enabled(const struct idiagnl_vegasinfo *); extern uint32_t idiagnl_vegasinfo_get_rttcnt(const struct idiagnl_vegasinfo *); extern uint32_t idiagnl_vegasinfo_get_rtt(const struct idiagnl_vegasinfo *); extern uint32_t idiagnl_vegasinfo_get_minrtt(const struct idiagnl_vegasinfo *); extern void idiagnl_vegasinfo_set_enabled(struct idiagnl_vegasinfo *, uint32_t); extern void idiagnl_vegasinfo_set_rttcnt(struct idiagnl_vegasinfo *, uint32_t); extern void idiagnl_vegasinfo_set_rtt(struct idiagnl_vegasinfo *, uint32_t); extern void idiagnl_vegasinfo_set_minrtt(struct idiagnl_vegasinfo *, uint32_t); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* NETLINK_IDIAGNL_VEGASINFO_H_ */ libnl-3.2.29/include/netlink/idiag/meminfo.h0000644000175000017500000000264113023014600015567 00000000000000/* * netlink/idiag/meminfo.h Inetdiag Netlink Memory Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #ifndef NETLINK_IDIAGNL_MEMINFO_H_ #define NETLINK_IDIAGNL_MEMINFO_H_ #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern struct nl_object_ops idiagnl_meminfo_obj_ops; extern struct idiagnl_meminfo *idiagnl_meminfo_alloc(void); extern void idiagnl_meminfo_get(struct idiagnl_meminfo *); extern void idiagnl_meminfo_put(struct idiagnl_meminfo *); extern uint32_t idiagnl_meminfo_get_rmem(const struct idiagnl_meminfo *); extern uint32_t idiagnl_meminfo_get_wmem(const struct idiagnl_meminfo *); extern uint32_t idiagnl_meminfo_get_fmem(const struct idiagnl_meminfo *); extern uint32_t idiagnl_meminfo_get_tmem(const struct idiagnl_meminfo *); extern void idiagnl_meminfo_set_rmem(struct idiagnl_meminfo *, uint32_t); extern void idiagnl_meminfo_set_wmem(struct idiagnl_meminfo *, uint32_t); extern void idiagnl_meminfo_set_fmem(struct idiagnl_meminfo *, uint32_t); extern void idiagnl_meminfo_set_tmem(struct idiagnl_meminfo *, uint32_t); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* NETLINK_IDIAGNL_MEMINFO_H_ */ libnl-3.2.29/include/netlink/genl/0000755000175000017500000000000013031473756013735 500000000000000libnl-3.2.29/include/netlink/genl/family.h0000644000175000017500000000271613023014600015271 00000000000000/* * netlink/genl/family.h Generic Netlink Family * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_GENL_FAMILY_H_ #define NETLINK_GENL_FAMILY_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct genl_family; extern struct genl_family * genl_family_alloc(void); extern void genl_family_put(struct genl_family *); extern unsigned int genl_family_get_id(struct genl_family *); extern void genl_family_set_id(struct genl_family *, unsigned int); extern char * genl_family_get_name(struct genl_family *); extern void genl_family_set_name(struct genl_family *, const char *); extern uint8_t genl_family_get_version(struct genl_family *); extern void genl_family_set_version(struct genl_family *, uint8_t); extern uint32_t genl_family_get_hdrsize(struct genl_family *); extern void genl_family_set_hdrsize(struct genl_family *, uint32_t); extern uint32_t genl_family_get_maxattr(struct genl_family *); extern void genl_family_set_maxattr(struct genl_family *, uint32_t); extern int genl_family_add_op(struct genl_family *, int, int); extern int genl_family_add_grp(struct genl_family *, uint32_t , const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/genl/genl.h0000644000175000017500000000305013023014600014725 00000000000000/* * netlink/genl/genl.h Generic Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_GENL_H_ #define NETLINK_GENL_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern int genl_connect(struct nl_sock *); extern int genl_send_simple(struct nl_sock *, int, int, int, int); extern void * genlmsg_put(struct nl_msg *, uint32_t, uint32_t, int, int, int, uint8_t, uint8_t); extern int genlmsg_valid_hdr(struct nlmsghdr *, int); extern int genlmsg_validate(struct nlmsghdr *, int, int, struct nla_policy *); extern int genlmsg_parse(struct nlmsghdr *, int, struct nlattr **, int, struct nla_policy *); extern struct genlmsghdr * genlmsg_hdr(struct nlmsghdr *); extern void * genlmsg_data(const struct genlmsghdr *); extern void * genlmsg_user_hdr(const struct genlmsghdr *); extern void * genlmsg_user_data(const struct genlmsghdr *, const int); extern int genlmsg_user_datalen(const struct genlmsghdr *, const int); extern int genlmsg_len(const struct genlmsghdr *); extern struct nlattr * genlmsg_attrdata(const struct genlmsghdr *, int); extern int genlmsg_attrlen(const struct genlmsghdr *, int); extern char * genl_op2name(int, int, char *, size_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/genl/ctrl.h0000644000175000017500000000176713023014600014761 00000000000000/* * netlink/genl/ctrl.h Generic Netlink Controller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_GENL_CTRL_H_ #define NETLINK_GENL_CTRL_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif struct genl_family; extern int genl_ctrl_alloc_cache(struct nl_sock *, struct nl_cache **); extern struct genl_family * genl_ctrl_search(struct nl_cache *, int); extern struct genl_family * genl_ctrl_search_by_name(struct nl_cache *, const char *); extern int genl_ctrl_resolve(struct nl_sock *, const char *); extern int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family, const char *grp); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/genl/mngt.h0000644000175000017500000000774613023014600014765 00000000000000/* * netlink/genl/mngt.h Generic Netlink Management * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_GENL_MNGT_H_ #define NETLINK_GENL_MNGT_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif struct nl_cache_ops; /** * @ingroup genl_mngt * @struct genl_info netlink/genl/mngt.h * * Informative structure passed on to message parser callbacks * * This structure is passed on to all message parser callbacks and contains * information about the sender of the message as well as pointers to all * relevant sections of the parsed message. * * @see genl_cmd::c_msg_parser */ struct genl_info { /** Socket address of sender */ struct sockaddr_nl * who; /** Pointer to Netlink message header */ struct nlmsghdr * nlh; /** Pointer to Generic Netlink message header */ struct genlmsghdr * genlhdr; /** Pointer to user header */ void * userhdr; /** Pointer to array of parsed attributes */ struct nlattr ** attrs; }; /** * @ingroup genl_mngt * @struct genl_cmd netlink/genl/mngt.h * * Definition of a Generic Netlink command. * * This structure is used to define the list of available commands on the * receiving side. * * @par Example: * @code * static struct genl_cmd foo_cmds[] = { * { * .c_id = FOO_CMD_NEW, * .c_name = "NEWFOO" , * .c_maxattr = FOO_ATTR_MAX, * .c_attr_policy = foo_policy, * .c_msg_parser = foo_msg_parser, * }, * { * .c_id = FOO_CMD_DEL, * .c_name = "DELFOO" , * }, * }; * * static struct genl_ops my_genl_ops = { * [...] * .o_cmds = foo_cmds, * .o_ncmds = ARRAY_SIZE(foo_cmds), * }; * @endcode */ struct genl_cmd { /** Numeric command identifier (required) */ int c_id; /** Human readable name (required) */ char * c_name; /** Maximum attribute identifier that the command is prepared to handle. */ int c_maxattr; /** Called whenever a message for this command is received */ int (*c_msg_parser)(struct nl_cache_ops *, struct genl_cmd *, struct genl_info *, void *); /** Attribute validation policy, enforced before the callback is called */ struct nla_policy * c_attr_policy; }; /** * @ingroup genl_mngt * @struct genl_ops netlink/genl/mngt.h * * Definition of a Generic Netlink family * * @par Example: * @code * static struct genl_cmd foo_cmds[] = { * [...] * }; * * static struct genl_ops my_genl_ops = { * .o_name = "foo", * .o_hdrsize = sizeof(struct my_hdr), * .o_cmds = foo_cmds, * .o_ncmds = ARRAY_SIZE(foo_cmds), * }; * * if ((err = genl_register_family(&my_genl_ops)) < 0) * // ERROR * @endcode * * @see genl_cmd */ struct genl_ops { /** Length of user header */ unsigned int o_hdrsize; /** Numeric identifier, automatically filled in by genl_ops_resolve() */ int o_id; /** Human readable name, used by genl_ops_resolve() to resolve numeric id */ char * o_name; /** * If registered via genl_register(), will point to the related * cache operations. */ struct nl_cache_ops * o_cache_ops; /** Optional array defining the available Generic Netlink commands */ struct genl_cmd * o_cmds; /** Number of elements in \c o_cmds array */ int o_ncmds; /** * @private * Used internally to link together all registered operations. */ struct nl_list_head o_list; }; extern int genl_register_family(struct genl_ops *); extern int genl_unregister_family(struct genl_ops *); extern int genl_handle_msg(struct nl_msg *, void *); extern int genl_register(struct nl_cache_ops *); extern void genl_unregister(struct nl_cache_ops *); extern int genl_ops_resolve(struct nl_sock *, struct genl_ops *); extern int genl_mngt_resolve(struct nl_sock *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/xfrm/0000755000175000017500000000000013031473756013764 500000000000000libnl-3.2.29/include/netlink/xfrm/sa.h0000644000175000017500000002367613023014600014452 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef NETLINK_XFRM_SA_H_ #define NETLINK_XFRM_SA_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct xfrmnl_sa; extern struct xfrmnl_sa* xfrmnl_sa_alloc(void); extern void xfrmnl_sa_put(struct xfrmnl_sa *); extern int xfrmnl_sa_alloc_cache(struct nl_sock *, struct nl_cache **); extern struct xfrmnl_sa* xfrmnl_sa_get(struct nl_cache*, struct nl_addr*, unsigned int, unsigned int); extern int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result); extern int xfrmnl_sa_build_get_request(struct nl_addr*, unsigned int, unsigned int, unsigned int, unsigned int, struct nl_msg **); extern int xfrmnl_sa_get_kernel(struct nl_sock*, struct nl_addr*, unsigned int, unsigned int, unsigned int, unsigned int, struct xfrmnl_sa**); extern int xfrmnl_sa_build_add_request(struct xfrmnl_sa*, int, struct nl_msg **); extern int xfrmnl_sa_add(struct nl_sock*, struct xfrmnl_sa*, int); extern int xfrmnl_sa_build_update_request(struct xfrmnl_sa*, int, struct nl_msg **); extern int xfrmnl_sa_update(struct nl_sock*, struct xfrmnl_sa*, int); extern int xfrmnl_sa_build_delete_request(struct xfrmnl_sa*, int, struct nl_msg **); extern int xfrmnl_sa_delete(struct nl_sock*, struct xfrmnl_sa*, int); extern struct xfrmnl_sel* xfrmnl_sa_get_sel (struct xfrmnl_sa*); extern int xfrmnl_sa_set_sel (struct xfrmnl_sa*, struct xfrmnl_sel*); extern struct nl_addr* xfrmnl_sa_get_daddr (struct xfrmnl_sa*); extern int xfrmnl_sa_set_daddr (struct xfrmnl_sa*, struct nl_addr*); extern int xfrmnl_sa_get_spi (struct xfrmnl_sa*); extern int xfrmnl_sa_set_spi (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_proto (struct xfrmnl_sa*); extern int xfrmnl_sa_set_proto (struct xfrmnl_sa*, unsigned int); extern struct nl_addr* xfrmnl_sa_get_saddr (struct xfrmnl_sa*); extern int xfrmnl_sa_set_saddr (struct xfrmnl_sa*, struct nl_addr*); extern struct xfrmnl_ltime_cfg* xfrmnl_sa_get_lifetime_cfg (struct xfrmnl_sa*); extern int xfrmnl_sa_set_lifetime_cfg (struct xfrmnl_sa*, struct xfrmnl_ltime_cfg*); extern int xfrmnl_sa_get_curlifetime (struct xfrmnl_sa*, unsigned long long int*, unsigned long long int*, unsigned long long int*, unsigned long long int*); extern int xfrmnl_sa_get_stats (struct xfrmnl_sa*, unsigned long long int*, unsigned long long int*, unsigned long long int*); extern int xfrmnl_sa_get_seq (struct xfrmnl_sa*); extern int xfrmnl_sa_get_reqid (struct xfrmnl_sa*); extern int xfrmnl_sa_set_reqid (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_family (struct xfrmnl_sa*); extern int xfrmnl_sa_set_family (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_mode (struct xfrmnl_sa*); extern int xfrmnl_sa_set_mode (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_replay_window (struct xfrmnl_sa*); extern int xfrmnl_sa_set_replay_window (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_flags (struct xfrmnl_sa*); extern int xfrmnl_sa_set_flags (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_aead_params (struct xfrmnl_sa*, char*, unsigned int*, unsigned int*, char*); extern int xfrmnl_sa_set_aead_params (struct xfrmnl_sa*, const char*, unsigned int, unsigned int, const char*); extern int xfrmnl_sa_get_auth_params (struct xfrmnl_sa*, char*, unsigned int*, unsigned int*, char*); extern int xfrmnl_sa_set_auth_params (struct xfrmnl_sa*, const char*, unsigned int, unsigned int, const char*); extern int xfrmnl_sa_get_crypto_params (struct xfrmnl_sa*, char*, unsigned int*, char*); extern int xfrmnl_sa_set_crypto_params (struct xfrmnl_sa*, const char*, unsigned int, const char*); extern int xfrmnl_sa_get_comp_params (struct xfrmnl_sa*, char*, unsigned int*, char*); extern int xfrmnl_sa_set_comp_params (struct xfrmnl_sa*, const char*, unsigned int, const char*); extern int xfrmnl_sa_get_encap_tmpl (struct xfrmnl_sa*, unsigned int*, unsigned int*, unsigned int*, struct nl_addr**); extern int xfrmnl_sa_set_encap_tmpl (struct xfrmnl_sa*, unsigned int, unsigned int, unsigned int, struct nl_addr*); extern int xfrmnl_sa_get_tfcpad (struct xfrmnl_sa*); extern int xfrmnl_sa_set_tfcpad (struct xfrmnl_sa*, unsigned int); extern struct nl_addr* xfrmnl_sa_get_coaddr (struct xfrmnl_sa*); extern int xfrmnl_sa_set_coaddr (struct xfrmnl_sa*, struct nl_addr*); extern int xfrmnl_sa_get_mark (struct xfrmnl_sa*, unsigned int*, unsigned int*); extern int xfrmnl_sa_set_mark (struct xfrmnl_sa*, unsigned int, unsigned int); extern int xfrmnl_sa_get_sec_ctx (struct xfrmnl_sa*, unsigned int, unsigned int, unsigned int, unsigned int, char*); extern int xfrmnl_sa_set_sec_ctx (struct xfrmnl_sa*, unsigned int, unsigned int, unsigned int, unsigned int, const char*); extern int xfrmnl_sa_get_replay_maxage (struct xfrmnl_sa*); extern int xfrmnl_sa_set_replay_maxage (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_replay_maxdiff (struct xfrmnl_sa*); extern int xfrmnl_sa_set_replay_maxdiff (struct xfrmnl_sa*, unsigned int); extern int xfrmnl_sa_get_replay_state (struct xfrmnl_sa*, unsigned int*, unsigned int*, unsigned int*); extern int xfrmnl_sa_set_replay_state (struct xfrmnl_sa*, unsigned int, unsigned int, unsigned int); extern int xfrmnl_sa_get_replay_state_esn (struct xfrmnl_sa*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*); extern int xfrmnl_sa_set_replay_state_esn (struct xfrmnl_sa*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int*); extern int xfrmnl_sa_is_expiry_reached (struct xfrmnl_sa*); extern int xfrmnl_sa_is_hardexpiry_reached (struct xfrmnl_sa*); extern char* xfrmnl_sa_flags2str(int, char *, size_t); extern int xfrmnl_sa_str2flag(const char *); extern char* xfrmnl_sa_mode2str(int, char *, size_t); extern int xfrmnl_sa_str2mode(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/xfrm/template.h0000644000175000017500000001135713023014600015653 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef NETLINK_XFRM_TEMPL_H_ #define NETLINK_XFRM_TEMPL_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct xfrmnl_user_tmpl; /* Creation */ extern struct xfrmnl_user_tmpl* xfrmnl_user_tmpl_alloc(void); extern struct xfrmnl_user_tmpl* xfrmnl_user_tmpl_clone(struct xfrmnl_user_tmpl*); extern void xfrmnl_user_tmpl_free(struct xfrmnl_user_tmpl* utmpl); /* Utility functions */ extern int xfrmnl_user_tmpl_cmp(struct xfrmnl_user_tmpl*, struct xfrmnl_user_tmpl*); extern void xfrmnl_user_tmpl_dump(struct xfrmnl_user_tmpl*, struct nl_dump_params*); /* Access Functions */ extern struct nl_addr* xfrmnl_user_tmpl_get_daddr (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_daddr (struct xfrmnl_user_tmpl*, struct nl_addr*); extern int xfrmnl_user_tmpl_get_spi (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_spi (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_proto (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_proto (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_family (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_family (struct xfrmnl_user_tmpl*, unsigned int); extern struct nl_addr* xfrmnl_user_tmpl_get_saddr (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_saddr (struct xfrmnl_user_tmpl*, struct nl_addr*); extern int xfrmnl_user_tmpl_get_reqid (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_reqid (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_mode (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_mode (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_share (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_share (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_optional (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_optional (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_aalgos (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_aalgos (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_ealgos (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_ealgos (struct xfrmnl_user_tmpl*, unsigned int); extern int xfrmnl_user_tmpl_get_calgos (struct xfrmnl_user_tmpl*); extern int xfrmnl_user_tmpl_set_calgos (struct xfrmnl_user_tmpl*, unsigned int); extern char* xfrmnl_user_tmpl_mode2str(int, char *, size_t); extern int xfrmnl_user_tmpl_str2mode(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/xfrm/selector.h0000644000175000017500000001063313023014600015654 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef NETLINK_XFRM_SEL_H_ #define NETLINK_XFRM_SEL_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct xfrmnl_sel; /* Creation */ extern struct xfrmnl_sel* xfrmnl_sel_alloc(void); extern struct xfrmnl_sel* xfrmnl_sel_clone(struct xfrmnl_sel*); /* Usage Management */ extern struct xfrmnl_sel* xfrmnl_sel_get(struct xfrmnl_sel*); extern void xfrmnl_sel_put(struct xfrmnl_sel*); extern int xfrmnl_sel_shared(struct xfrmnl_sel*); extern int xfrmnl_sel_cmp(struct xfrmnl_sel*, struct xfrmnl_sel*); extern void xfrmnl_sel_dump(struct xfrmnl_sel*, struct nl_dump_params *); /* Access Functions */ extern struct nl_addr* xfrmnl_sel_get_daddr (struct xfrmnl_sel*); extern int xfrmnl_sel_set_daddr (struct xfrmnl_sel*, struct nl_addr*); extern struct nl_addr* xfrmnl_sel_get_saddr (struct xfrmnl_sel*); extern int xfrmnl_sel_set_saddr (struct xfrmnl_sel*, struct nl_addr*); extern int xfrmnl_sel_get_dport (struct xfrmnl_sel*); extern int xfrmnl_sel_set_dport (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_dportmask (struct xfrmnl_sel*); extern int xfrmnl_sel_set_dportmask (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_sport (struct xfrmnl_sel*); extern int xfrmnl_sel_set_sport (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_sportmask (struct xfrmnl_sel*); extern int xfrmnl_sel_set_sportmask (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_family (struct xfrmnl_sel*); extern int xfrmnl_sel_set_family (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_prefixlen_d (struct xfrmnl_sel*); extern int xfrmnl_sel_set_prefixlen_d (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_prefixlen_s (struct xfrmnl_sel*); extern int xfrmnl_sel_set_prefixlen_s (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_proto (struct xfrmnl_sel*); extern int xfrmnl_sel_set_proto (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_ifindex (struct xfrmnl_sel*); extern int xfrmnl_sel_set_ifindex (struct xfrmnl_sel*, unsigned int); extern int xfrmnl_sel_get_userid (struct xfrmnl_sel*); extern int xfrmnl_sel_set_userid (struct xfrmnl_sel*, unsigned int); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/xfrm/lifetime.h0000644000175000017500000001012513023014600015626 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef NETLINK_XFRM_LTIME_H_ #define NETLINK_XFRM_LTIME_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct xfrmnl_ltime_cfg; /* Creation */ extern struct xfrmnl_ltime_cfg* xfrmnl_ltime_cfg_alloc(void); extern struct xfrmnl_ltime_cfg* xfrmnl_ltime_cfg_clone(struct xfrmnl_ltime_cfg*); /* Usage Management */ extern struct xfrmnl_ltime_cfg* xfrmnl_ltime_cfg_get(struct xfrmnl_ltime_cfg*); extern void xfrmnl_ltime_cfg_put(struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_shared(struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_cmp(struct xfrmnl_ltime_cfg*, struct xfrmnl_ltime_cfg*); /* Access Functions */ extern unsigned long long xfrmnl_ltime_cfg_get_soft_bytelimit (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_soft_bytelimit (struct xfrmnl_ltime_cfg*, unsigned long long); extern unsigned long long xfrmnl_ltime_cfg_get_hard_bytelimit (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_hard_bytelimit (struct xfrmnl_ltime_cfg*, unsigned long long); extern unsigned long long xfrmnl_ltime_cfg_get_soft_packetlimit (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_soft_packetlimit (struct xfrmnl_ltime_cfg*, unsigned long long); extern unsigned long long xfrmnl_ltime_cfg_get_hard_packetlimit (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_hard_packetlimit (struct xfrmnl_ltime_cfg*, unsigned long long); extern unsigned long long xfrmnl_ltime_cfg_get_soft_addexpires (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_soft_addexpires (struct xfrmnl_ltime_cfg*, unsigned long long); extern unsigned long long xfrmnl_ltime_cfg_get_hard_addexpires (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_hard_addexpires (struct xfrmnl_ltime_cfg*, unsigned long long); extern unsigned long long xfrmnl_ltime_cfg_get_soft_useexpires (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_soft_useexpires (struct xfrmnl_ltime_cfg*, unsigned long long); extern unsigned long long xfrmnl_ltime_cfg_get_hard_useexpires (struct xfrmnl_ltime_cfg*); extern int xfrmnl_ltime_cfg_set_hard_useexpires (struct xfrmnl_ltime_cfg*, unsigned long long); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/xfrm/ae.h0000644000175000017500000001252113023014600014417 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef NETLINK_XFRM_AE_H_ #define NETLINK_XFRM_AE_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct xfrmnl_ae; extern struct xfrmnl_ae*xfrmnl_ae_alloc(void); extern void xfrmnl_ae_put(struct xfrmnl_ae *); extern int xfrmnl_ae_get_kernel(struct nl_sock*, struct nl_addr*, unsigned int, unsigned int, unsigned int, unsigned int, struct xfrmnl_ae**); extern int xfrmnl_ae_set(struct nl_sock*, struct xfrmnl_ae*, int); extern int xfrmnl_ae_parse(struct nlmsghdr*, struct xfrmnl_ae **); extern int xfrmnl_ae_build_get_request(struct nl_addr*, unsigned int, unsigned int, unsigned int, unsigned int, struct nl_msg **); extern struct nl_addr* xfrmnl_ae_get_daddr (struct xfrmnl_ae*); extern int xfrmnl_ae_set_daddr (struct xfrmnl_ae*, struct nl_addr*); extern int xfrmnl_ae_get_spi (struct xfrmnl_ae*); extern int xfrmnl_ae_set_spi (struct xfrmnl_ae*, unsigned int); extern int xfrmnl_ae_get_family (struct xfrmnl_ae*); extern int xfrmnl_ae_set_family (struct xfrmnl_ae*, unsigned int); extern int xfrmnl_ae_get_proto (struct xfrmnl_ae*); extern int xfrmnl_ae_set_proto (struct xfrmnl_ae*, unsigned int); extern struct nl_addr* xfrmnl_ae_get_saddr (struct xfrmnl_ae*); extern int xfrmnl_ae_set_saddr (struct xfrmnl_ae*, struct nl_addr*); extern int xfrmnl_ae_get_flags (struct xfrmnl_ae*); extern int xfrmnl_ae_set_flags (struct xfrmnl_ae*, unsigned int); extern int xfrmnl_ae_get_reqid (struct xfrmnl_ae*); extern int xfrmnl_ae_set_reqid (struct xfrmnl_ae*, unsigned int); extern int xfrmnl_ae_get_mark (struct xfrmnl_ae*, unsigned int*, unsigned int*); extern int xfrmnl_ae_set_mark (struct xfrmnl_ae*, unsigned int, unsigned int); extern int xfrmnl_ae_get_curlifetime (struct xfrmnl_ae*, unsigned long long int*, unsigned long long int*, unsigned long long int*, unsigned long long int*); extern int xfrmnl_ae_set_curlifetime (struct xfrmnl_ae*, unsigned long long int, unsigned long long int, unsigned long long int, unsigned long long int); extern int xfrmnl_ae_get_replay_maxage (struct xfrmnl_ae*); extern int xfrmnl_ae_set_replay_maxage (struct xfrmnl_ae*, unsigned int); extern int xfrmnl_ae_get_replay_maxdiff (struct xfrmnl_ae*); extern int xfrmnl_ae_set_replay_maxdiff (struct xfrmnl_ae*, unsigned int); extern int xfrmnl_ae_get_replay_state (struct xfrmnl_ae*, unsigned int*, unsigned int*, unsigned int*); extern int xfrmnl_ae_set_replay_state (struct xfrmnl_ae*, unsigned int, unsigned int, unsigned int); extern int xfrmnl_ae_get_replay_state_esn (struct xfrmnl_ae*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*); extern int xfrmnl_ae_set_replay_state_esn (struct xfrmnl_ae*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int*); extern char* xfrmnl_ae_flags2str(int, char *, size_t); extern int xfrmnl_ae_str2flag(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/xfrm/sp.h0000644000175000017500000001615113023014600014457 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef NETLINK_XFRM_SP_H_ #define NETLINK_XFRM_SP_H_ #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct xfrmnl_sp; extern struct xfrmnl_sp* xfrmnl_sp_alloc(void); extern void xfrmnl_sp_put(struct xfrmnl_sp *); extern int xfrmnl_sp_alloc_cache(struct nl_sock *, struct nl_cache **); extern struct xfrmnl_sp* xfrmnl_sp_get(struct nl_cache*, unsigned int, unsigned int); extern int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result); extern int xfrmnl_sp_build_get_request(unsigned int, unsigned int, unsigned int, unsigned int, struct nl_msg **); extern int xfrmnl_sp_get_kernel(struct nl_sock*, unsigned int, unsigned int, unsigned int, unsigned int, struct xfrmnl_sp**); extern int xfrmnl_sp_add(struct nl_sock*, struct xfrmnl_sp*, int); extern int xfrmnl_sp_build_add_request(struct xfrmnl_sp*, int, struct nl_msg **); extern int xfrmnl_sp_update(struct nl_sock*, struct xfrmnl_sp*, int); extern int xfrmnl_sp_build_update_request(struct xfrmnl_sp*, int, struct nl_msg **); extern int xfrmnl_sp_delete(struct nl_sock*, struct xfrmnl_sp*, int); extern int xfrmnl_sp_build_delete_request(struct xfrmnl_sp*, int, struct nl_msg **); extern struct xfrmnl_sel* xfrmnl_sp_get_sel (struct xfrmnl_sp*); extern int xfrmnl_sp_set_sel (struct xfrmnl_sp*, struct xfrmnl_sel*); extern struct xfrmnl_ltime_cfg* xfrmnl_sp_get_lifetime_cfg (struct xfrmnl_sp*); extern int xfrmnl_sp_set_lifetime_cfg (struct xfrmnl_sp*, struct xfrmnl_ltime_cfg*); extern int xfrmnl_sp_get_curlifetime (struct xfrmnl_sp*, unsigned long long int*, unsigned long long int*, unsigned long long int*, unsigned long long int*); extern int xfrmnl_sp_get_priority (struct xfrmnl_sp*); extern int xfrmnl_sp_set_priority (struct xfrmnl_sp*, unsigned int); extern int xfrmnl_sp_get_index (struct xfrmnl_sp*); extern int xfrmnl_sp_set_index (struct xfrmnl_sp*, unsigned int); extern int xfrmnl_sp_get_dir (struct xfrmnl_sp*); extern int xfrmnl_sp_set_dir (struct xfrmnl_sp*, unsigned int); extern int xfrmnl_sp_get_action (struct xfrmnl_sp*); extern int xfrmnl_sp_set_action (struct xfrmnl_sp*, unsigned int); extern int xfrmnl_sp_get_flags (struct xfrmnl_sp*); extern int xfrmnl_sp_set_flags (struct xfrmnl_sp*, unsigned int); extern int xfrmnl_sp_get_share (struct xfrmnl_sp*); extern int xfrmnl_sp_set_share (struct xfrmnl_sp*, unsigned int); extern int xfrmnl_sp_get_sec_ctx (struct xfrmnl_sp*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, char*); extern int xfrmnl_sp_set_sec_ctx (struct xfrmnl_sp*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, char*); extern int xfrmnl_sp_get_userpolicy_type (struct xfrmnl_sp*); extern int xfrmnl_sp_set_userpolicy_type (struct xfrmnl_sp*, unsigned int); extern void xfrmnl_sp_add_usertemplate(struct xfrmnl_sp*, struct xfrmnl_user_tmpl*); extern void xfrmnl_sp_remove_usertemplate(struct xfrmnl_sp*, struct xfrmnl_user_tmpl*); extern struct nl_list_head* xfrmnl_sp_get_usertemplates(struct xfrmnl_sp*); extern int xfrmnl_sp_get_nusertemplates(struct xfrmnl_sp*); extern void xfrmnl_sp_foreach_usertemplate(struct xfrmnl_sp*, void (*cb)(struct xfrmnl_user_tmpl*, void *), void *arg); extern struct xfrmnl_user_tmpl* xfrmnl_sp_usertemplate_n(struct xfrmnl_sp*, int); extern int xfrmnl_sp_get_mark (struct xfrmnl_sp*, unsigned int*, unsigned int*); extern int xfrmnl_sp_set_mark (struct xfrmnl_sp*, unsigned int, unsigned int); extern char* xfrmnl_sp_action2str(int, char *, size_t); extern int xfrmnl_sp_str2action(const char *); extern char* xfrmnl_sp_flags2str(int, char *, size_t); extern int xfrmnl_sp_str2flag(const char *); extern char* xfrmnl_sp_type2str(int, char *, size_t); extern int xfrmnl_sp_str2type(const char *); extern char* xfrmnl_sp_dir2str(int, char *, size_t); extern int xfrmnl_sp_str2dir(const char *); extern char* xfrmnl_sp_share2str(int, char *, size_t); extern int xfrmnl_sp_str2share(const char *); extern int xfrmnl_sp_index2dir (unsigned int); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/netlink-kernel.h0000644000175000017500000001235313023014600016003 00000000000000#ifndef __NETLINK_KERNEL_H_ #define __NETLINK_KERNEL_H_ #if 0 /* * FIXME: Goal is to preseve the documentation but make it simple * to keep linux/netlink.h in sync. Maybe use named documentation * sections. */ /** * Netlink socket address * @ingroup nl */ struct sockaddr_nl { /** socket family (AF_NETLINK) */ sa_family_t nl_family; /** Padding (unused) */ unsigned short nl_pad; /** Unique process ID */ uint32_t nl_pid; /** Multicast group subscriptions */ uint32_t nl_groups; }; /** * @addtogroup msg * @{ */ /** * Netlink message header */ struct nlmsghdr { /** Length of message including header and padding. */ uint32_t nlmsg_len; /** Message type (content type) */ uint16_t nlmsg_type; /** Message flags */ uint16_t nlmsg_flags; /** Sequence number of message \see core_sk_seq_num. */ uint32_t nlmsg_seq; /** Netlink port */ uint32_t nlmsg_pid; }; /** * @name Standard message flags * @{ */ /** * Must be set on all request messages (typically from user space to * kernel space). */ #define NLM_F_REQUEST 1 /** * Indicates the message is part of a multipart message terminated * by NLMSG_DONE. */ #define NLM_F_MULTI 2 /** * Request for an acknowledgment on success. */ #define NLM_F_ACK 4 /** * Echo this request */ #define NLM_F_ECHO 8 /** @} */ /** * @name Additional message flags for GET requests * @{ */ /** * Return the complete table instead of a single entry. */ #define NLM_F_ROOT 0x100 /** * Return all entries matching criteria passed in message content. */ #define NLM_F_MATCH 0x200 /** * Return an atomic snapshot of the table being referenced. This * may require special privileges because it has the potential to * interrupt service in the FE for a longer time. */ #define NLM_F_ATOMIC 0x400 /** * Dump all entries */ #define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) /** @} */ /** * @name Additional messsage flags for NEW requests * @{ */ /** * Replace existing matching config object with this request. */ #define NLM_F_REPLACE 0x100 /** * Don't replace the config object if it already exists. */ #define NLM_F_EXCL 0x200 /** * Create config object if it doesn't already exist. */ #define NLM_F_CREATE 0x400 /** * Add to the end of the object list. */ #define NLM_F_APPEND 0x800 /** @} */ /** * @name Standard Message types * @{ */ /** * No operation, message must be ignored */ #define NLMSG_NOOP 0x1 /** * The message signals an error and the payload contains a nlmsgerr * structure. This can be looked at as a NACK and typically it is * from FEC to CPC. */ #define NLMSG_ERROR 0x2 /** * Message terminates a multipart message. */ #define NLMSG_DONE 0x3 /** * The message signals that data got lost */ #define NLMSG_OVERRUN 0x4 /** * Lower limit of reserved message types */ #define NLMSG_MIN_TYPE 0x10 /** @} */ /** * Netlink error message header */ struct nlmsgerr { /** Error code (errno number) */ int error; /** Original netlink message causing the error */ struct nlmsghdr msg; }; struct nl_pktinfo { __u32 group; }; /** * Netlink alignment constant, all boundries within messages must be align to this. * * See \ref core_msg_fmt_align for more information on message alignment. */ #define NLMSG_ALIGNTO 4 /** * Returns \p len properly aligned to NLMSG_ALIGNTO. * * See \ref core_msg_fmt_align for more information on message alignment. */ #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) /** * Length of a netlink message header including padding. * * See \ref core_msg_fmt_align for more information on message alignment. */ #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) /** @} */ /** * @addtogroup attr * @{ */ /* */ /** * Netlink attribute structure * * @code * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)--> * +---------------------+- - -+- - - - - - - - - -+- - -+ * | Header | Pad | Payload | Pad | * | (struct nlattr) | ing | | ing | * +---------------------+- - -+- - - - - - - - - -+- - -+ * <-------------- nlattr->nla_len --------------> * @endcode */ struct nlattr { /** * Attribute length in bytes including header */ __u16 nla_len; /** * Netlink attribute type */ __u16 nla_type; }; /** * @name Attribute Type Flags * * @code * nla_type (16 bits) * +---+---+-------------------------------+ * | N | O | Attribute Type | * +---+---+-------------------------------+ * N := Carries nested attributes * O := Payload stored in network byte order * @endcode * * @note The N and O flag are mutually exclusive. * * @{ */ /* */ #define NLA_F_NESTED (1 << 15) #define NLA_F_NET_BYTEORDER (1 << 14) #define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) /** @} */ #define NLA_ALIGNTO 4 /** * Returns \p len properly aligned to NLA_ALIGNTO. * * See \ref core_msg_fmt_align for more information on message alignment. */ #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) /** * Length of a netlink attribute header including padding. * * See \ref core_msg_fmt_align for more information on message alignment. */ #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) /** @} */ #endif #endif /* __LINUX_NETLINK_H */ libnl-3.2.29/include/netlink/netlink-compat.h0000644000175000017500000000173412505607054016026 00000000000000/* * netlink/netlink-compat.h Netlink Compatability * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_COMPAT_H_ #define NETLINK_COMPAT_H_ #if !defined _LINUX_SOCKET_H && !defined _BITS_SOCKADDR_H typedef unsigned short sa_family_t; #endif #ifndef IFNAMSIZ /** Maximum length of a interface name */ #define IFNAMSIZ 16 #endif /* patch 2.4.x if_arp */ #ifndef ARPHRD_INFINIBAND #define ARPHRD_INFINIBAND 32 #endif /* patch 2.4.x eth header file */ #ifndef ETH_P_MPLS_UC #define ETH_P_MPLS_UC 0x8847 #endif #ifndef ETH_P_MPLS_MC #define ETH_P_MPLS_MC 0x8848 #endif #ifndef ETH_P_EDP2 #define ETH_P_EDP2 0x88A2 #endif #ifndef ETH_P_HDLC #define ETH_P_HDLC 0x0019 #endif #ifndef AF_LLC #define AF_LLC 26 #endif #endif libnl-3.2.29/include/netlink/object.h0000644000175000017500000000500313023014600014321 00000000000000/* * netlink/object.c Generic Cacheable Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_OBJECT_H_ #define NETLINK_OBJECT_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct nl_cache; struct nl_object; struct nl_object_ops; #define OBJ_CAST(ptr) ((struct nl_object *) (ptr)) /* General */ extern struct nl_object * nl_object_alloc(struct nl_object_ops *); extern int nl_object_alloc_name(const char *, struct nl_object **); extern void nl_object_free(struct nl_object *); extern struct nl_object * nl_object_clone(struct nl_object *obj); extern int nl_object_update(struct nl_object *dst, struct nl_object *src); extern void nl_object_get(struct nl_object *); extern void nl_object_put(struct nl_object *); extern int nl_object_shared(struct nl_object *); extern void nl_object_dump(struct nl_object *, struct nl_dump_params *); extern void nl_object_dump_buf(struct nl_object *, char *, size_t); extern int nl_object_identical(struct nl_object *, struct nl_object *); extern uint32_t nl_object_diff(struct nl_object *, struct nl_object *); extern uint64_t nl_object_diff64(struct nl_object *, struct nl_object *); extern int nl_object_match_filter(struct nl_object *, struct nl_object *); extern char * nl_object_attrs2str(struct nl_object *, uint32_t attrs, char *buf, size_t); extern char * nl_object_attr_list(struct nl_object *, char *, size_t); extern void nl_object_keygen(struct nl_object *, uint32_t *, uint32_t); /* Marks */ extern void nl_object_mark(struct nl_object *); extern void nl_object_unmark(struct nl_object *); extern int nl_object_is_marked(struct nl_object *); /* Access Functions */ extern int nl_object_get_refcnt(struct nl_object *); extern struct nl_cache * nl_object_get_cache(struct nl_object *); extern const char * nl_object_get_type(const struct nl_object *); extern int nl_object_get_msgtype(const struct nl_object *); struct nl_object_ops * nl_object_get_ops(const struct nl_object *); uint32_t nl_object_get_id_attrs(struct nl_object *obj); static inline void * nl_object_priv(struct nl_object *obj) { return obj; } #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/utils.h0000644000175000017500000002437113031472553014242 00000000000000/* * netlink/utils.h Utility Functions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_UTILS_H_ #define NETLINK_UTILS_H_ #include #include #ifdef __cplusplus extern "C" { #endif /** * @name Probability Constants * @{ */ /** * Lower probability limit * @ingroup utils */ #define NL_PROB_MIN 0x0 /** * Upper probability limit nl_dump_type * @ingroup utils */ #define NL_PROB_MAX 0xffffffff /** @} */ enum { NL_BYTE_RATE, NL_BIT_RATE, }; /* unit pretty-printing */ extern double nl_cancel_down_bytes(unsigned long long, char **); extern double nl_cancel_down_bits(unsigned long long, char **); extern int nl_rate2str(unsigned long long, int, char *, size_t); extern double nl_cancel_down_us(uint32_t, char **); /* generic unit translations */ extern long nl_size2int(const char *); extern char * nl_size2str(const size_t, char *, const size_t); extern long nl_prob2int(const char *); /* time translations */ extern int nl_get_user_hz(void); extern int nl_get_psched_hz(void); extern uint32_t nl_us2ticks(uint32_t); extern uint32_t nl_ticks2us(uint32_t); extern int nl_str2msec(const char *, uint64_t *); extern char * nl_msec2str(uint64_t, char *, size_t); /* link layer protocol translations */ extern char * nl_llproto2str(int, char *, size_t); extern int nl_str2llproto(const char *); /* ethernet protocol translations */ extern char * nl_ether_proto2str(int, char *, size_t); extern int nl_str2ether_proto(const char *); /* IP protocol translations */ extern char * nl_ip_proto2str(int, char *, size_t); extern int nl_str2ip_proto(const char *); /* Dumping helpers */ extern void nl_new_line(struct nl_dump_params *); extern void nl_dump(struct nl_dump_params *, const char *, ...); extern void nl_dump_line(struct nl_dump_params *, const char *, ...); enum { NL_CAPABILITY_NONE, /** * rtnl_route_build_msg() no longer guesses the route scope * if explicitly set to RT_SCOPE_NOWHERE. * @ingroup utils */ NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE = 1, #define NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE /** * rtnl_link_veth_get_peer() now returns a reference that is owned by the * caller and must be released by the caller with rtnl_link_put(). */ NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE = 2, #define NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE /** * rtnl_u32_add_action() and rtnl_basic_add_action() now grab a reference to act * caller are free to release its own */ NL_CAPABILITY_ROUTE_LINK_CLS_ADD_ACT_OWN_REFERENCE = 3, #define NL_CAPABILITY_ROUTE_LINK_CLS_ADD_ACT_OWN_REFERENCE NL_CAPABILITY_ROUTE_LINK_CLS_ADD_ACT_OWN_REFERENCE /** * Indicate that the local port is unspecified until the user accesses * it (via nl_socket_get_local_port()) or until nl_connect(). More importantly, * if the port is left unspecified, nl_connect() will retry generating another * port when bind() fails with ADDRINUSE. */ NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE = 4, #define NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE /** * Indicate that rtnl_link_get_kernel() fails with -NLE_OPNOTSUPP in case * of older kernals not supporting lookup by ifname. This changes behavior * from returning -NLE_INVAL to return -NLE_OPNOTSUPP. */ NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP = 5, #define NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP /** * Also consider the a_cacheinfo field (ADDR_ATTR_CACHEINFO) that contains the * address timestamps and expiry when comparing struct rtnl_addr objects with * nl_object_diff(). */ NL_CAPABILITY_ROUTE_ADDR_COMPARE_CACHEINFO = 6, #define NL_CAPABILITY_ROUTE_ADDR_COMPARE_CACHEINFO NL_CAPABILITY_ROUTE_ADDR_COMPARE_CACHEINFO /** * The library version is libnl3 3.2.26 or newer. This capability should never be backported. */ NL_CAPABILITY_VERSION_3_2_26 = 7, #define NL_CAPABILITY_VERSION_3_2_26 NL_CAPABILITY_VERSION_3_2_26 /** * nl_recv() fails with NLE_MSG_TRUNC if a message got truncated * with NL_MSG_PEEK disabled. Previously, the failed message was wrongly * discarded and the next message received. */ NL_CAPABILITY_NL_RECV_FAIL_TRUNC_NO_PEEK = 8, #define NL_CAPABILITY_NL_RECV_FAIL_TRUNC_NO_PEEK NL_CAPABILITY_NL_RECV_FAIL_TRUNC_NO_PEEK /** * rtnl_link_build_change_request() and rtnl_link_change() would set ifi.ifi_flags but leave * ifi.ifi_change at zero. This was later fixed to set ifi.ifi_change to the flags that are actually * set in changes. */ NL_CAPABILITY_LINK_BUILD_CHANGE_REQUEST_SET_CHANGE = 9, #define NL_CAPABILITY_LINK_BUILD_CHANGE_REQUEST_SET_CHANGE NL_CAPABILITY_LINK_BUILD_CHANGE_REQUEST_SET_CHANGE /** * Between 3.2.14 (64fcb47a36ec12d7e7f00605f6a8952ce985dd08) and 3.2.22 (8571f58f23763d8db7365d02c9b27832ad3d7005), * rtnl_neigh_get() behaved differently and only returned objects with family AF_UNSPEC. * This capability indicates, that the function was fixed. The absense of the capability, * doesn't indicate however which behavior the function will have. So beware. */ NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX = 10, #define NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX /** * The library version is libnl3 3.2.27 or newer. This capability should never be backported. */ NL_CAPABILITY_VERSION_3_2_27 = 11, #define NL_CAPABILITY_VERSION_3_2_27 NL_CAPABILITY_VERSION_3_2_27 /** * Properly serialize vlan protocol IFLA_VLAN_PROTOCOL. */ NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE = 12, #define NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE /** * Properly read gre REMOTE port. */ NL_CAPABILITY_RTNL_LINK_PARSE_GRE_REMOTE = 13, #define NL_CAPABILITY_RTNL_LINK_PARSE_GRE_REMOTE NL_CAPABILITY_RTNL_LINK_PARSE_GRE_REMOTE /** * Don't skip over vlan ingress-map entries with "to" field zero when serializing * a netlink message. Previously such entires would be ignored which inhibits the * user from clearing ingress map entries. */ NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR = 14, #define NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR /** * Consider vxlan link info for nl_object_diff(). */ NL_CAPABILITY_RTNL_LINK_VXLAN_IO_COMPARE = 15, #define NL_CAPABILITY_RTNL_LINK_VXLAN_IO_COMPARE NL_CAPABILITY_RTNL_LINK_VXLAN_IO_COMPARE /** * Support 64 bit attributes for nl_object_diff(). */ NL_CAPABILITY_NL_OBJECT_DIFF64 = 16, #define NL_CAPABILITY_NL_OBJECT_DIFF64 NL_CAPABILITY_NL_OBJECT_DIFF64 /** * Support omitting @key argument to xfrmnl_sa_get_*_params() to check * for required buffer size for key. */ NL_CAPABILITY_XFRM_SA_KEY_SIZE = 17, #define NL_CAPABILITY_XFRM_SA_KEY_SIZE NL_CAPABILITY_XFRM_SA_KEY_SIZE /** * Properly handle nl_object_identity() for AF_INET and AF_INET6 addresses * and properly handle the peer/IFA_ADDRESS for IPv4 addresses. */ NL_CAPABILITY_RTNL_ADDR_PEER_FIX = 18, #define NL_CAPABILITY_RTNL_ADDR_PEER_FIX NL_CAPABILITY_RTNL_ADDR_PEER_FIX /** * The library version is libnl3 3.2.28 or newer. This capability should never be backported. */ NL_CAPABILITY_VERSION_3_2_28 = 19, #define NL_CAPABILITY_VERSION_3_2_28 NL_CAPABILITY_VERSION_3_2_28 /** * After NL_CAPABILITY_RTNL_ADDR_PEER_FIX, a follow up regression to lookup * IPv4 addresses in the cache was fixed (PR#105). */ NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX = 20, #define NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX /** * nl_addr_fill_sockaddr() properly checks that the provided address to * avoid read-out-of-bounds for invalid addresses. */ NL_CAPABILITY_NL_ADDR_FILL_SOCKADDR = 21, #define NL_CAPABILITY_NL_ADDR_FILL_SOCKADDR NL_CAPABILITY_NL_ADDR_FILL_SOCKADDR /** * Support omitting @ctx_str argument to xfrmnl_sa_get_sec_ctx() to check * for required buffer size for context string. */ NL_CAPABILITY_XFRM_SEC_CTX_LEN = 22, #define NL_CAPABILITY_XFRM_SEC_CTX_LEN NL_CAPABILITY_XFRM_SEC_CTX_LEN /** * rtnl_link_build_add_request() would set ifi.ifi_flags but leave ifi.ifi_change at zero. * This was later fixed to set ifi.ifi_change to the flags that are actually * set */ NL_CAPABILITY_LINK_BUILD_ADD_REQUEST_SET_CHANGE = 23, #define NL_CAPABILITY_LINK_BUILD_ADD_REQUEST_SET_CHANGE NL_CAPABILITY_LINK_BUILD_ADD_REQUEST_SET_CHANGE /* Older versions of libnl3 would not use MSG_PEEK for nl_recvmsgs() unless calling * nl_socket_enable_msg_peek(). Instead, the user had to specify the buffer size via * nl_socket_set_msg_buf_size(), which in turn would default to 4*getpagesize(). * * The default value might not be large enough, so users who were not aware of the * problem easily ended up using a too small receive buffer. Usually, one wants to * avoid MSG_PEEK for recvmsg() because it requires an additional syscall. * * Now, as indicated by this capability, nl_recvmsgs() would use MSG_PEEK by default. The * user still can explicitly disable MSG_PEEK by calling nl_socket_disable_msg_peek() or * by setting the nl_socket_set_msg_buf_size() to a non-zero value. */ NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT = 24, #define NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT /** * The library version is libnl3 3.2.29 or newer. This capability should never be backported. */ NL_CAPABILITY_VERSION_3_2_29 = 25, #define NL_CAPABILITY_VERSION_3_2_29 NL_CAPABILITY_VERSION_3_2_29 __NL_CAPABILITY_MAX, NL_CAPABILITY_MAX = (__NL_CAPABILITY_MAX - 1), #define NL_CAPABILITY_MAX NL_CAPABILITY_MAX /** * The range 0x7000 to 0x7FFF is reserved for private capabilities. Upstream libnl3 will * not register capabilities in this range. However, instead of adding private capabilities, * better register their number with upstream libnl3. */ #define NL_CAPABILITY_IS_USER_RESERVED(cap) ( ((cap) & ~0x0FFF) == 0x7000 ) }; int nl_has_capability (int capability); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/errno.h0000644000175000017500000000267113023014600014210 00000000000000/* * netlink/errno.h Error Numbers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008 Thomas Graf */ #ifndef NETLINK_ERRNO_H_ #define NETLINK_ERRNO_H_ #ifdef __cplusplus extern "C" { #endif #define NLE_SUCCESS 0 #define NLE_FAILURE 1 #define NLE_INTR 2 #define NLE_BAD_SOCK 3 #define NLE_AGAIN 4 #define NLE_NOMEM 5 #define NLE_EXIST 6 #define NLE_INVAL 7 #define NLE_RANGE 8 #define NLE_MSGSIZE 9 #define NLE_OPNOTSUPP 10 #define NLE_AF_NOSUPPORT 11 #define NLE_OBJ_NOTFOUND 12 #define NLE_NOATTR 13 #define NLE_MISSING_ATTR 14 #define NLE_AF_MISMATCH 15 #define NLE_SEQ_MISMATCH 16 #define NLE_MSG_OVERFLOW 17 #define NLE_MSG_TRUNC 18 #define NLE_NOADDR 19 #define NLE_SRCRT_NOSUPPORT 20 #define NLE_MSG_TOOSHORT 21 #define NLE_MSGTYPE_NOSUPPORT 22 #define NLE_OBJ_MISMATCH 23 #define NLE_NOCACHE 24 #define NLE_BUSY 25 #define NLE_PROTO_MISMATCH 26 #define NLE_NOACCESS 27 #define NLE_PERM 28 #define NLE_PKTLOC_FILE 29 #define NLE_PARSE_ERR 30 #define NLE_NODEV 31 #define NLE_IMMUTABLE 32 #define NLE_DUMP_INTR 33 #define NLE_ATTRSIZE 34 #define NLE_MAX NLE_ATTRSIZE extern const char * nl_geterror(int); extern void nl_perror(int, const char *); extern int nl_syserr2nlerr(int); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/types.h0000644000175000017500000000422013023014600014217 00000000000000/* * netlink/types.h Definition of public types * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef __NETLINK_TYPES_H_ #define __NETLINK_TYPES_H_ #include /** * @ingroup utils * Enumeration of dumping variations (dp_type) */ enum nl_dump_type { NL_DUMP_LINE, /**< Dump object briefly on one line */ NL_DUMP_DETAILS, /**< Dump all attributes but no statistics */ NL_DUMP_STATS, /**< Dump all attributes including statistics */ __NL_DUMP_MAX, }; #define NL_DUMP_MAX (__NL_DUMP_MAX - 1) /** * @ingroup utils * Dumping parameters */ struct nl_dump_params { /** * Specifies the type of dump that is requested. */ enum nl_dump_type dp_type; /** * Specifies the number of whitespaces to be put in front * of every new line (indentation). */ int dp_prefix; /** * Causes the cache index to be printed for each element. */ int dp_print_index; /** * Causes each element to be prefixed with the message type. */ int dp_dump_msgtype; /** * A callback invoked for output * * Passed arguments are: * - dumping parameters * - string to append to the output */ void (*dp_cb)(struct nl_dump_params *, char *); /** * A callback invoked for every new line, can be used to * customize the indentation. * * Passed arguments are: * - dumping parameters * - line number starting from 0 */ void (*dp_nl_cb)(struct nl_dump_params *, int); /** * User data pointer, can be used to pass data to callbacks. */ void *dp_data; /** * File descriptor the dumping output should go to */ FILE * dp_fd; /** * Alternatively the output may be redirected into a buffer */ char * dp_buf; /** * Length of the buffer dp_buf */ size_t dp_buflen; /** * PRIVATE * Set if a dump was performed prior to the actual dump handler. */ int dp_pre_dump; /** * PRIVATE * Owned by the current caller */ int dp_ivar; unsigned int dp_line; }; #endif libnl-3.2.29/include/netlink/handlers.h0000644000175000017500000000713413023014600014662 00000000000000/* * netlink/handlers.c default netlink message handlers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_HANDLERS_H_ #define NETLINK_HANDLERS_H_ #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct nl_cb; struct nl_sock; struct nl_msg; struct ucred; /** * @name Callback Typedefs * @{ */ /** * nl_recvmsgs() callback for message processing customization * @ingroup cb * @arg msg netlink message being processed * @arg arg argument passwd on through caller */ typedef int (*nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg); /** * nl_recvmsgs() callback for error message processing customization * @ingroup cb * @arg nla netlink address of the peer * @arg nlerr netlink error message being processed * @arg arg argument passed on through caller */ typedef int (*nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg); /** @} */ /** * Callback actions * @ingroup cb */ enum nl_cb_action { /** Proceed with wathever would come next */ NL_OK, /** Skip this message */ NL_SKIP, /** Stop parsing altogether and discard remaining messages */ NL_STOP, }; /** * Callback kinds * @ingroup cb */ enum nl_cb_kind { /** Default handlers (quiet) */ NL_CB_DEFAULT, /** Verbose default handlers (error messages printed) */ NL_CB_VERBOSE, /** Debug handlers for debugging */ NL_CB_DEBUG, /** Customized handler specified by the user */ NL_CB_CUSTOM, __NL_CB_KIND_MAX, }; #define NL_CB_KIND_MAX (__NL_CB_KIND_MAX - 1) /** * Callback types * @ingroup cb */ enum nl_cb_type { /** Message is valid */ NL_CB_VALID, /** Last message in a series of multi part messages received */ NL_CB_FINISH, /** Report received that data was lost */ NL_CB_OVERRUN, /** Message wants to be skipped */ NL_CB_SKIPPED, /** Message is an acknowledge */ NL_CB_ACK, /** Called for every message received */ NL_CB_MSG_IN, /** Called for every message sent out except for nl_sendto() */ NL_CB_MSG_OUT, /** Message is malformed and invalid */ NL_CB_INVALID, /** Called instead of internal sequence number checking */ NL_CB_SEQ_CHECK, /** Sending of an acknowledge message has been requested */ NL_CB_SEND_ACK, /** Flag NLM_F_DUMP_INTR is set in message */ NL_CB_DUMP_INTR, __NL_CB_TYPE_MAX, }; #define NL_CB_TYPE_MAX (__NL_CB_TYPE_MAX - 1) extern struct nl_cb * nl_cb_alloc(enum nl_cb_kind); extern struct nl_cb * nl_cb_clone(struct nl_cb *); extern struct nl_cb * nl_cb_get(struct nl_cb *); extern void nl_cb_put(struct nl_cb *); extern int nl_cb_set(struct nl_cb *, enum nl_cb_type, enum nl_cb_kind, nl_recvmsg_msg_cb_t, void *); extern int nl_cb_set_all(struct nl_cb *, enum nl_cb_kind, nl_recvmsg_msg_cb_t, void *); extern int nl_cb_err(struct nl_cb *, enum nl_cb_kind, nl_recvmsg_err_cb_t, void *); extern void nl_cb_overwrite_recvmsgs(struct nl_cb *, int (*func)(struct nl_sock *, struct nl_cb *)); extern void nl_cb_overwrite_recv(struct nl_cb *, int (*func)(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **)); extern void nl_cb_overwrite_send(struct nl_cb *, int (*func)(struct nl_sock *, struct nl_msg *)); extern enum nl_cb_type nl_cb_active_type(struct nl_cb *cb); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/version.h.in0000644000175000017500000000177613023014600015162 00000000000000/* * netlink/version.h Versioning Information * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2011 Thomas Graf */ #ifndef NETLINK_VERSION_H_ #define NETLINK_VERSION_H_ /* Compile Time Versioning Information */ #define LIBNL_STRING "@PACKAGE_STRING@" #define LIBNL_VERSION "@PACKAGE_VERSION@" #define LIBNL_VER_MAJ @MAJ_VERSION@ #define LIBNL_VER_MIN @MIN_VERSION@ #define LIBNL_VER_MIC @MIC_VERSION@ #define LIBNL_VER(maj,min) ((maj) << 8 | (min)) #define LIBNL_VER_NUM LIBNL_VER(LIBNL_VER_MAJ, LIBNL_VER_MIN) #define LIBNL_CURRENT @LT_CURRENT@ #define LIBNL_REVISION @LT_REVISION@ #define LIBNL_AGE @LT_AGE@ /* Run-time version information */ extern const int nl_ver_num; extern const int nl_ver_maj; extern const int nl_ver_min; extern const int nl_ver_mic; #endif libnl-3.2.29/include/netlink/attr.h0000644000175000017500000002265013023014600014034 00000000000000/* * netlink/attr.h Netlink Attributes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_ATTR_H_ #define NETLINK_ATTR_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct nl_msg; /** * @name Basic Attribute Data Types * @{ */ /** * @ingroup attr * Basic attribute data types * * See section @core_doc{core_attr_parse,Attribute Parsing} for more details. */ enum { NLA_UNSPEC, /**< Unspecified type, binary data chunk */ NLA_U8, /**< 8 bit integer */ NLA_U16, /**< 16 bit integer */ NLA_U32, /**< 32 bit integer */ NLA_U64, /**< 64 bit integer */ NLA_STRING, /**< NUL terminated character string */ NLA_FLAG, /**< Flag */ NLA_MSECS, /**< Micro seconds (64bit) */ NLA_NESTED, /**< Nested attributes */ NLA_NESTED_COMPAT, NLA_NUL_STRING, NLA_BINARY, NLA_S8, NLA_S16, NLA_S32, NLA_S64, __NLA_TYPE_MAX, }; #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) /** @} */ /** * @ingroup attr * Attribute validation policy. * * See section @core_doc{core_attr_parse,Attribute Parsing} for more details. */ struct nla_policy { /** Type of attribute or NLA_UNSPEC */ uint16_t type; /** Minimal length of payload required */ uint16_t minlen; /** Maximal length of payload allowed */ uint16_t maxlen; }; /* Size calculations */ extern int nla_attr_size(int payload); extern int nla_total_size(int payload); extern int nla_padlen(int payload); /* Attribute parsing */ extern int nla_type(const struct nlattr *); extern void * nla_data(const struct nlattr *); extern int nla_len(const struct nlattr *); extern int nla_ok(const struct nlattr *, int); extern struct nlattr * nla_next(const struct nlattr *, int *); extern int nla_parse(struct nlattr **, int, struct nlattr *, int, struct nla_policy *); extern int nla_validate(const struct nlattr *, int, int, const struct nla_policy *); extern struct nlattr * nla_find(const struct nlattr *, int, int); /* Helper Functions */ extern int nla_memcpy(void *, const struct nlattr *, int); extern size_t nla_strlcpy(char *, const struct nlattr *, size_t); extern int nla_memcmp(const struct nlattr *, const void *, size_t); extern int nla_strcmp(const struct nlattr *, const char *); /* Unspecific attribute */ extern struct nlattr * nla_reserve(struct nl_msg *, int, int); extern int nla_put(struct nl_msg *, int, int, const void *); extern int nla_put_data(struct nl_msg *, int, const struct nl_data *); extern int nla_put_addr(struct nl_msg *, int, struct nl_addr *); /* Integer attribute */ extern int8_t nla_get_s8(const struct nlattr *); extern int nla_put_s8(struct nl_msg *, int, int8_t); extern uint8_t nla_get_u8(const struct nlattr *); extern int nla_put_u8(struct nl_msg *, int, uint8_t); extern int16_t nla_get_s16(const struct nlattr *); extern int nla_put_s16(struct nl_msg *, int, int16_t); extern uint16_t nla_get_u16(const struct nlattr *); extern int nla_put_u16(struct nl_msg *, int, uint16_t); extern int32_t nla_get_s32(const struct nlattr *); extern int nla_put_s32(struct nl_msg *, int, int32_t); extern uint32_t nla_get_u32(const struct nlattr *); extern int nla_put_u32(struct nl_msg *, int, uint32_t); extern int64_t nla_get_s64(const struct nlattr *); extern int nla_put_s64(struct nl_msg *, int, int64_t); extern uint64_t nla_get_u64(const struct nlattr *); extern int nla_put_u64(struct nl_msg *, int, uint64_t); /* String attribute */ extern char * nla_get_string(const struct nlattr *); extern char * nla_strdup(const struct nlattr *); extern int nla_put_string(struct nl_msg *, int, const char *); /* Flag attribute */ extern int nla_get_flag(const struct nlattr *); extern int nla_put_flag(struct nl_msg *, int); /* Msec attribute */ extern unsigned long nla_get_msecs(const struct nlattr *); extern int nla_put_msecs(struct nl_msg *, int, unsigned long); /* Attribute nesting */ extern int nla_put_nested(struct nl_msg *, int, const struct nl_msg *); extern struct nlattr * nla_nest_start(struct nl_msg *, int); extern int nla_nest_end(struct nl_msg *, struct nlattr *); extern void nla_nest_cancel(struct nl_msg *, const struct nlattr *); extern int nla_parse_nested(struct nlattr **, int, struct nlattr *, struct nla_policy *); extern int nla_is_nested(const struct nlattr *); /** * @name Attribute Construction (Exception Based) * @{ */ /** * @ingroup attr * Add unspecific attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg attrlen Length of attribute payload. * @arg data Head of attribute payload. */ #define NLA_PUT(msg, attrtype, attrlen, data) \ do { \ if (nla_put(msg, attrtype, attrlen, data) < 0) \ goto nla_put_failure; \ } while(0) /** * @ingroup attr * Add atomic type attribute to netlink message. * @arg msg Netlink message. * @arg type Atomic type. * @arg attrtype Attribute type. * @arg value Head of attribute payload. */ #define NLA_PUT_TYPE(msg, type, attrtype, value) \ do { \ type __tmp = value; \ NLA_PUT(msg, attrtype, sizeof(type), &__tmp); \ } while(0) /** * Add 8 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_S8(msg, attrtype, value) \ NLA_PUT_TYPE(msg, int8_t, attrtype, value) /** * Add 8 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_U8(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint8_t, attrtype, value) /** * Add 16 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_S16(msg, attrtype, value) \ NLA_PUT_TYPE(msg, int16_t, attrtype, value) /** * Add 16 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_U16(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint16_t, attrtype, value) /** * Add 32 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_S32(msg, attrtype, value) \ NLA_PUT_TYPE(msg, int32_t, attrtype, value) /** * Add 32 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_U32(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint32_t, attrtype, value) /** * Add 64 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_S64(msg, attrtype, value) \ NLA_PUT_TYPE(msg, int64_t, attrtype, value) /** * Add 64 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value. */ #define NLA_PUT_U64(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint64_t, attrtype, value) /** * Add string attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value NUL terminated character string. */ #define NLA_PUT_STRING(msg, attrtype, value) \ NLA_PUT(msg, attrtype, (int) strlen(value) + 1, value) /** * Add flag attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. */ #define NLA_PUT_FLAG(msg, attrtype) \ NLA_PUT(msg, attrtype, 0, NULL) /** * Add msecs attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg msecs Numeric value in micro seconds. */ #define NLA_PUT_MSECS(msg, attrtype, msecs) \ NLA_PUT_U64(msg, attrtype, msecs) /** * Add address attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg addr Abstract address object. */ #define NLA_PUT_ADDR(msg, attrtype, addr) \ NLA_PUT(msg, attrtype, nl_addr_get_len(addr), \ nl_addr_get_binary_addr(addr)) /** * Add abstract data attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg data Abstract data object. */ #define NLA_PUT_DATA(msg, attrtype, data) \ NLA_PUT(msg, attrtype, nl_data_get_size(data), \ nl_data_get(data)) /** @} */ /** * @name Iterators * @{ */ /** * @ingroup attr * Iterate over a stream of attributes * @arg pos loop counter, set to current attribute * @arg head head of attribute stream * @arg len length of attribute stream * @arg rem initialized to len, holds bytes currently remaining in stream */ #define nla_for_each_attr(pos, head, len, rem) \ for (pos = head, rem = len; \ nla_ok(pos, rem); \ pos = nla_next(pos, &(rem))) /** * @ingroup attr * Iterate over a stream of nested attributes * @arg pos loop counter, set to current attribute * @arg nla attribute containing the nested attributes * @arg rem initialized to len, holds bytes currently remaining in stream */ #define nla_for_each_nested(pos, nla, rem) \ for (pos = (struct nlattr *) nla_data(nla), rem = nla_len(nla); \ nla_ok(pos, rem); \ pos = nla_next(pos, &(rem))) /** @} */ #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/cache.h0000644000175000017500000001411713023014600014124 00000000000000/* * netlink/cache.h Caching Module * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_CACHE_H_ #define NETLINK_CACHE_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif enum { NL_ACT_UNSPEC, NL_ACT_NEW, NL_ACT_DEL, NL_ACT_GET, NL_ACT_SET, NL_ACT_CHANGE, __NL_ACT_MAX, }; #define NL_ACT_MAX (__NL_ACT_MAX - 1) struct nl_cache; typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *); typedef void (*change_func_v2_t)(struct nl_cache *, struct nl_object *old_obj, struct nl_object *new_obj, uint64_t, int, void *); /** * @ingroup cache * Explicitely iterate over all address families when updating the cache */ #define NL_CACHE_AF_ITER 0x0001 /* Access Functions */ extern int nl_cache_nitems(struct nl_cache *); extern int nl_cache_nitems_filter(struct nl_cache *, struct nl_object *); extern struct nl_cache_ops * nl_cache_get_ops(struct nl_cache *); extern struct nl_object * nl_cache_get_first(struct nl_cache *); extern struct nl_object * nl_cache_get_last(struct nl_cache *); extern struct nl_object * nl_cache_get_next(struct nl_object *); extern struct nl_object * nl_cache_get_prev(struct nl_object *); extern struct nl_cache * nl_cache_alloc(struct nl_cache_ops *); extern int nl_cache_alloc_and_fill(struct nl_cache_ops *, struct nl_sock *, struct nl_cache **); extern int nl_cache_alloc_name(const char *, struct nl_cache **); extern struct nl_cache * nl_cache_subset(struct nl_cache *, struct nl_object *); extern struct nl_cache * nl_cache_clone(struct nl_cache *); extern void nl_cache_clear(struct nl_cache *); extern void nl_cache_get(struct nl_cache *); extern void nl_cache_free(struct nl_cache *); extern void nl_cache_put(struct nl_cache *cache); /* Cache modification */ extern int nl_cache_add(struct nl_cache *, struct nl_object *); extern int nl_cache_parse_and_add(struct nl_cache *, struct nl_msg *); extern int nl_cache_move(struct nl_cache *, struct nl_object *); extern void nl_cache_remove(struct nl_object *); extern int nl_cache_refill(struct nl_sock *, struct nl_cache *); extern int nl_cache_pickup(struct nl_sock *, struct nl_cache *); extern int nl_cache_pickup_checkdup(struct nl_sock *, struct nl_cache *); extern int nl_cache_resync(struct nl_sock *, struct nl_cache *, change_func_t, void *); extern int nl_cache_include(struct nl_cache *, struct nl_object *, change_func_t, void *); extern int nl_cache_include_v2(struct nl_cache *, struct nl_object *, change_func_v2_t, void *); extern void nl_cache_set_arg1(struct nl_cache *, int); extern void nl_cache_set_arg2(struct nl_cache *, int); extern void nl_cache_set_flags(struct nl_cache *, unsigned int); /* General */ extern int nl_cache_is_empty(struct nl_cache *); extern struct nl_object * nl_cache_search(struct nl_cache *, struct nl_object *); extern struct nl_object *nl_cache_find(struct nl_cache *, struct nl_object *); extern void nl_cache_mark_all(struct nl_cache *); /* Dumping */ extern void nl_cache_dump(struct nl_cache *, struct nl_dump_params *); extern void nl_cache_dump_filter(struct nl_cache *, struct nl_dump_params *, struct nl_object *); /* Iterators */ extern void nl_cache_foreach(struct nl_cache *, void (*cb)(struct nl_object *, void *), void *arg); extern void nl_cache_foreach_filter(struct nl_cache *, struct nl_object *, void (*cb)(struct nl_object *, void *), void *arg); /* --- cache management --- */ /* Cache type management */ extern struct nl_cache_ops * nl_cache_ops_lookup(const char *); extern struct nl_cache_ops * nl_cache_ops_lookup_safe(const char *); extern struct nl_cache_ops * nl_cache_ops_associate(int, int); extern struct nl_cache_ops * nl_cache_ops_associate_safe(int, int); extern struct nl_msgtype * nl_msgtype_lookup(struct nl_cache_ops *, int); extern void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *); extern int nl_cache_mngt_register(struct nl_cache_ops *); extern int nl_cache_mngt_unregister(struct nl_cache_ops *); /* Global cache provisioning/requiring */ extern void nl_cache_mngt_provide(struct nl_cache *); extern void nl_cache_mngt_unprovide(struct nl_cache *); extern struct nl_cache * nl_cache_mngt_require(const char *); extern struct nl_cache * nl_cache_mngt_require_safe(const char *); extern struct nl_cache * __nl_cache_mngt_require(const char *); struct nl_cache_mngr; #define NL_AUTO_PROVIDE 1 #define NL_ALLOCATED_SOCK 2 /* For internal use only, do not use */ extern int nl_cache_mngr_alloc(struct nl_sock *, int, int, struct nl_cache_mngr **); extern int nl_cache_mngr_add(struct nl_cache_mngr *, const char *, change_func_t, void *, struct nl_cache **); extern int nl_cache_mngr_add_cache(struct nl_cache_mngr *mngr, struct nl_cache *cache, change_func_t cb, void *data); extern int nl_cache_mngr_add_cache_v2(struct nl_cache_mngr *mngr, struct nl_cache *cache, change_func_v2_t cb, void *data); extern int nl_cache_mngr_get_fd(struct nl_cache_mngr *); extern int nl_cache_mngr_poll(struct nl_cache_mngr *, int); extern int nl_cache_mngr_data_ready(struct nl_cache_mngr *); extern void nl_cache_mngr_info(struct nl_cache_mngr *, struct nl_dump_params *); extern void nl_cache_mngr_free(struct nl_cache_mngr *); extern void nl_cache_ops_get(struct nl_cache_ops *); extern void nl_cache_ops_put(struct nl_cache_ops *); extern void nl_cache_ops_set_flags(struct nl_cache_ops *, unsigned int); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/socket.h0000644000175000017500000000512713023014600014352 00000000000000/* * netlink/socket.h Netlink Socket * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_SOCKET_H_ #define NETLINK_SOCKET_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct nl_sock * nl_socket_alloc(void); extern struct nl_sock * nl_socket_alloc_cb(struct nl_cb *); extern void nl_socket_free(struct nl_sock *); extern uint32_t nl_socket_get_local_port(const struct nl_sock *); extern void nl_socket_set_local_port(struct nl_sock *, uint32_t); extern int nl_socket_add_memberships(struct nl_sock *, int, ...); extern int nl_socket_add_membership(struct nl_sock *, int); extern int nl_socket_drop_memberships(struct nl_sock *, int, ...); extern int nl_socket_drop_membership(struct nl_sock *, int); extern void nl_join_groups(struct nl_sock *, int); extern uint32_t nl_socket_get_peer_port(const struct nl_sock *); extern void nl_socket_set_peer_port(struct nl_sock *, uint32_t); extern uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk); extern void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups); extern struct nl_cb * nl_socket_get_cb(const struct nl_sock *); extern void nl_socket_set_cb(struct nl_sock *, struct nl_cb *); extern int nl_socket_modify_cb(struct nl_sock *, enum nl_cb_type, enum nl_cb_kind, nl_recvmsg_msg_cb_t, void *); extern int nl_socket_modify_err_cb(struct nl_sock *, enum nl_cb_kind, nl_recvmsg_err_cb_t, void *); extern int nl_socket_set_buffer_size(struct nl_sock *, int, int); extern int nl_socket_set_msg_buf_size(struct nl_sock *, size_t); extern size_t nl_socket_get_msg_buf_size(struct nl_sock *); extern int nl_socket_set_passcred(struct nl_sock *, int); extern int nl_socket_recv_pktinfo(struct nl_sock *, int); extern void nl_socket_disable_seq_check(struct nl_sock *); extern unsigned int nl_socket_use_seq(struct nl_sock *); extern void nl_socket_disable_auto_ack(struct nl_sock *); extern void nl_socket_enable_auto_ack(struct nl_sock *); extern int nl_socket_get_fd(const struct nl_sock *); extern int nl_socket_set_fd(struct nl_sock *sk, int protocol, int fd); extern int nl_socket_set_nonblocking(const struct nl_sock *); extern void nl_socket_enable_msg_peek(struct nl_sock *); extern void nl_socket_disable_msg_peek(struct nl_sock *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/object-api.h0000644000175000017500000000073713023014600015101 00000000000000/* * netlink/object-api.h Object API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #ifndef NETLINK_DUMMY_OBJECT_API_H_ #define NETLINK_DUMMY_OBJECT_API_H_ #include #include #include #endif libnl-3.2.29/include/netlink/netlink.h0000644000175000017500000000612613023014600014526 00000000000000/* * netlink/netlink.h Netlink Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_NETLINK_H_ #define NETLINK_NETLINK_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct ucred; struct nl_cache_ops; struct nl_parser_param; struct nl_object; struct nl_sock; extern int nl_debug; extern struct nl_dump_params nl_debug_dp; /* Connection Management */ extern int nl_connect(struct nl_sock *, int); extern void nl_close(struct nl_sock *); /* Send */ extern int nl_sendto(struct nl_sock *, void *, size_t); extern int nl_sendmsg(struct nl_sock *, struct nl_msg *, struct msghdr *); extern int nl_send(struct nl_sock *, struct nl_msg *); extern int nl_send_iovec(struct nl_sock *, struct nl_msg *, struct iovec *, unsigned); extern void nl_complete_msg(struct nl_sock *, struct nl_msg *); extern void nl_auto_complete(struct nl_sock *, struct nl_msg *); extern int nl_send_auto(struct nl_sock *, struct nl_msg *); extern int nl_send_auto_complete(struct nl_sock *, struct nl_msg *); extern int nl_send_sync(struct nl_sock *, struct nl_msg *); extern int nl_send_simple(struct nl_sock *, int, int, void *, size_t); /* Receive */ extern int nl_recv(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **); extern int nl_recvmsgs(struct nl_sock *, struct nl_cb *); extern int nl_recvmsgs_report(struct nl_sock *, struct nl_cb *); extern int nl_recvmsgs_default(struct nl_sock *); extern int nl_wait_for_ack(struct nl_sock *); extern int nl_pickup(struct nl_sock *, int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **); extern int nl_pickup_keep_syserr(struct nl_sock *sk, int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result, int *syserror); /* Netlink Family Translations */ extern char * nl_nlfamily2str(int, char *, size_t); extern int nl_str2nlfamily(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/cache-api.h0000644000175000017500000000102413023014600014664 00000000000000/* * netlink/cache-api.h Caching API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #ifndef NETLINK_DUMMY_CACHE_API_H_ #define NETLINK_DUMMY_CACHE_API_H_ #include #include #warning "You are including a deprecated header file, include ." #endif libnl-3.2.29/include/netlink/route/0000755000175000017500000000000013031473756014146 500000000000000libnl-3.2.29/include/netlink/route/pktloc.h0000644000175000017500000000207413023014600015512 00000000000000/* * netlink/route/pktloc.h Packet Location Aliasing * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #ifndef NETLINK_PKTLOC_H_ #define NETLINK_PKTLOC_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_pktloc { char * name; uint8_t layer; uint8_t shift; uint16_t offset; uint16_t align; uint32_t mask; uint32_t refcnt; struct nl_list_head list; }; extern int rtnl_pktloc_lookup(const char *, struct rtnl_pktloc **); extern struct rtnl_pktloc *rtnl_pktloc_alloc(void); extern void rtnl_pktloc_put(struct rtnl_pktloc *); extern int rtnl_pktloc_add(struct rtnl_pktloc *); extern void rtnl_pktloc_foreach(void (*cb)(struct rtnl_pktloc *, void *), void *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc.h0000644000175000017500000000411313023014600015315 00000000000000/* * netlink/route/qdisc.h Queueing Disciplines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_QDISC_H_ #define NETLINK_QDISC_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_qdisc; extern struct rtnl_qdisc * rtnl_qdisc_alloc(void); extern void rtnl_qdisc_put(struct rtnl_qdisc *); extern int rtnl_qdisc_alloc_cache(struct nl_sock *, struct nl_cache **); extern struct rtnl_qdisc * rtnl_qdisc_get(struct nl_cache *, int, uint32_t); extern struct rtnl_qdisc * rtnl_qdisc_get_by_parent(struct nl_cache *, int, uint32_t); extern int rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int, struct nl_msg **); extern int rtnl_qdisc_add(struct nl_sock *, struct rtnl_qdisc *, int); extern int rtnl_qdisc_build_update_request(struct rtnl_qdisc *, struct rtnl_qdisc *, int, struct nl_msg **); extern int rtnl_qdisc_update(struct nl_sock *, struct rtnl_qdisc *, struct rtnl_qdisc *, int); extern int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *, struct nl_msg **); extern int rtnl_qdisc_delete(struct nl_sock *, struct rtnl_qdisc *); /* Deprecated functions */ extern void rtnl_qdisc_foreach_child(struct rtnl_qdisc *, struct nl_cache *, void (*cb)(struct nl_object *, void *), void *) __attribute__ ((deprecated)); extern void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *, struct nl_cache *, void (*cb)(struct nl_object *, void *), void *) __attribute__ ((deprecated)); extern int rtnl_qdisc_build_change_request(struct rtnl_qdisc *, struct rtnl_qdisc *, struct nl_msg **) __attribute__ ((deprecated)); extern int rtnl_qdisc_change(struct nl_sock *, struct rtnl_qdisc *, struct rtnl_qdisc *) __attribute__ ((deprecated)); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/0000755000175000017500000000000013031473756014727 500000000000000libnl-3.2.29/include/netlink/route/cls/ematch/0000755000175000017500000000000013031473756016170 500000000000000libnl-3.2.29/include/netlink/route/cls/ematch/nbyte.h0000644000175000017500000000203513023014600017356 00000000000000/* * netlink/route/cls/ematch/nbyte.h N-Byte Comparison * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #ifndef NETLINK_CLS_EMATCH_NBYTE_H_ #define NETLINK_CLS_EMATCH_NBYTE_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_ematch_nbyte_set_offset(struct rtnl_ematch *, uint8_t, uint16_t); extern uint16_t rtnl_ematch_nbyte_get_offset(struct rtnl_ematch *); extern uint8_t rtnl_ematch_nbyte_get_layer(struct rtnl_ematch *); extern void rtnl_ematch_nbyte_set_pattern(struct rtnl_ematch *, uint8_t *, size_t); extern uint8_t * rtnl_ematch_nbyte_get_pattern(struct rtnl_ematch *); extern size_t rtnl_ematch_nbyte_get_len(struct rtnl_ematch *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/ematch/meta.h0000644000175000017500000000223513023014600017165 00000000000000/* * netlink/route/cls/ematch/meta.h Metadata Match * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #ifndef NETLINK_CLS_EMATCH_META_H_ #define NETLINK_CLS_EMATCH_META_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_meta_value; extern struct rtnl_meta_value * rtnl_meta_value_alloc_int(uint64_t); extern struct rtnl_meta_value * rtnl_meta_value_alloc_var(void *, size_t); extern struct rtnl_meta_value * rtnl_meta_value_alloc_id(uint8_t, uint16_t, uint8_t, uint64_t); extern void rtnl_meta_value_put(struct rtnl_meta_value *); extern void rtnl_ematch_meta_set_lvalue(struct rtnl_ematch *, struct rtnl_meta_value *); void rtnl_ematch_meta_set_rvalue(struct rtnl_ematch *, struct rtnl_meta_value *); extern void rtnl_ematch_meta_set_operand(struct rtnl_ematch *, uint8_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/ematch/text.h0000644000175000017500000000255313023014600017226 00000000000000/* * netlink/route/cls/ematch/text.h Text Search * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #ifndef NETLINK_CLS_EMATCH_TEXT_H_ #define NETLINK_CLS_EMATCH_TEXT_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_ematch_text_set_from(struct rtnl_ematch *, uint8_t, uint16_t); extern uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *); extern uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *); extern void rtnl_ematch_text_set_to(struct rtnl_ematch *, uint8_t, uint16_t); extern uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *); extern uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *); extern void rtnl_ematch_text_set_pattern(struct rtnl_ematch *, char *, size_t); extern char * rtnl_ematch_text_get_pattern(struct rtnl_ematch *); extern size_t rtnl_ematch_text_get_len(struct rtnl_ematch *); extern void rtnl_ematch_text_set_algo(struct rtnl_ematch *, const char *); extern char * rtnl_ematch_text_get_algo(struct rtnl_ematch *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/ematch/cmp.h0000644000175000017500000000135013023014600017013 00000000000000/* * netlink/route/cls/ematch/cmp.h Simple Comparison * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2010 Thomas Graf */ #ifndef NETLINK_CLS_EMATCH_CMP_H_ #define NETLINK_CLS_EMATCH_CMP_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_ematch_cmp_set(struct rtnl_ematch *, struct tcf_em_cmp *); extern struct tcf_em_cmp * rtnl_ematch_cmp_get(struct rtnl_ematch *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/fw.h0000644000175000017500000000134513023014600015413 00000000000000/* * netlink/route/cls/fw.h fw classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf * Copyright (c) 2006 Petr Gotthard * Copyright (c) 2006 Siemens AG Oesterreich */ #ifndef NETLINK_FW_H_ #define NETLINK_FW_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_fw_set_classid(struct rtnl_cls *, uint32_t); extern int rtnl_fw_set_mask(struct rtnl_cls *, uint32_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/ematch.h0000644000175000017500000000555313023014600016245 00000000000000/* * netlink/route/cls/ematch.h Extended Matches * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2010 Thomas Graf */ #ifndef NETLINK_CLS_EMATCH_H_ #define NETLINK_CLS_EMATCH_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* FIXME: Should be moved to the kernel header at some point */ #define RTNL_EMATCH_PROGID 2 struct rtnl_ematch; struct rtnl_ematch_tree; /** * Extended Match Operations */ struct rtnl_ematch_ops { int eo_kind; const char * eo_name; size_t eo_minlen; size_t eo_datalen; int (*eo_parse)(struct rtnl_ematch *, void *, size_t); void (*eo_dump)(struct rtnl_ematch *, struct nl_dump_params *); int (*eo_fill)(struct rtnl_ematch *, struct nl_msg *); void (*eo_free)(struct rtnl_ematch *); struct nl_list_head eo_list; }; extern int rtnl_ematch_register(struct rtnl_ematch_ops *); extern struct rtnl_ematch_ops * rtnl_ematch_lookup_ops(int); extern struct rtnl_ematch_ops * rtnl_ematch_lookup_ops_by_name(const char *); extern struct rtnl_ematch * rtnl_ematch_alloc(void); extern int rtnl_ematch_add_child(struct rtnl_ematch *, struct rtnl_ematch *); extern void rtnl_ematch_unlink(struct rtnl_ematch *); extern void rtnl_ematch_free(struct rtnl_ematch *); extern void * rtnl_ematch_data(struct rtnl_ematch *); extern void rtnl_ematch_set_flags(struct rtnl_ematch *, uint16_t); extern void rtnl_ematch_unset_flags(struct rtnl_ematch *, uint16_t); extern uint16_t rtnl_ematch_get_flags(struct rtnl_ematch *); extern int rtnl_ematch_set_ops(struct rtnl_ematch *, struct rtnl_ematch_ops *); extern int rtnl_ematch_set_kind(struct rtnl_ematch *, uint16_t); extern int rtnl_ematch_set_name(struct rtnl_ematch *, const char *); extern struct rtnl_ematch_tree *rtnl_ematch_tree_alloc(uint16_t); extern void rtnl_ematch_tree_free(struct rtnl_ematch_tree *); extern void rtnl_ematch_tree_add(struct rtnl_ematch_tree *, struct rtnl_ematch *); extern int rtnl_ematch_parse_attr(struct nlattr *, struct rtnl_ematch_tree **); extern int rtnl_ematch_fill_attr(struct nl_msg *, int, struct rtnl_ematch_tree *); extern void rtnl_ematch_tree_dump(struct rtnl_ematch_tree *, struct nl_dump_params *); extern int rtnl_ematch_parse_expr(const char *, char **, struct rtnl_ematch_tree **); extern char * rtnl_ematch_offset2txt(uint8_t, uint16_t, char *, size_t); extern char * rtnl_ematch_opnd2txt(uint8_t, char *, size_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/police.h0000644000175000017500000000113612505607054016267 00000000000000/* * netlink/route/cls/police.h Policer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_CLS_POLICE_H_ #define NETLINK_CLS_POLICE_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern char * nl_police2str(int, char *, size_t); extern int nl_str2police(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/cgroup.h0000644000175000017500000000140113023014600016267 00000000000000/* * netlink/route/cls/cgroup.h Control Groups Classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2009-2010 Thomas Graf */ #ifndef NETLINK_CLS_CGROUP_H_ #define NETLINK_CLS_CGROUP_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_cgroup_set_ematch(struct rtnl_cls *, struct rtnl_ematch_tree *); struct rtnl_ematch_tree * rtnl_cgroup_get_ematch(struct rtnl_cls *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/u32.h0000644000175000017500000000415713023014600015414 00000000000000/* * netlink/route/cls/u32.h u32 classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_U32_H_ #define NETLINK_U32_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_u32_set_handle(struct rtnl_cls *, int, int, int); extern int rtnl_u32_set_classid(struct rtnl_cls *, uint32_t); extern int rtnl_u32_get_classid(struct rtnl_cls *, uint32_t *); extern int rtnl_u32_set_divisor(struct rtnl_cls *, uint32_t); extern int rtnl_u32_set_link(struct rtnl_cls *, uint32_t); extern int rtnl_u32_set_hashtable(struct rtnl_cls *, uint32_t); extern int rtnl_u32_set_hashmask(struct rtnl_cls *, uint32_t, uint32_t); extern int rtnl_u32_set_selector(struct rtnl_cls *, int, uint32_t, char, uint16_t, char); extern int rtnl_u32_set_cls_terminal(struct rtnl_cls *); extern int rtnl_u32_set_flags(struct rtnl_cls *, int); extern int rtnl_u32_add_mark(struct rtnl_cls *, uint32_t, uint32_t); extern int rtnl_u32_del_mark(struct rtnl_cls *); extern int rtnl_u32_add_key(struct rtnl_cls *, uint32_t, uint32_t, int, int); extern int rtnl_u32_get_key(struct rtnl_cls *, uint8_t, uint32_t *, uint32_t *, int *, int *); extern int rtnl_u32_add_key_uint8(struct rtnl_cls *, uint8_t, uint8_t, int, int); extern int rtnl_u32_add_key_uint16(struct rtnl_cls *, uint16_t, uint16_t, int, int); extern int rtnl_u32_add_key_uint32(struct rtnl_cls *, uint32_t, uint32_t, int, int); extern int rtnl_u32_add_key_in_addr(struct rtnl_cls *, const struct in_addr *, uint8_t, int, int); extern int rtnl_u32_add_key_in6_addr(struct rtnl_cls *, const struct in6_addr *, uint8_t, int, int); extern int rtnl_u32_add_action(struct rtnl_cls *, struct rtnl_act *); extern int rtnl_u32_del_action(struct rtnl_cls *, struct rtnl_act *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/cls/basic.h0000644000175000017500000000201413023014600016052 00000000000000/* * netlink/route/cls/basic.h Basic Classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2010 Thomas Graf */ #ifndef NETLINK_BASIC_H_ #define NETLINK_BASIC_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_basic_set_target(struct rtnl_cls *, uint32_t); extern uint32_t rtnl_basic_get_target(struct rtnl_cls *); extern void rtnl_basic_set_ematch(struct rtnl_cls *, struct rtnl_ematch_tree *); extern struct rtnl_ematch_tree *rtnl_basic_get_ematch(struct rtnl_cls *); extern int rtnl_basic_add_action(struct rtnl_cls *, struct rtnl_act *); extern int rtnl_basic_del_action(struct rtnl_cls *, struct rtnl_act *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/class.h0000644000175000017500000000331013023014600015315 00000000000000/* * netlink/route/class.h Traffic Classes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_CLASS_H_ #define NETLINK_CLASS_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_class; extern struct rtnl_class * rtnl_class_alloc(void); extern void rtnl_class_put(struct rtnl_class *); extern int rtnl_class_alloc_cache(struct nl_sock *, int, struct nl_cache **); extern struct rtnl_class * rtnl_class_get(struct nl_cache *, int, uint32_t); extern struct rtnl_qdisc * rtnl_class_leaf_qdisc(struct rtnl_class *, struct nl_cache *); extern int rtnl_class_build_add_request(struct rtnl_class *, int, struct nl_msg **); extern int rtnl_class_add(struct nl_sock *, struct rtnl_class *, int); extern int rtnl_class_build_delete_request(struct rtnl_class *, struct nl_msg **); extern int rtnl_class_delete(struct nl_sock *, struct rtnl_class *); /* deprecated functions */ extern void rtnl_class_foreach_child(struct rtnl_class *, struct nl_cache *, void (*cb)(struct nl_object *, void *), void *) __attribute__((deprecated)); extern void rtnl_class_foreach_cls(struct rtnl_class *, struct nl_cache *, void (*cb)(struct nl_object *, void *), void *) __attribute__((deprecated)); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/0000755000175000017500000000000013031473756015103 500000000000000libnl-3.2.29/include/netlink/route/link/ipvlan.h0000644000175000017500000000165513023014600016450 00000000000000/* * netlink/route/link/ipvlan.h IPVLAN interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2015 Cong Wang */ #ifndef NETLINK_LINK_IPVLAN_H_ #define NETLINK_LINK_IPVLAN_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_ipvlan_alloc(void); extern int rtnl_link_is_ipvlan(struct rtnl_link *); extern char * rtnl_link_ipvlan_mode2str(int, char *, size_t); extern int rtnl_link_ipvlan_str2mode(const char *); extern int rtnl_link_ipvlan_set_mode(struct rtnl_link *, uint16_t); extern int rtnl_link_ipvlan_get_mode(struct rtnl_link *, uint16_t *out_mode); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/inet.h0000644000175000017500000000144213023014600016110 00000000000000/* * netlink/route/link/inet.h INET Link Module * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #ifndef NETLINK_LINK_INET_H_ #define NETLINK_LINK_INET_H_ #include #ifdef __cplusplus extern "C" { #endif extern const char * rtnl_link_inet_devconf2str(int, char *, size_t); extern int rtnl_link_inet_str2devconf(const char *); extern int rtnl_link_inet_get_conf(struct rtnl_link *, const unsigned int, uint32_t *); extern int rtnl_link_inet_set_conf(struct rtnl_link *, const unsigned int, uint32_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/inet6.h0000644000175000017500000000176413023014600016205 00000000000000/* * netlink/route/link/inet6.h INET6 Link Module * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Dan Williams */ #ifndef NETLINK_LINK_INET6_H_ #define NETLINK_LINK_INET6_H_ #include #ifdef __cplusplus extern "C" { #endif const char * rtnl_link_inet6_addrgenmode2str (uint8_t mode, char *buf, size_t len); uint8_t rtnl_link_inet6_str2addrgenmode (const char *mode); extern int rtnl_link_inet6_get_token(struct rtnl_link *, struct nl_addr **); extern int rtnl_link_inet6_set_token(struct rtnl_link *, struct nl_addr *); extern int rtnl_link_inet6_get_addr_gen_mode(struct rtnl_link *, uint8_t *); extern int rtnl_link_inet6_set_addr_gen_mode(struct rtnl_link *, uint8_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/macvtap.h0000644000175000017500000000276413023014600016614 00000000000000/* * netlink/route/link/macvtap.h MACVTAP interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2015 Beniamino Galvani */ #ifndef NETLINK_LINK_MACVTAP_H_ #define NETLINK_LINK_MACVTAP_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_macvtap_alloc(void); extern int rtnl_link_is_macvtap(struct rtnl_link *); extern char * rtnl_link_macvtap_mode2str(int, char *, size_t); extern int rtnl_link_macvtap_str2mode(const char *); extern char * rtnl_link_macvtap_flags2str(int, char *, size_t); extern int rtnl_link_macvtap_str2flags(const char *); extern int rtnl_link_macvtap_set_mode(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_macvtap_get_mode(struct rtnl_link *); extern int rtnl_link_macvtap_set_flags(struct rtnl_link *, uint16_t); extern int rtnl_link_macvtap_unset_flags(struct rtnl_link *, uint16_t); extern uint16_t rtnl_link_macvtap_get_flags(struct rtnl_link *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/info-api.h0000644000175000017500000000106413023014600016653 00000000000000/* * netlink/route/link/info-api.h Link Modules API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #ifndef NETLINK_DUMMY_LINK_INFO_API_H_ #define NETLINK_DUMMY_LINK_INFO_API_H_ #include #include #warning "You are including a deprecated header file, include ." #endif libnl-3.2.29/include/netlink/route/link/ip6tnl.h0000644000175000017500000000413013023014600016362 00000000000000/* * netlink/route/link/ip6tnl.h IP6TNL interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ #ifndef NETLINK_LINK_IP6TNL_H_ #define NETLINK_LINK_IP6TNL_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_ip6_tnl_alloc(void); extern int rtnl_link_ip6_tnl_add(struct nl_sock *sk, const char *name); extern int rtnl_link_is_ip6_tnl(struct rtnl_link *link); extern int rtnl_link_ip6_tnl_set_link(struct rtnl_link *link, uint32_t index); extern uint32_t rtnl_link_ip6_tnl_get_link(struct rtnl_link *link); extern int rtnl_link_ip6_tnl_set_local(struct rtnl_link *link, struct in6_addr *); extern int rtnl_link_ip6_tnl_get_local(struct rtnl_link *link, struct in6_addr *addr); extern int rtnl_link_ip6_tnl_set_remote(struct rtnl_link *link, struct in6_addr *); extern int rtnl_link_ip6_tnl_get_remote(struct rtnl_link *link, struct in6_addr *); extern int rtnl_link_ip6_tnl_set_ttl(struct rtnl_link *link, uint8_t ttl); extern uint8_t rtnl_link_ip6_tnl_get_ttl(struct rtnl_link *link); extern int rtnl_link_ip6_tnl_set_tos(struct rtnl_link *link, uint8_t tos); extern uint8_t rtnl_link_ip6_tnl_get_tos(struct rtnl_link *link); extern int rtnl_link_ip6_tnl_set_encaplimit(struct rtnl_link *link, uint8_t encap_limit); extern uint8_t rtnl_link_ip6_tnl_get_encaplimit(struct rtnl_link *link); extern int rtnl_link_ip6_tnl_set_flags(struct rtnl_link *link, uint32_t flags); extern uint32_t rtnl_link_ip6_tnl_get_flags(struct rtnl_link *link); extern uint32_t rtnl_link_ip6_tnl_get_flowinfo(struct rtnl_link *link); extern int rtnl_link_ip6_tnl_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo); extern int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto); extern uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/ipvti.h0000644000175000017500000000252513023014600016307 00000000000000/* * netlink/route/link/ipvti.h IPVTI interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ #ifndef NETLINK_LINK_IPVTI_H_ #define NETLINK_LINK_IPVTI_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_ipvti_alloc(void); extern int rtnl_link_ipvti_add(struct nl_sock *sk, const char *name); extern int rtnl_link_ipvti_set_link(struct rtnl_link *link, uint32_t index); extern uint32_t rtnl_link_ipvti_get_link(struct rtnl_link *link); extern int rtnl_link_ipvti_set_ikey(struct rtnl_link *link, uint32_t ikey); extern uint32_t rtnl_link_get_ikey(struct rtnl_link *link); extern int rtnl_link_ipvti_set_okey(struct rtnl_link *link, uint32_t okey); extern uint32_t rtnl_link_get_okey(struct rtnl_link *link); extern int rtnl_link_ipvti_set_local(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_get_local(struct rtnl_link *link); extern int rtnl_link_ipvti_set_remote(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_get_remote(struct rtnl_link *link); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/macvlan.h0000644000175000017500000000376613023014600016605 00000000000000/* * netlink/route/link/macvlan.h MACVLAN interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Michael Braun */ #ifndef NETLINK_LINK_MACVLAN_H_ #define NETLINK_LINK_MACVLAN_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_macvlan_alloc(void); extern int rtnl_link_is_macvlan(struct rtnl_link *); extern char * rtnl_link_macvlan_mode2str(int, char *, size_t); extern int rtnl_link_macvlan_str2mode(const char *); extern char * rtnl_link_macvlan_flags2str(int, char *, size_t); extern int rtnl_link_macvlan_str2flags(const char *); extern char * rtnl_link_macvlan_macmode2str(int, char *, size_t); extern int rtnl_link_macvlan_str2macmode(const char *); extern int rtnl_link_macvlan_set_mode(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_macvlan_get_mode(struct rtnl_link *); extern int rtnl_link_macvlan_set_flags(struct rtnl_link *, uint16_t); extern int rtnl_link_macvlan_unset_flags(struct rtnl_link *, uint16_t); extern uint16_t rtnl_link_macvlan_get_flags(struct rtnl_link *); extern int rtnl_link_macvlan_set_macmode(struct rtnl_link *, uint32_t); extern int rtnl_link_macvlan_get_macmode(struct rtnl_link *link, uint32_t *out_macmode); extern int rtnl_link_macvlan_count_macaddr(struct rtnl_link *link, uint32_t *out_count); extern int rtnl_link_macvlan_get_macaddr(struct rtnl_link *link, uint32_t idx, const struct nl_addr **addr); extern int rtnl_link_macvlan_add_macaddr(struct rtnl_link *link, struct nl_addr *addr); extern int rtnl_link_macvlan_del_macaddr(struct rtnl_link *link, struct nl_addr *addr); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/ipgre.h0000644000175000017500000000451013023014600016256 00000000000000/* * netlink/route/link/ip_gre.h IPGRE interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ #ifndef NETLINK_LINK_IPGRE_H_ #define NETLINK_LINK_IPGRE_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_link_is_ipgre(struct rtnl_link *link); extern int rtnl_link_is_ipgretap(struct rtnl_link *link); extern struct rtnl_link *rtnl_link_ipgre_alloc(void); extern struct rtnl_link *rtnl_link_ipgretap_alloc(void); extern int rtnl_link_ipgre_add(struct nl_sock *sk, const char *name); extern int rtnl_link_ipgretap_add(struct nl_sock *sk, const char *name); extern int rtnl_link_ipgre_set_link(struct rtnl_link *link, uint32_t index); extern uint32_t rtnl_link_ipgre_get_link(struct rtnl_link *link); extern int rtnl_link_ipgre_set_iflags(struct rtnl_link *link, uint16_t iflags); extern uint16_t rtnl_link_ipgre_get_iflags(struct rtnl_link *link); extern int rtnl_link_ipgre_set_oflags(struct rtnl_link *link, uint16_t oflags); extern uint16_t rtnl_link_ipgre_get_oflags(struct rtnl_link *link); extern int rtnl_link_ipgre_set_ikey(struct rtnl_link *link, uint32_t ikey); extern uint32_t rtnl_link_ipgre_get_ikey(struct rtnl_link *link); extern int rtnl_link_ipgre_set_okey(struct rtnl_link *link, uint32_t okey); extern uint32_t rtnl_link_ipgre_get_okey(struct rtnl_link *link); extern int rtnl_link_ipgre_set_local(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_ipgre_get_local(struct rtnl_link *link); extern int rtnl_link_ipgre_set_remote(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_ipgre_get_remote(struct rtnl_link *link); extern int rtnl_link_ipgre_set_ttl(struct rtnl_link *link, uint8_t ttl); extern uint8_t rtnl_link_ipgre_get_ttl(struct rtnl_link *link); extern int rtnl_link_ipgre_set_tos(struct rtnl_link *link, uint8_t tos); extern uint8_t rtnl_link_ipgre_get_tos(struct rtnl_link *link); extern int rtnl_link_ipgre_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc); extern uint8_t rtnl_link_ipgre_get_pmtudisc(struct rtnl_link *link); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/sit.h0000644000175000017500000000465613023014600015762 00000000000000/* * netlink/route/link/sit.h SIT interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ #ifndef NETLINK_LINK_SIT_H_ #define NETLINK_LINK_SIT_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_sit_alloc(void); extern int rtnl_link_sit_add(struct nl_sock *sk, const char *name); extern int rtnl_link_sit_set_link(struct rtnl_link *link, uint32_t index); extern uint32_t rtnl_link_sit_get_link(struct rtnl_link *link); extern int rtnl_link_sit_set_local(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_get_sit_local(struct rtnl_link *link); extern int rtnl_link_sit_set_remote(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_sit_get_remote(struct rtnl_link *link); extern int rtnl_link_sit_set_ttl(struct rtnl_link *link, uint8_t ttl); extern uint8_t rtnl_link_sit_get_ttl(struct rtnl_link *link); extern int rtnl_link_sit_set_tos(struct rtnl_link *link, uint8_t tos); extern uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link); extern int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc); extern uint8_t rtnl_link_sit_get_pmtudisc(struct rtnl_link *link); extern int rtnl_link_sit_set_flags(struct rtnl_link *link, uint16_t flags); extern uint16_t rtnl_link_sit_get_flags(struct rtnl_link *link); int rtnl_link_sit_set_proto(struct rtnl_link *link, uint8_t proto); uint8_t rtnl_link_sit_get_proto(struct rtnl_link *link); int rtnl_link_sit_set_ip6rd_prefix(struct rtnl_link *link, const struct in6_addr *prefix); int rtnl_link_sit_get_ip6rd_prefix(const struct rtnl_link *link, struct in6_addr *prefix); int rtnl_link_sit_set_ip6rd_prefixlen(struct rtnl_link *link, uint16_t prefixlen); int rtnl_link_sit_get_ip6rd_prefixlen(struct rtnl_link *link, uint16_t *prefixlen); int rtnl_link_sit_set_ip6rd_relay_prefix(struct rtnl_link *link, uint32_t prefix); int rtnl_link_sit_get_ip6rd_relay_prefix(const struct rtnl_link *link, uint32_t *prefix); int rtnl_link_sit_set_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t prefix); int rtnl_link_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *prefix); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/macsec.h0000644000175000017500000000456113023014600016411 00000000000000/* * netlink/route/link/macsec.h MACsec Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Sabrina Dubroca */ #ifndef NETLINK_LINK_MACSEC_H_ #define NETLINK_LINK_MACSEC_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_link *rtnl_link_macsec_alloc(void); int rtnl_link_macsec_set_sci(struct rtnl_link *, uint64_t); int rtnl_link_macsec_get_sci(struct rtnl_link *, uint64_t *); int rtnl_link_macsec_set_port(struct rtnl_link *, uint16_t); int rtnl_link_macsec_get_port(struct rtnl_link *, uint16_t *); int rtnl_link_macsec_set_cipher_suite(struct rtnl_link *, uint64_t); int rtnl_link_macsec_get_cipher_suite(struct rtnl_link *, uint64_t *); int rtnl_link_macsec_set_icv_len(struct rtnl_link *, uint16_t); int rtnl_link_macsec_get_icv_len(struct rtnl_link *, uint16_t *); int rtnl_link_macsec_set_protect(struct rtnl_link *, uint8_t); int rtnl_link_macsec_get_protect(struct rtnl_link *, uint8_t *); int rtnl_link_macsec_set_encrypt(struct rtnl_link *, uint8_t); int rtnl_link_macsec_get_encrypt(struct rtnl_link *, uint8_t *); int rtnl_link_macsec_set_encoding_sa(struct rtnl_link *, uint8_t); int rtnl_link_macsec_get_encoding_sa(struct rtnl_link *, uint8_t *); int rtnl_link_macsec_set_validation_type(struct rtnl_link *, enum macsec_validation_type); int rtnl_link_macsec_get_validation_type(struct rtnl_link *, enum macsec_validation_type *); int rtnl_link_macsec_set_replay_protect(struct rtnl_link *, uint8_t); int rtnl_link_macsec_get_replay_protect(struct rtnl_link *, uint8_t *); int rtnl_link_macsec_set_window(struct rtnl_link *, uint32_t); int rtnl_link_macsec_get_window(struct rtnl_link *, uint32_t *); int rtnl_link_macsec_set_send_sci(struct rtnl_link *, uint8_t); int rtnl_link_macsec_get_send_sci(struct rtnl_link *, uint8_t *); int rtnl_link_macsec_set_end_station(struct rtnl_link *, uint8_t); int rtnl_link_macsec_get_end_station(struct rtnl_link *, uint8_t *); int rtnl_link_macsec_set_scb(struct rtnl_link *, uint8_t); int rtnl_link_macsec_get_scb(struct rtnl_link *, uint8_t *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/ipip.h0000644000175000017500000000301313023014600016106 00000000000000/* * netlink/route/link/ipip.h IPIP interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ #ifndef NETLINK_LINK_IPIP_H_ #define NETLINK_LINK_IPIP_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_ipip_alloc(void); extern int rtnl_link_ipip_add(struct nl_sock *sk, const char *name); extern uint32_t rtnl_link_ipip_get_link(struct rtnl_link *link); extern int rtnl_link_ipip_set_link(struct rtnl_link *link, uint32_t index); extern int rtnl_link_ipip_set_local(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_ipip_get_local(struct rtnl_link *link); extern int rtnl_link_ipip_set_remote(struct rtnl_link *link, uint32_t addr); extern uint32_t rtnl_link_ipip_get_remote(struct rtnl_link *link); extern int rtnl_link_ipip_set_ttl(struct rtnl_link *link, uint8_t ttl); extern uint8_t rtnl_link_ipip_get_ttl(struct rtnl_link *link); extern int rtnl_link_ipip_set_tos(struct rtnl_link *link, uint8_t tos); extern uint8_t rtnl_link_ipip_get_tos(struct rtnl_link *link); extern int rtnl_link_ipip_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc); extern uint8_t rtnl_link_ipip_get_pmtudisc(struct rtnl_link *link); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/can.h0000644000175000017500000000376613023014600015725 00000000000000/* * netlink/route/link/can.h CAN interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Benedikt Spranger */ #ifndef NETLINK_LINK_CAN_H_ #define NETLINK_LINK_CAN_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_link_is_can(struct rtnl_link *link); extern char *rtnl_link_can_ctrlmode2str(int, char *, size_t); extern int rtnl_link_can_str2ctrlmode(const char *); extern int rtnl_link_can_restart(struct rtnl_link *); extern int rtnl_link_can_freq(struct rtnl_link *, uint32_t *); extern int rtnl_link_can_state(struct rtnl_link *, uint32_t *); extern int rtnl_link_can_berr_rx(struct rtnl_link *); extern int rtnl_link_can_berr_tx(struct rtnl_link *); extern int rtnl_link_can_berr(struct rtnl_link *, struct can_berr_counter *); extern int rtnl_link_can_get_bt_const(struct rtnl_link *, struct can_bittiming_const *); extern int rtnl_link_can_get_bittiming(struct rtnl_link *, struct can_bittiming *); extern int rtnl_link_can_set_bittiming(struct rtnl_link *, struct can_bittiming *); extern int rtnl_link_can_get_bitrate(struct rtnl_link *, uint32_t *); extern int rtnl_link_can_set_bitrate(struct rtnl_link *, uint32_t); extern int rtnl_link_can_get_sample_point(struct rtnl_link *, uint32_t *); extern int rtnl_link_can_set_sample_point(struct rtnl_link *, uint32_t); extern int rtnl_link_can_get_restart_ms(struct rtnl_link *, uint32_t *); extern int rtnl_link_can_set_restart_ms(struct rtnl_link *, uint32_t); extern int rtnl_link_can_get_ctrlmode(struct rtnl_link *, uint32_t *); extern int rtnl_link_can_set_ctrlmode(struct rtnl_link *, uint32_t); extern int rtnl_link_can_unset_ctrlmode(struct rtnl_link *, uint32_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/vrf.h0000644000175000017500000000154413023014600015751 00000000000000/* * netlink/route/link/vrf.h VRF interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2015 Cumulus Networks. All rights reserved. * Copyright (c) 2015 David Ahern */ #ifndef NETLINK_LINK_VRF_H_ #define NETLINK_LINK_VRF_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_vrf_alloc(void); extern int rtnl_link_is_vrf(struct rtnl_link *link); extern int rtnl_link_vrf_get_tableid(struct rtnl_link *link, uint32_t *id); extern int rtnl_link_vrf_set_tableid(struct rtnl_link *link, uint32_t id); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/api.h0000644000175000017500000000104513023014600015721 00000000000000/* * netlink/route/link/api.h Link Modules API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #ifndef NETLINK_DUMMY_LINK_API_H_ #define NETLINK_DUMMY_LINK_API_H_ #include #include #warning "You are including a deprecated header file, include ." #endif libnl-3.2.29/include/netlink/route/link/vlan.h0000644000175000017500000000317613023014600016117 00000000000000/* * netlink/route/link/vlan.h VLAN interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #ifndef NETLINK_LINK_VLAN_H_ #define NETLINK_LINK_VLAN_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct vlan_map { uint32_t vm_from; uint32_t vm_to; }; #define VLAN_PRIO_MAX 7 extern struct rtnl_link *rtnl_link_vlan_alloc(void); extern int rtnl_link_is_vlan(struct rtnl_link *); extern char * rtnl_link_vlan_flags2str(int, char *, size_t); extern int rtnl_link_vlan_str2flags(const char *); extern int rtnl_link_vlan_set_protocol(struct rtnl_link *link, uint16_t); extern int rtnl_link_vlan_get_protocol(struct rtnl_link *link); extern int rtnl_link_vlan_set_id(struct rtnl_link *, uint16_t); extern int rtnl_link_vlan_get_id(struct rtnl_link *); extern int rtnl_link_vlan_set_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_vlan_unset_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_vlan_get_flags(struct rtnl_link *); extern int rtnl_link_vlan_set_ingress_map(struct rtnl_link *, int, uint32_t); extern uint32_t * rtnl_link_vlan_get_ingress_map(struct rtnl_link *); extern int rtnl_link_vlan_set_egress_map(struct rtnl_link *, uint32_t, int); extern struct vlan_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *, int *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/bridge.h0000644000175000017500000000573213023014600016413 00000000000000/* * netlink/route/link/bridge.h Bridge * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #ifndef NETLINK_LINK_BRIDGE_H_ #define NETLINK_LINK_BRIDGE_H_ #include #include #ifdef __cplusplus extern "C" { #endif #define RTNL_LINK_BRIDGE_VLAN_BITMAP_MAX 4096 #define RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN (RTNL_LINK_BRIDGE_VLAN_BITMAP_MAX / 32) struct rtnl_link_bridge_vlan { uint16_t pvid; uint32_t vlan_bitmap[RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN]; uint32_t untagged_bitmap[RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN]; }; /** * Bridge flags * @ingroup bridge */ enum rtnl_link_bridge_flags { RTNL_BRIDGE_HAIRPIN_MODE = 0x0001, RTNL_BRIDGE_BPDU_GUARD = 0x0002, RTNL_BRIDGE_ROOT_BLOCK = 0x0004, RTNL_BRIDGE_FAST_LEAVE = 0x0008, RTNL_BRIDGE_UNICAST_FLOOD = 0x0010, RTNL_BRIDGE_LEARNING = 0x0020, RTNL_BRIDGE_LEARNING_SYNC = 0x0040, }; #define RTNL_BRIDGE_HWMODE_VEB BRIDGE_MODE_VEB #define RTNL_BRIDGE_HWMODE_VEPA BRIDGE_MODE_VEPA #define RTNL_BRIDGE_HWMODE_MAX BRIDGE_MODE_VEPA #define RTNL_BRIDGE_HWMODE_UNDEF BRIDGE_MODE_UNDEF extern struct rtnl_link *rtnl_link_bridge_alloc(void); extern int rtnl_link_is_bridge(struct rtnl_link *); extern int rtnl_link_bridge_has_ext_info(struct rtnl_link *); extern int rtnl_link_bridge_set_port_state(struct rtnl_link *, uint8_t ); extern int rtnl_link_bridge_get_port_state(struct rtnl_link *); extern int rtnl_link_bridge_set_priority(struct rtnl_link *, uint16_t); extern int rtnl_link_bridge_get_priority(struct rtnl_link *); extern int rtnl_link_bridge_set_cost(struct rtnl_link *, uint32_t); extern int rtnl_link_bridge_get_cost(struct rtnl_link *, uint32_t *); extern int rtnl_link_bridge_unset_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_set_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_get_flags(struct rtnl_link *); extern int rtnl_link_bridge_set_self(struct rtnl_link *); extern int rtnl_link_bridge_get_hwmode(struct rtnl_link *, uint16_t *); extern int rtnl_link_bridge_set_hwmode(struct rtnl_link *, uint16_t); extern char * rtnl_link_bridge_flags2str(int, char *, size_t); extern int rtnl_link_bridge_str2flags(const char *); extern char * rtnl_link_bridge_portstate2str(int, char *, size_t); extern int rtnl_link_bridge_str2portstate(const char *); extern char * rtnl_link_bridge_hwmode2str(uint16_t, char *, size_t); extern uint16_t rtnl_link_bridge_str2hwmode(const char *); extern int rtnl_link_bridge_add(struct nl_sock *sk, const char *name); extern int rtnl_link_bridge_pvid(struct rtnl_link *link); extern int rtnl_link_bridge_has_vlan(struct rtnl_link *link); extern struct rtnl_link_bridge_vlan *rtnl_link_bridge_get_port_vlan(struct rtnl_link *link); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/ppp.h0000644000175000017500000000130213023014600015743 00000000000000/* * netlink/route/link/ppp.h PPP Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Jonas Johansson */ #ifndef NETLINK_LINK_PPP_H_ #define NETLINK_LINK_PPP_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_ppp_alloc(void); extern int rtnl_link_ppp_set_fd(struct rtnl_link *, int32_t); extern int rtnl_link_ppp_get_fd(struct rtnl_link *, int32_t *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/vxlan.h0000644000175000017500000001142413023014600016302 00000000000000/* * netlink/route/link/vxlan.h VXLAN interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Yasunobu Chiba */ #ifndef NETLINK_LINK_VXLAN_H_ #define NETLINK_LINK_VXLAN_H_ #include #include #ifdef __cplusplus extern "C" { #endif #define VXLAN_ID_MAX 16777215 enum { RTNL_LINK_VXLAN_F_GBP = 1 << 0, #define RTNL_LINK_VXLAN_F_GBP RTNL_LINK_VXLAN_F_GBP RTNL_LINK_VXLAN_F_GPE = 1 << 1, #define RTNL_LINK_VXLAN_F_GPE RTNL_LINK_VXLAN_F_GPE RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL = 1 << 2, #define RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL }; extern struct rtnl_link *rtnl_link_vxlan_alloc(void); extern int rtnl_link_is_vxlan(struct rtnl_link *); extern int rtnl_link_vxlan_set_id(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_id(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_group(struct rtnl_link *, struct nl_addr *); extern int rtnl_link_vxlan_get_group(struct rtnl_link *, struct nl_addr **); extern int rtnl_link_vxlan_set_link(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_link(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_local(struct rtnl_link *, struct nl_addr *); extern int rtnl_link_vxlan_get_local(struct rtnl_link *, struct nl_addr **); extern int rtnl_link_vxlan_set_ttl(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_ttl(struct rtnl_link *); extern int rtnl_link_vxlan_set_tos(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_tos(struct rtnl_link *); extern int rtnl_link_vxlan_set_learning(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_learning(struct rtnl_link *); extern int rtnl_link_vxlan_enable_learning(struct rtnl_link *); extern int rtnl_link_vxlan_disable_learning(struct rtnl_link *); extern int rtnl_link_vxlan_set_ageing(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_ageing(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_limit(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_limit(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_port_range(struct rtnl_link *, struct ifla_vxlan_port_range *); extern int rtnl_link_vxlan_get_port_range(struct rtnl_link *, struct ifla_vxlan_port_range *); extern int rtnl_link_vxlan_set_proxy(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_proxy(struct rtnl_link *); extern int rtnl_link_vxlan_enable_proxy(struct rtnl_link *); extern int rtnl_link_vxlan_disable_proxy(struct rtnl_link *); extern int rtnl_link_vxlan_set_rsc(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_rsc(struct rtnl_link *); extern int rtnl_link_vxlan_enable_rsc(struct rtnl_link *); extern int rtnl_link_vxlan_disable_rsc(struct rtnl_link *); extern int rtnl_link_vxlan_set_l2miss(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_l2miss(struct rtnl_link *); extern int rtnl_link_vxlan_enable_l2miss(struct rtnl_link *); extern int rtnl_link_vxlan_disable_l2miss(struct rtnl_link *); extern int rtnl_link_vxlan_set_l3miss(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_l3miss(struct rtnl_link *); extern int rtnl_link_vxlan_enable_l3miss(struct rtnl_link *); extern int rtnl_link_vxlan_disable_l3miss(struct rtnl_link *); extern int rtnl_link_vxlan_set_port(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_port(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_udp_csum(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_udp_csum(struct rtnl_link *); extern int rtnl_link_vxlan_set_udp_zero_csum6_tx(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_udp_zero_csum6_tx(struct rtnl_link *); extern int rtnl_link_vxlan_set_udp_zero_csum6_rx(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_udp_zero_csum6_rx(struct rtnl_link *); extern int rtnl_link_vxlan_set_remcsum_tx(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_remcsum_tx(struct rtnl_link *); extern int rtnl_link_vxlan_set_remcsum_rx(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_remcsum_rx(struct rtnl_link *); extern int rtnl_link_vxlan_set_flags(struct rtnl_link *, uint32_t flags, int enable); extern int rtnl_link_vxlan_get_flags(struct rtnl_link *, uint32_t *out_flags); extern int rtnl_link_vxlan_set_collect_metadata(struct rtnl_link *, uint8_t); extern int rtnl_link_vxlan_get_collect_metadata(struct rtnl_link *); extern int rtnl_link_vxlan_set_label(struct rtnl_link *, uint32_t); extern int rtnl_link_vxlan_get_label(struct rtnl_link *, uint32_t *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/sriov.h0000644000175000017500000001114613023014600016315 00000000000000/* * include/netlink/route/link/sriov.h SRIOV VF Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Intel Corp. All rights reserved. * Copyright (c) 2016 Jef Oliver */ #ifndef NETLINK_LINK_SRIOV_H_ #define NETLINK_LINK_SRIOV_H_ #include #include #ifdef __cplusplus extern "C" { #endif #define RTNL_VF_GUID_STR_LEN 23 /** * @ingroup sriov */ typedef enum { RTNL_LINK_VF_RATE_API_UNSPEC, /*!< Unspecified API type */ RTNL_LINK_VF_RATE_API_OLD, /*!< Old Rate setting API */ RTNL_LINK_VF_RATE_API_NEW, /*!< New Rate setting API */ __RTNL_LINK_VF_RATE_API_MAX, } rtnl_link_rate_api_t; #define RTNL_LINK_VF_RATE_API_MAX (__RTNL_LINK_VF_RATE_API_MAX - 1) /** * @ingroup sriov */ typedef enum { RTNL_LINK_VF_STATS_RX_PACKETS, /*!< Packets Received */ RTNL_LINK_VF_STATS_TX_PACKETS, /*!< Packets Sent */ RTNL_LINK_VF_STATS_RX_BYTES, /*!< Bytes Recieved */ RTNL_LINK_VF_STATS_TX_BYTES, /*!< Bytes Sent */ RTNL_LINK_VF_STATS_BROADCAST, /*!< Broadcast packets received */ RTNL_LINK_VF_STATS_MULTICAST, /*!< Multicast packets received */ __RTNL_LINK_VF_STATS_MAX, } rtnl_link_vf_stats_t; #define RTNL_LINK_VF_STATS_MAX (__RTNL_LINK_VF_STATS_MAX - 1) /** * @struct rtnl_link_vf sriov.h "netlink/route/link/sriov.h" * @brief SRIOV VF object * @ingroup sriov * * @copydoc private_struct */ struct rtnl_link_vf; /** * @brief SRIOV VF VFLAN settings * @ingroup sriov */ typedef struct nl_vf_vlan_info { uint32_t vf_vlan; /*!< VLAN number */ uint32_t vf_vlan_qos; /*!< VLAN QOS value */ uint16_t vf_vlan_proto; /*!< VLAN protocol */ } nl_vf_vlan_info_t; /** * @brief SRIOV VF VLANs information * @ingroup sriov */ typedef struct nl_vf_vlans { int ce_refcnt; /*!< Reference counter. Don't change this value */ int size; /*!< Number of VLANs on the SRIOV VF */ nl_vf_vlan_info_t * vlans; /*!< nl_vf_vlan_info_t array of SRIOV VF VLANs */ } nl_vf_vlans_t; /** * @brief VF Rate information structure * @ingroup sriov */ struct nl_vf_rate { int api; /*!< rtnl_link_rate_api_t API Version to use */ uint32_t rate; /*!< Old API Max Rate in Mbps */ uint32_t max_tx_rate; /*!< New API Max Rate in Mbps */ uint32_t min_tx_rate; /*!< New API Mix Rate in Mbps */ }; extern int rtnl_link_vf_add(struct rtnl_link *, struct rtnl_link_vf *); extern struct rtnl_link_vf *rtnl_link_vf_alloc(void); extern void rtnl_link_vf_free(struct rtnl_link_vf *); extern struct rtnl_link_vf *rtnl_link_vf_get(struct rtnl_link *, uint32_t); extern void rtnl_link_vf_put(struct rtnl_link_vf *); extern int rtnl_link_vf_get_addr(struct rtnl_link_vf *, struct nl_addr **); extern void rtnl_link_vf_set_addr(struct rtnl_link_vf *, struct nl_addr *); extern void rtnl_link_vf_set_ib_node_guid(struct rtnl_link_vf *, uint64_t); extern void rtnl_link_vf_set_ib_port_guid(struct rtnl_link_vf *, uint64_t); extern int rtnl_link_vf_get_index(struct rtnl_link_vf *, uint32_t *); extern void rtnl_link_vf_set_index(struct rtnl_link_vf *, uint32_t); extern int rtnl_link_vf_get_linkstate(struct rtnl_link_vf *, uint32_t *); extern void rtnl_link_vf_set_linkstate(struct rtnl_link_vf *, uint32_t); extern int rtnl_link_vf_get_rate(struct rtnl_link_vf *, struct nl_vf_rate *); extern void rtnl_link_vf_set_rate(struct rtnl_link_vf *, struct nl_vf_rate *); extern int rtnl_link_vf_get_rss_query_en(struct rtnl_link_vf *, uint32_t *); extern void rtnl_link_vf_set_rss_query_en(struct rtnl_link_vf *, uint32_t); extern int rtnl_link_vf_get_spoofchk(struct rtnl_link_vf *, uint32_t *); extern void rtnl_link_vf_set_spoofchk(struct rtnl_link_vf *, uint32_t); extern int rtnl_link_vf_get_stat(struct rtnl_link_vf *, rtnl_link_vf_stats_t, uint64_t *); extern int rtnl_link_vf_get_trust(struct rtnl_link_vf *, uint32_t *); extern void rtnl_link_vf_set_trust(struct rtnl_link_vf *, uint32_t); extern int rtnl_link_vf_get_vlans(struct rtnl_link_vf *, nl_vf_vlans_t **); extern void rtnl_link_vf_set_vlans(struct rtnl_link_vf *, nl_vf_vlans_t *); extern int rtnl_link_vf_vlan_alloc(nl_vf_vlans_t **, int); extern void rtnl_link_vf_vlan_put(nl_vf_vlans_t *); /* Utility functions */ extern char *rtnl_link_vf_linkstate2str(uint32_t, char *, size_t); extern int rtnl_link_vf_str2linkstate(const char *); extern char *rtnl_link_vf_vlanproto2str(uint16_t, char *, size_t); extern int rtnl_link_vf_str2vlanproto(const char *); extern int rtnl_link_vf_str2guid(uint64_t *, const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/bonding.h0000644000175000017500000000174713023014600016601 00000000000000/* * netlink/route/link/bonding.h Bonding Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2011-2013 Thomas Graf */ #ifndef NETLINK_LINK_BONDING_H_ #define NETLINK_LINK_BONDING_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_bond_alloc(void); extern int rtnl_link_bond_add(struct nl_sock *, const char *, struct rtnl_link *); extern int rtnl_link_bond_enslave_ifindex(struct nl_sock *, int, int); extern int rtnl_link_bond_enslave(struct nl_sock *, struct rtnl_link *, struct rtnl_link *); extern int rtnl_link_bond_release_ifindex(struct nl_sock *, int); extern int rtnl_link_bond_release(struct nl_sock *, struct rtnl_link *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link/veth.h0000644000175000017500000000157513023014600016126 00000000000000/* * netlink/route/link/veth.h VETH interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ #ifndef NETLINK_LINK_VETH_H_ #define NETLINK_LINK_VETH_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_link *rtnl_link_veth_alloc(void); extern void rtnl_link_veth_release(struct rtnl_link *); extern int rtnl_link_is_veth(struct rtnl_link *); extern struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *); extern int rtnl_link_veth_add(struct nl_sock *sock, const char *name, const char *peer, pid_t pid); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/addr.h0000644000175000017500000000661213023014600015132 00000000000000/* * netlink/route/addr.c rtnetlink addr layer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf * Copyright (c) 2003-2006 Baruch Even , * Mediatrix Telecom, inc. */ #ifndef NETADDR_ADDR_H_ #define NETADDR_ADDR_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_addr; /* General */ extern struct rtnl_addr *rtnl_addr_alloc(void); extern void rtnl_addr_put(struct rtnl_addr *); extern int rtnl_addr_alloc_cache(struct nl_sock *, struct nl_cache **); extern struct rtnl_addr * rtnl_addr_get(struct nl_cache *, int, struct nl_addr *); extern int rtnl_addr_build_add_request(struct rtnl_addr *, int, struct nl_msg **); extern int rtnl_addr_add(struct nl_sock *, struct rtnl_addr *, int); extern int rtnl_addr_build_delete_request(struct rtnl_addr *, int, struct nl_msg **); extern int rtnl_addr_delete(struct nl_sock *, struct rtnl_addr *, int); extern char * rtnl_addr_flags2str(int, char *, size_t); extern int rtnl_addr_str2flags(const char *); extern int rtnl_addr_set_label(struct rtnl_addr *, const char *); extern char * rtnl_addr_get_label(struct rtnl_addr *); extern void rtnl_addr_set_ifindex(struct rtnl_addr *, int); extern int rtnl_addr_get_ifindex(struct rtnl_addr *); extern void rtnl_addr_set_link(struct rtnl_addr *, struct rtnl_link *); extern struct rtnl_link * rtnl_addr_get_link(struct rtnl_addr *); extern void rtnl_addr_set_family(struct rtnl_addr *, int); extern int rtnl_addr_get_family(struct rtnl_addr *); extern void rtnl_addr_set_prefixlen(struct rtnl_addr *, int); extern int rtnl_addr_get_prefixlen(struct rtnl_addr *); extern void rtnl_addr_set_scope(struct rtnl_addr *, int); extern int rtnl_addr_get_scope(struct rtnl_addr *); extern void rtnl_addr_set_flags(struct rtnl_addr *, unsigned int); extern void rtnl_addr_unset_flags(struct rtnl_addr *, unsigned int); extern unsigned int rtnl_addr_get_flags(struct rtnl_addr *); extern int rtnl_addr_set_local(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *); extern int rtnl_addr_set_peer(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *); extern int rtnl_addr_set_broadcast(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *); extern int rtnl_addr_set_multicast(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *); extern int rtnl_addr_set_anycast(struct rtnl_addr *, struct nl_addr *); extern struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *); extern uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *); extern void rtnl_addr_set_valid_lifetime(struct rtnl_addr *, uint32_t); extern uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *); extern void rtnl_addr_set_preferred_lifetime(struct rtnl_addr *, uint32_t); extern uint32_t rtnl_addr_get_create_time(struct rtnl_addr *); extern uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/classifier.h0000644000175000017500000000275513023014600016350 00000000000000/* * netlink/route/classifier.h Classifiers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_CLASSIFIER_H_ #define NETLINK_CLASSIFIER_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_cls *rtnl_cls_alloc(void); extern void rtnl_cls_put(struct rtnl_cls *); extern int rtnl_cls_alloc_cache(struct nl_sock *, int, uint32_t, struct nl_cache **); extern int rtnl_cls_build_add_request(struct rtnl_cls *, int, struct nl_msg **); extern int rtnl_cls_add(struct nl_sock *, struct rtnl_cls *, int); extern int rtnl_cls_change(struct nl_sock *, struct rtnl_cls *, int); extern int rtnl_cls_build_change_request(struct rtnl_cls *, int, struct nl_msg **); extern int rtnl_cls_build_delete_request(struct rtnl_cls *, int, struct nl_msg **); extern int rtnl_cls_delete(struct nl_sock *, struct rtnl_cls *, int); extern void rtnl_cls_set_prio(struct rtnl_cls *, uint16_t); extern uint16_t rtnl_cls_get_prio(struct rtnl_cls *); extern void rtnl_cls_set_protocol(struct rtnl_cls *, uint16_t); extern uint16_t rtnl_cls_get_protocol(struct rtnl_cls *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/action.h0000644000175000017500000000277113023014600015477 00000000000000/* * netlink/route/action.h Actions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ #ifndef NETLINK_ACTION_H_ #define NETLINK_ACTION_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern struct rtnl_act *rtnl_act_alloc(void); extern void rtnl_act_get(struct rtnl_act *); extern void rtnl_act_put(struct rtnl_act *); extern int rtnl_act_build_add_request(struct rtnl_act *, int, struct nl_msg **); extern int rtnl_act_add(struct nl_sock *, struct rtnl_act *, int); extern int rtnl_act_change(struct nl_sock *, struct rtnl_act *, int); extern int rtnl_act_build_change_request(struct rtnl_act *, int, struct nl_msg **); extern int rtnl_act_build_delete_request(struct rtnl_act *, int, struct nl_msg **); extern int rtnl_act_delete(struct nl_sock *, struct rtnl_act *, int); extern int rtnl_act_append(struct rtnl_act **, struct rtnl_act *); extern int rtnl_act_remove(struct rtnl_act **, struct rtnl_act *); extern int rtnl_act_fill(struct nl_msg *, int, struct rtnl_act *); extern void rtnl_act_put_all(struct rtnl_act **); extern int rtnl_act_parse(struct rtnl_act **, struct nlattr *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/neighbour.h0000644000175000017500000000551713023014600016205 00000000000000/* * netlink/route/neighbour.h Neighbours * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_NEIGHBOUR_H_ #define NETLINK_NEIGHBOUR_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_neigh; extern struct rtnl_neigh *rtnl_neigh_alloc(void); extern void rtnl_neigh_put(struct rtnl_neigh *); extern int rtnl_neigh_alloc_cache(struct nl_sock *, struct nl_cache **); extern int rtnl_neigh_alloc_cache_flags(struct nl_sock *, struct nl_cache **, unsigned int); extern struct rtnl_neigh *rtnl_neigh_get(struct nl_cache *, int, struct nl_addr *); extern struct rtnl_neigh *rtnl_neigh_get_by_vlan(struct nl_cache *, int, struct nl_addr *, int); extern int rtnl_neigh_parse(struct nlmsghdr *, struct rtnl_neigh **); extern char * rtnl_neigh_state2str(int, char *, size_t); extern int rtnl_neigh_str2state(const char *); extern char * rtnl_neigh_flags2str(int, char *, size_t); extern int rtnl_neigh_str2flag(const char *); extern int rtnl_neigh_add(struct nl_sock *, struct rtnl_neigh *, int); extern int rtnl_neigh_build_add_request(struct rtnl_neigh *, int, struct nl_msg **); extern int rtnl_neigh_delete(struct nl_sock *, struct rtnl_neigh *, int); extern int rtnl_neigh_build_delete_request(struct rtnl_neigh *, int, struct nl_msg **); extern void rtnl_neigh_set_state(struct rtnl_neigh *, int); extern int rtnl_neigh_get_state(struct rtnl_neigh *); extern void rtnl_neigh_unset_state(struct rtnl_neigh *, int); extern void rtnl_neigh_set_flags(struct rtnl_neigh *, unsigned int); extern void rtnl_neigh_unset_flags(struct rtnl_neigh *, unsigned int); extern unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *); extern void rtnl_neigh_set_ifindex(struct rtnl_neigh *, int); extern int rtnl_neigh_get_ifindex(struct rtnl_neigh *); extern void rtnl_neigh_set_lladdr(struct rtnl_neigh *, struct nl_addr *); extern struct nl_addr * rtnl_neigh_get_lladdr(struct rtnl_neigh *); extern int rtnl_neigh_set_dst(struct rtnl_neigh *, struct nl_addr *); extern struct nl_addr * rtnl_neigh_get_dst(struct rtnl_neigh *); extern void rtnl_neigh_set_type(struct rtnl_neigh *, int); extern int rtnl_neigh_get_type(struct rtnl_neigh *); extern void rtnl_neigh_set_family(struct rtnl_neigh *, int); extern int rtnl_neigh_get_family(struct rtnl_neigh *); extern void rtnl_neigh_set_vlan(struct rtnl_neigh *, int); extern int rtnl_neigh_get_vlan(struct rtnl_neigh *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/link.h0000644000175000017500000002576513023014600015167 00000000000000/* * netlink/route/link.h Links (Interfaces) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_LINK_H_ #define NETLINK_LINK_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @struct rtnl_link link.h "netlink/route/link.h" * @brief Link object * @implements nl_object * @ingroup link * * @copydoc private_struct */ struct rtnl_link; /** * @ingroup link */ typedef enum { RTNL_LINK_RX_PACKETS, /*!< Packets received */ RTNL_LINK_TX_PACKETS, /*!< Packets sent */ RTNL_LINK_RX_BYTES, /*!< Bytes received */ RTNL_LINK_TX_BYTES, /*!< Bytes sent */ RTNL_LINK_RX_ERRORS, /*!< Receive errors */ RTNL_LINK_TX_ERRORS, /*!< Send errors */ RTNL_LINK_RX_DROPPED, /*!< Received packets dropped */ RTNL_LINK_TX_DROPPED, /*!< Packets dropped during transmit */ RTNL_LINK_RX_COMPRESSED, /*!< Compressed packets received */ RTNL_LINK_TX_COMPRESSED, /*!< Compressed packets sent */ RTNL_LINK_RX_FIFO_ERR, /*!< Receive FIFO errors */ RTNL_LINK_TX_FIFO_ERR, /*!< Send FIFO errors */ RTNL_LINK_RX_LEN_ERR, /*!< Length errors */ RTNL_LINK_RX_OVER_ERR, /*!< Over errors */ RTNL_LINK_RX_CRC_ERR, /*!< CRC errors */ RTNL_LINK_RX_FRAME_ERR, /*!< Frame errors */ RTNL_LINK_RX_MISSED_ERR, /*!< Missed errors */ RTNL_LINK_TX_ABORT_ERR, /*!< Aborted errors */ RTNL_LINK_TX_CARRIER_ERR, /*!< Carrier errors */ RTNL_LINK_TX_HBEAT_ERR, /*!< Heartbeat errors */ RTNL_LINK_TX_WIN_ERR, /*!< Window errors */ RTNL_LINK_COLLISIONS, /*!< Send collisions */ RTNL_LINK_MULTICAST, /*!< Multicast */ RTNL_LINK_IP6_INPKTS, /*!< IPv6 SNMP InReceives */ RTNL_LINK_IP6_INHDRERRORS, /*!< IPv6 SNMP InHdrErrors */ RTNL_LINK_IP6_INTOOBIGERRORS, /*!< IPv6 SNMP InTooBigErrors */ RTNL_LINK_IP6_INNOROUTES, /*!< IPv6 SNMP InNoRoutes */ RTNL_LINK_IP6_INADDRERRORS, /*!< IPv6 SNMP InAddrErrors */ RTNL_LINK_IP6_INUNKNOWNPROTOS, /*!< IPv6 SNMP InUnknownProtos */ RTNL_LINK_IP6_INTRUNCATEDPKTS, /*!< IPv6 SNMP InTruncatedPkts */ RTNL_LINK_IP6_INDISCARDS, /*!< IPv6 SNMP InDiscards */ RTNL_LINK_IP6_INDELIVERS, /*!< IPv6 SNMP InDelivers */ RTNL_LINK_IP6_OUTFORWDATAGRAMS, /*!< IPv6 SNMP OutForwDatagrams */ RTNL_LINK_IP6_OUTPKTS, /*!< IPv6 SNMP OutRequests */ RTNL_LINK_IP6_OUTDISCARDS, /*!< IPv6 SNMP OutDiscards */ RTNL_LINK_IP6_OUTNOROUTES, /*!< IPv6 SNMP OutNoRoutes */ RTNL_LINK_IP6_REASMTIMEOUT, /*!< IPv6 SNMP ReasmTimeout */ RTNL_LINK_IP6_REASMREQDS, /*!< IPv6 SNMP ReasmReqds */ RTNL_LINK_IP6_REASMOKS, /*!< IPv6 SNMP ReasmOKs */ RTNL_LINK_IP6_REASMFAILS, /*!< IPv6 SNMP ReasmFails */ RTNL_LINK_IP6_FRAGOKS, /*!< IPv6 SNMP FragOKs */ RTNL_LINK_IP6_FRAGFAILS, /*!< IPv6 SNMP FragFails */ RTNL_LINK_IP6_FRAGCREATES, /*!< IPv6 SNMP FragCreates */ RTNL_LINK_IP6_INMCASTPKTS, /*!< IPv6 SNMP InMcastPkts */ RTNL_LINK_IP6_OUTMCASTPKTS, /*!< IPv6 SNMP OutMcastPkts */ RTNL_LINK_IP6_INBCASTPKTS, /*!< IPv6 SNMP InBcastPkts */ RTNL_LINK_IP6_OUTBCASTPKTS, /*!< IPv6 SNMP OutBcastPkts */ RTNL_LINK_IP6_INOCTETS, /*!< IPv6 SNMP InOctets */ RTNL_LINK_IP6_OUTOCTETS, /*!< IPv6 SNMP OutOctets */ RTNL_LINK_IP6_INMCASTOCTETS, /*!< IPv6 SNMP InMcastOctets */ RTNL_LINK_IP6_OUTMCASTOCTETS, /*!< IPv6 SNMP OutMcastOctets */ RTNL_LINK_IP6_INBCASTOCTETS, /*!< IPv6 SNMP InBcastOctets */ RTNL_LINK_IP6_OUTBCASTOCTETS, /*!< IPv6 SNMP OutBcastOctets */ RTNL_LINK_ICMP6_INMSGS, /*!< ICMPv6 SNMP InMsgs */ RTNL_LINK_ICMP6_INERRORS, /*!< ICMPv6 SNMP InErrors */ RTNL_LINK_ICMP6_OUTMSGS, /*!< ICMPv6 SNMP OutMsgs */ RTNL_LINK_ICMP6_OUTERRORS, /*!< ICMPv6 SNMP OutErrors */ RTNL_LINK_ICMP6_CSUMERRORS, /*!< ICMPv6 SNMP InCsumErrors */ RTNL_LINK_IP6_CSUMERRORS, /*!< IPv6 SNMP InCsumErrors */ RTNL_LINK_IP6_NOECTPKTS, /*!< IPv6 SNMP InNoECTPkts */ RTNL_LINK_IP6_ECT1PKTS, /*!< IPv6 SNMP InECT1Pkts */ RTNL_LINK_IP6_ECT0PKTS, /*!< IPv6 SNMP InECT0Pkts */ RTNL_LINK_IP6_CEPKTS, /*!< IPv6 SNMP InCEPkts */ RTNL_LINK_RX_NOHANDLER, /*!< Received packets dropped on inactive device */ __RTNL_LINK_STATS_MAX, } rtnl_link_stat_id_t; #define RTNL_LINK_STATS_MAX (__RTNL_LINK_STATS_MAX - 1) extern struct nla_policy rtln_link_policy[]; extern struct rtnl_link *rtnl_link_alloc(void); extern void rtnl_link_put(struct rtnl_link *); extern int rtnl_link_alloc_cache(struct nl_sock *, int, struct nl_cache **); extern int rtnl_link_alloc_cache_flags(struct nl_sock *, int, struct nl_cache **, unsigned int flags); extern struct rtnl_link *rtnl_link_get(struct nl_cache *, int); extern struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *, const char *); extern int rtnl_link_build_add_request(struct rtnl_link *, int, struct nl_msg **); extern int rtnl_link_add(struct nl_sock *, struct rtnl_link *, int); extern int rtnl_link_build_change_request(struct rtnl_link *, struct rtnl_link *, int, struct nl_msg **); extern int rtnl_link_change(struct nl_sock *, struct rtnl_link *, struct rtnl_link *, int); extern int rtnl_link_build_delete_request(const struct rtnl_link *, struct nl_msg **); extern int rtnl_link_delete(struct nl_sock *, const struct rtnl_link *); extern int rtnl_link_build_get_request(int, const char *, struct nl_msg **); extern int rtnl_link_get_kernel(struct nl_sock *, int, const char *, struct rtnl_link **); /* Name <-> Index Translations */ extern char * rtnl_link_i2name(struct nl_cache *, int, char *, size_t); extern int rtnl_link_name2i(struct nl_cache *, const char *); /* Name <-> Statistic Translations */ extern char * rtnl_link_stat2str(int, char *, size_t); extern int rtnl_link_str2stat(const char *); /* Link Flags Translations */ extern char * rtnl_link_flags2str(int, char *, size_t); extern int rtnl_link_str2flags(const char *); extern char * rtnl_link_operstate2str(uint8_t, char *, size_t); extern int rtnl_link_str2operstate(const char *); extern char * rtnl_link_mode2str(uint8_t, char *, size_t); extern int rtnl_link_str2mode(const char *); /* Carrier State Translations */ extern char * rtnl_link_carrier2str(uint8_t, char *, size_t); extern int rtnl_link_str2carrier(const char *); /* Access Functions */ extern void rtnl_link_set_qdisc(struct rtnl_link *, const char *); extern char * rtnl_link_get_qdisc(struct rtnl_link *); extern void rtnl_link_set_name(struct rtnl_link *, const char *); extern char * rtnl_link_get_name(struct rtnl_link *); extern void rtnl_link_set_group(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_get_group(struct rtnl_link *); extern void rtnl_link_set_flags(struct rtnl_link *, unsigned int); extern void rtnl_link_unset_flags(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_flags(struct rtnl_link *); extern void rtnl_link_set_mtu(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_mtu(struct rtnl_link *); extern void rtnl_link_set_txqlen(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_txqlen(struct rtnl_link *); extern void rtnl_link_set_ifindex(struct rtnl_link *, int); extern int rtnl_link_get_ifindex(struct rtnl_link *); extern void rtnl_link_set_family(struct rtnl_link *, int); extern int rtnl_link_get_family(struct rtnl_link *); extern void rtnl_link_set_arptype(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_arptype(struct rtnl_link *); extern void rtnl_link_set_addr(struct rtnl_link *, struct nl_addr *); extern struct nl_addr *rtnl_link_get_addr(struct rtnl_link *); extern void rtnl_link_set_broadcast(struct rtnl_link *, struct nl_addr *); extern struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *); extern void rtnl_link_set_link(struct rtnl_link *, int); extern int rtnl_link_get_link(struct rtnl_link *); extern void rtnl_link_set_master(struct rtnl_link *, int); extern int rtnl_link_get_master(struct rtnl_link *); extern void rtnl_link_set_carrier(struct rtnl_link *, uint8_t); extern uint8_t rtnl_link_get_carrier(struct rtnl_link *); extern int rtnl_link_get_carrier_changes(struct rtnl_link *, uint32_t *); extern void rtnl_link_set_operstate(struct rtnl_link *, uint8_t); extern uint8_t rtnl_link_get_operstate(struct rtnl_link *); extern void rtnl_link_set_linkmode(struct rtnl_link *, uint8_t); extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *); int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid); int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid); extern const char * rtnl_link_get_ifalias(struct rtnl_link *); extern void rtnl_link_set_ifalias(struct rtnl_link *, const char *); extern int rtnl_link_get_num_vf(struct rtnl_link *, uint32_t *); extern uint64_t rtnl_link_get_stat(struct rtnl_link *, rtnl_link_stat_id_t); extern int rtnl_link_set_stat(struct rtnl_link *, rtnl_link_stat_id_t, const uint64_t); extern int rtnl_link_set_type(struct rtnl_link *, const char *); extern char * rtnl_link_get_type(struct rtnl_link *); extern void rtnl_link_set_promiscuity(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_get_promiscuity(struct rtnl_link *); extern void rtnl_link_set_num_tx_queues(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *); extern void rtnl_link_set_num_rx_queues(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *); extern int rtnl_link_get_gso_max_segs(struct rtnl_link *, uint32_t *); extern int rtnl_link_get_gso_max_size(struct rtnl_link *, uint32_t *); extern struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *); extern char* rtnl_link_get_phys_port_name(struct rtnl_link *); extern struct nl_data * rtnl_link_get_phys_switch_id(struct rtnl_link *); extern void rtnl_link_set_ns_fd(struct rtnl_link *, int); extern int rtnl_link_get_ns_fd(struct rtnl_link *); extern void rtnl_link_set_ns_pid(struct rtnl_link *, pid_t); extern pid_t rtnl_link_get_ns_pid(struct rtnl_link *); extern int rtnl_link_enslave_ifindex(struct nl_sock *, int, int); extern int rtnl_link_enslave(struct nl_sock *, struct rtnl_link *, struct rtnl_link *); extern int rtnl_link_release_ifindex(struct nl_sock *, int); extern int rtnl_link_release(struct nl_sock *, struct rtnl_link *); extern int rtnl_link_fill_info(struct nl_msg *, struct rtnl_link *); extern int rtnl_link_info_parse(struct rtnl_link *, struct nlattr **); extern int rtnl_link_has_vf_list(struct rtnl_link *); extern void rtnl_link_set_vf_list(struct rtnl_link *); extern void rtnl_link_unset_vf_list(struct rtnl_link *); /* deprecated */ extern int rtnl_link_set_info_type(struct rtnl_link *, const char *) __attribute__((deprecated)); extern char * rtnl_link_get_info_type(struct rtnl_link *) __attribute__((deprecated)); extern void rtnl_link_set_weight(struct rtnl_link *, unsigned int) __attribute__((deprecated)); extern unsigned int rtnl_link_get_weight(struct rtnl_link *) __attribute__((deprecated)); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/rule.h0000644000175000017500000000542413023014600015167 00000000000000/* * netlink/route/rule.h Rules * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2010 Thomas Graf */ #ifndef NETLINK_RULE_H_ #define NETLINK_RULE_H_ #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_rule; /* General */ extern struct rtnl_rule * rtnl_rule_alloc(void); extern void rtnl_rule_put(struct rtnl_rule *); extern int rtnl_rule_alloc_cache(struct nl_sock *, int, struct nl_cache **); extern void rtnl_rule_dump(struct rtnl_rule *, FILE *, struct nl_dump_params *); extern int rtnl_rule_build_add_request(struct rtnl_rule *, int, struct nl_msg **); extern int rtnl_rule_add(struct nl_sock *, struct rtnl_rule *, int); extern int rtnl_rule_build_delete_request(struct rtnl_rule *, int, struct nl_msg **); extern int rtnl_rule_delete(struct nl_sock *, struct rtnl_rule *, int); /* attribute modification */ extern void rtnl_rule_set_family(struct rtnl_rule *, int); extern int rtnl_rule_get_family(struct rtnl_rule *); extern void rtnl_rule_set_prio(struct rtnl_rule *, uint32_t); extern uint32_t rtnl_rule_get_prio(struct rtnl_rule *); extern void rtnl_rule_set_mark(struct rtnl_rule *, uint32_t); extern uint32_t rtnl_rule_get_mark(struct rtnl_rule *); extern void rtnl_rule_set_mask(struct rtnl_rule *, uint32_t); extern uint32_t rtnl_rule_get_mask(struct rtnl_rule *); extern void rtnl_rule_set_table(struct rtnl_rule *, uint32_t); extern uint32_t rtnl_rule_get_table(struct rtnl_rule *); extern void rtnl_rule_set_dsfield(struct rtnl_rule *, uint8_t); extern uint8_t rtnl_rule_get_dsfield(struct rtnl_rule *); extern int rtnl_rule_set_src(struct rtnl_rule *, struct nl_addr *); extern struct nl_addr * rtnl_rule_get_src(struct rtnl_rule *); extern int rtnl_rule_set_dst(struct rtnl_rule *, struct nl_addr *); extern struct nl_addr * rtnl_rule_get_dst(struct rtnl_rule *); extern void rtnl_rule_set_action(struct rtnl_rule *, uint8_t); extern uint8_t rtnl_rule_get_action(struct rtnl_rule *); extern int rtnl_rule_set_iif(struct rtnl_rule *, const char *); extern char * rtnl_rule_get_iif(struct rtnl_rule *); extern int rtnl_rule_set_oif(struct rtnl_rule *, const char *); extern char * rtnl_rule_get_oif(struct rtnl_rule *); extern void rtnl_rule_set_realms(struct rtnl_rule *, uint32_t); extern uint32_t rtnl_rule_get_realms(struct rtnl_rule *); extern void rtnl_rule_set_goto(struct rtnl_rule *, uint32_t); extern uint32_t rtnl_rule_get_goto(struct rtnl_rule *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/neightbl.h0000644000175000017500000000516513023014600016016 00000000000000/* * netlink/route/neightbl.h Neighbour Tables * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_NEIGHTBL_H_ #define NETLINK_NEIGHTBL_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_neightbl; extern struct rtnl_neightbl *rtnl_neightbl_alloc(void); extern void rtnl_neightbl_put(struct rtnl_neightbl *); extern void rtnl_neightbl_free(struct rtnl_neightbl *); extern int rtnl_neightbl_alloc_cache(struct nl_sock *, struct nl_cache **); extern struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *, const char *, int); extern void rtnl_neightbl_dump(struct rtnl_neightbl *, FILE *, struct nl_dump_params *); extern int rtnl_neightbl_build_change_request(struct rtnl_neightbl *, struct rtnl_neightbl *, struct nl_msg **); extern int rtnl_neightbl_change(struct nl_sock *, struct rtnl_neightbl *, struct rtnl_neightbl *); extern void rtnl_neightbl_set_family(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_gc_tresh1(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_gc_tresh2(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_gc_tresh3(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_gc_interval(struct rtnl_neightbl *, uint64_t); extern void rtnl_neightbl_set_name(struct rtnl_neightbl *, const char *); extern void rtnl_neightbl_set_dev(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_queue_len(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_proxy_queue_len(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_app_probes(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_ucast_probes(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_mcast_probes(struct rtnl_neightbl *, int); extern void rtnl_neightbl_set_base_reachable_time(struct rtnl_neightbl *, uint64_t); extern void rtnl_neightbl_set_retrans_time(struct rtnl_neightbl *, uint64_t); extern void rtnl_neightbl_set_gc_stale_time(struct rtnl_neightbl *, uint64_t); extern void rtnl_neightbl_set_delay_probe_time(struct rtnl_neightbl *, uint64_t); extern void rtnl_neightbl_set_anycast_delay(struct rtnl_neightbl *, uint64_t); extern void rtnl_neightbl_set_proxy_delay(struct rtnl_neightbl *, uint64_t); extern void rtnl_neightbl_set_locktime(struct rtnl_neightbl *, uint64_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/rtnl.h0000644000175000017500000000252013023014600015171 00000000000000/* * netlink/route/rtnl.h Routing Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_RTNL_H_ #define NETLINK_RTNL_H_ #include #ifdef __cplusplus extern "C" { #endif /** * @name Realms * @{ */ /** * Mask specying the size of each realm part * @ingroup rtnl */ #define RTNL_REALM_MASK (0xFFFF) /** * Extract FROM realm from a realms field */ #define RTNL_REALM_FROM(realm) ((realm) >> 16) /** * Extract TO realm from a realms field */ #define RTNL_REALM_TO(realm) ((realm) & RTNL_REALM_MASK) /** * Build a realms field */ #define RTNL_MAKE_REALM(from, to) \ ((RTNL_REALM_TO(from) << 16) & RTNL_REALM_TO(to)) /** @} */ /* General */ extern int nl_rtgen_request(struct nl_sock *, int, int, int); /* Routing Type Translations */ extern char * nl_rtntype2str(int, char *, size_t); extern int nl_str2rtntype(const char *); /* Scope Translations */ extern char * rtnl_scope2str(int, char *, size_t); extern int rtnl_str2scope(const char *); /* Realms Translations */ extern char * rtnl_realms2str(uint32_t, char *, size_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/route.h0000644000175000017500000001120713023014600015352 00000000000000/* * netlink/route/route.h Routes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #ifndef NETLINK_ROUTE_H_ #define NETLINK_ROUTE_H_ #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @ingroup route * When passed to rtnl_route_alloc_cache() the cache will * correspond to the contents of the routing cache instead * of the actual routes. */ #define ROUTE_CACHE_CONTENT 1 struct rtnl_route; struct rtnl_rtcacheinfo { uint32_t rtci_clntref; uint32_t rtci_last_use; uint32_t rtci_expires; int32_t rtci_error; uint32_t rtci_used; uint32_t rtci_id; uint32_t rtci_ts; uint32_t rtci_tsage; }; extern struct nl_object_ops route_obj_ops; extern struct rtnl_route * rtnl_route_alloc(void); extern void rtnl_route_put(struct rtnl_route *); extern int rtnl_route_alloc_cache(struct nl_sock *, int, int, struct nl_cache **); extern void rtnl_route_get(struct rtnl_route *); extern int rtnl_route_parse(struct nlmsghdr *, struct rtnl_route **); extern int rtnl_route_build_msg(struct nl_msg *, struct rtnl_route *); extern int rtnl_route_build_add_request(struct rtnl_route *, int, struct nl_msg **); extern int rtnl_route_add(struct nl_sock *, struct rtnl_route *, int); extern int rtnl_route_build_del_request(struct rtnl_route *, int, struct nl_msg **); extern int rtnl_route_delete(struct nl_sock *, struct rtnl_route *, int); extern void rtnl_route_set_table(struct rtnl_route *, uint32_t); extern uint32_t rtnl_route_get_table(struct rtnl_route *); extern void rtnl_route_set_scope(struct rtnl_route *, uint8_t); extern uint8_t rtnl_route_get_scope(struct rtnl_route *); extern void rtnl_route_set_tos(struct rtnl_route *, uint8_t); extern uint8_t rtnl_route_get_tos(struct rtnl_route *); extern void rtnl_route_set_protocol(struct rtnl_route *, uint8_t); extern uint8_t rtnl_route_get_protocol(struct rtnl_route *); extern void rtnl_route_set_priority(struct rtnl_route *, uint32_t); extern uint32_t rtnl_route_get_priority(struct rtnl_route *); extern int rtnl_route_set_family(struct rtnl_route *, uint8_t); extern uint8_t rtnl_route_get_family(struct rtnl_route *); extern int rtnl_route_set_type(struct rtnl_route *, uint8_t); extern uint8_t rtnl_route_get_type(struct rtnl_route *); extern void rtnl_route_set_flags(struct rtnl_route *, uint32_t); extern void rtnl_route_unset_flags(struct rtnl_route *, uint32_t); extern uint32_t rtnl_route_get_flags(struct rtnl_route *); extern int rtnl_route_set_metric(struct rtnl_route *, int, unsigned int); extern int rtnl_route_unset_metric(struct rtnl_route *, int); extern int rtnl_route_get_metric(struct rtnl_route *, int, uint32_t *); extern int rtnl_route_set_dst(struct rtnl_route *, struct nl_addr *); extern struct nl_addr *rtnl_route_get_dst(struct rtnl_route *); extern int rtnl_route_set_src(struct rtnl_route *, struct nl_addr *); extern struct nl_addr *rtnl_route_get_src(struct rtnl_route *); extern int rtnl_route_set_pref_src(struct rtnl_route *, struct nl_addr *); extern struct nl_addr *rtnl_route_get_pref_src(struct rtnl_route *); extern void rtnl_route_set_iif(struct rtnl_route *, int); extern int rtnl_route_get_iif(struct rtnl_route *); extern int rtnl_route_get_src_len(struct rtnl_route *); extern void rtnl_route_add_nexthop(struct rtnl_route *, struct rtnl_nexthop *); extern void rtnl_route_remove_nexthop(struct rtnl_route *, struct rtnl_nexthop *); extern struct nl_list_head *rtnl_route_get_nexthops(struct rtnl_route *); extern int rtnl_route_get_nnexthops(struct rtnl_route *); extern void rtnl_route_foreach_nexthop(struct rtnl_route *r, void (*cb)(struct rtnl_nexthop *, void *), void *arg); extern struct rtnl_nexthop * rtnl_route_nexthop_n(struct rtnl_route *r, int n); extern int rtnl_route_guess_scope(struct rtnl_route *); extern char * rtnl_route_table2str(int, char *, size_t); extern int rtnl_route_str2table(const char *); extern int rtnl_route_read_table_names(const char *); extern char * rtnl_route_proto2str(int, char *, size_t); extern int rtnl_route_str2proto(const char *); extern int rtnl_route_read_protocol_names(const char *); extern char * rtnl_route_metric2str(int, char *, size_t); extern int rtnl_route_str2metric(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/0000755000175000017500000000000013031473756015251 500000000000000libnl-3.2.29/include/netlink/route/qdisc/dsmark.h0000644000175000017500000000234313023014600016601 00000000000000/* * netlink/route/sch/dsmark.h DSMARK * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_DSMARK_H_ #define NETLINK_DSMARK_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_class_dsmark_set_bitmask(struct rtnl_class *, uint8_t); extern int rtnl_class_dsmark_get_bitmask(struct rtnl_class *); extern int rtnl_class_dsmark_set_value(struct rtnl_class *, uint8_t); extern int rtnl_class_dsmark_get_value(struct rtnl_class *); extern int rtnl_qdisc_dsmark_set_indices(struct rtnl_qdisc *, uint16_t); extern int rtnl_qdisc_dsmark_get_indices(struct rtnl_qdisc *); extern int rtnl_qdisc_dsmark_set_default_index(struct rtnl_qdisc *, uint16_t); extern int rtnl_qdisc_dsmark_get_default_index(struct rtnl_qdisc *); extern int rtnl_qdisc_dsmark_set_set_tc_index(struct rtnl_qdisc *, int); extern int rtnl_qdisc_dsmark_get_set_tc_index(struct rtnl_qdisc *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/tbf.h0000644000175000017500000000235613023014600016077 00000000000000/* * netlink/route/sch/tbf.h TBF Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_TBF_H_ #define NETLINK_TBF_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_qdisc_tbf_set_limit(struct rtnl_qdisc *, int); extern int rtnl_qdisc_tbf_set_limit_by_latency(struct rtnl_qdisc *, int); extern int rtnl_qdisc_tbf_get_limit(struct rtnl_qdisc *); extern void rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *, int, int, int); extern int rtnl_qdisc_tbf_get_rate(struct rtnl_qdisc *); extern int rtnl_qdisc_tbf_get_rate_bucket(struct rtnl_qdisc *); extern int rtnl_qdisc_tbf_get_rate_cell(struct rtnl_qdisc *); extern int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *, int, int, int); extern int rtnl_qdisc_tbf_get_peakrate(struct rtnl_qdisc *); extern int rtnl_qdisc_tbf_get_peakrate_bucket(struct rtnl_qdisc *); extern int rtnl_qdisc_tbf_get_peakrate_cell(struct rtnl_qdisc *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/netem.h0000644000175000017500000000506313023014600016432 00000000000000/* * netlink/route/sch/netem.h Network Emulator Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_NETEM_H_ #define NETLINK_NETEM_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_netem_set_limit(struct rtnl_qdisc *, int); extern int rtnl_netem_get_limit(struct rtnl_qdisc *); /* Packet Re-ordering */ extern void rtnl_netem_set_gap(struct rtnl_qdisc *, int); extern int rtnl_netem_get_gap(struct rtnl_qdisc *); extern void rtnl_netem_set_reorder_probability(struct rtnl_qdisc *, int); extern int rtnl_netem_get_reorder_probability(struct rtnl_qdisc *); extern void rtnl_netem_set_reorder_correlation(struct rtnl_qdisc *, int); extern int rtnl_netem_get_reorder_correlation(struct rtnl_qdisc *); /* Corruption */ extern void rtnl_netem_set_corruption_probability(struct rtnl_qdisc *, int); extern int rtnl_netem_get_corruption_probability(struct rtnl_qdisc *); extern void rtnl_netem_set_corruption_correlation(struct rtnl_qdisc *, int); extern int rtnl_netem_get_corruption_correlation(struct rtnl_qdisc *); /* Packet Loss */ extern void rtnl_netem_set_loss(struct rtnl_qdisc *, int); extern int rtnl_netem_get_loss(struct rtnl_qdisc *); extern void rtnl_netem_set_loss_correlation(struct rtnl_qdisc *, int); extern int rtnl_netem_get_loss_correlation(struct rtnl_qdisc *); /* Packet Duplication */ extern void rtnl_netem_set_duplicate(struct rtnl_qdisc *, int); extern int rtnl_netem_get_duplicate(struct rtnl_qdisc *); extern void rtnl_netem_set_duplicate_correlation(struct rtnl_qdisc *, int); extern int rtnl_netem_get_duplicate_correlation(struct rtnl_qdisc *); /* Packet Delay */ extern void rtnl_netem_set_delay(struct rtnl_qdisc *, int); extern int rtnl_netem_get_delay(struct rtnl_qdisc *); extern void rtnl_netem_set_jitter(struct rtnl_qdisc *, int); extern int rtnl_netem_get_jitter(struct rtnl_qdisc *); extern void rtnl_netem_set_delay_correlation(struct rtnl_qdisc *, int); extern int rtnl_netem_get_delay_correlation(struct rtnl_qdisc *); /* Delay Distribution */ #define MAXDIST 65536 extern int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *, const char *); extern int rtnl_netem_get_delay_distribution_size(struct rtnl_qdisc *); extern int rtnl_netem_get_delay_distribution(struct rtnl_qdisc *, int16_t **); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/prio.h0000644000175000017500000000220313023014600016264 00000000000000/* * netlink/route/sch/prio.c PRIO Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_PRIO_H_ #define NETLINK_PRIO_H_ #include #include #ifdef __cplusplus extern "C" { #endif /** * @name Default Values * @{ */ /** * Default number of bands. * @ingroup prio */ #define QDISC_PRIO_DEFAULT_BANDS 3 /** * Default priority mapping. * @ingroup prio */ #define QDISC_PRIO_DEFAULT_PRIOMAP \ { 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 } /** @} */ extern void rtnl_qdisc_prio_set_bands(struct rtnl_qdisc *, int); extern int rtnl_qdisc_prio_get_bands(struct rtnl_qdisc *); extern int rtnl_qdisc_prio_set_priomap(struct rtnl_qdisc *, uint8_t[], int); extern uint8_t *rtnl_qdisc_prio_get_priomap(struct rtnl_qdisc *); extern char * rtnl_prio2str(int, char *, size_t); extern int rtnl_str2prio(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/fq_codel.h0000644000175000017500000000251213023014600017072 00000000000000/* * netlink/route/sch/fq_codel.h fq_codel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ #ifndef NETLINK_FQ_CODEL_H_ #define NETLINK_FQ_CODEL_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_qdisc_fq_codel_set_limit(struct rtnl_qdisc *, int); extern int rtnl_qdisc_fq_codel_get_limit(struct rtnl_qdisc *); extern int rtnl_qdisc_fq_codel_set_target(struct rtnl_qdisc *, uint32_t); extern uint32_t rtnl_qdisc_fq_codel_get_target(struct rtnl_qdisc *); extern int rtnl_qdisc_fq_codel_set_interval(struct rtnl_qdisc *, uint32_t); extern uint32_t rtnl_qdisc_fq_codel_get_interval(struct rtnl_qdisc *); extern int rtnl_qdisc_fq_codel_set_quantum(struct rtnl_qdisc *, uint32_t); extern uint32_t rtnl_qdisc_fq_codel_get_quantum(struct rtnl_qdisc *); extern int rtnl_qdisc_fq_codel_set_flows(struct rtnl_qdisc *, int); extern int rtnl_qdisc_fq_codel_get_flows(struct rtnl_qdisc *); extern int rtnl_qdisc_fq_codel_set_ecn(struct rtnl_qdisc *, int); extern int rtnl_qdisc_fq_codel_get_ecn(struct rtnl_qdisc *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/fifo.h0000644000175000017500000000117213023014600016242 00000000000000/* * netlink/route/sch/fifo.c FIFO Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_FIFO_H_ #define NETLINK_FIFO_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_qdisc_fifo_set_limit(struct rtnl_qdisc *, int); extern int rtnl_qdisc_fifo_get_limit(struct rtnl_qdisc *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/htb.h0000644000175000017500000000334313023014600016076 00000000000000/* * netlink/route/sch/htb.h HTB Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf * Copyright (c) 2005 Petr Gotthard * Copyright (c) 2005 Siemens AG Oesterreich */ #ifndef NETLINK_HTB_H_ #define NETLINK_HTB_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *); extern int rtnl_htb_set_rate2quantum(struct rtnl_qdisc *, uint32_t); extern uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *); extern int rtnl_htb_set_defcls(struct rtnl_qdisc *, uint32_t); extern uint32_t rtnl_htb_get_prio(struct rtnl_class *); extern int rtnl_htb_set_prio(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_rate(struct rtnl_class *); extern int rtnl_htb_set_rate(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_ceil(struct rtnl_class *); extern int rtnl_htb_set_ceil(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *); extern int rtnl_htb_set_rbuffer(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *); extern int rtnl_htb_set_cbuffer(struct rtnl_class *, uint32_t); extern uint32_t rtnl_htb_get_quantum(struct rtnl_class *); extern int rtnl_htb_set_quantum(struct rtnl_class *, uint32_t); extern int rtnl_htb_set_level(struct rtnl_class *, int); extern int rtnl_htb_get_level(struct rtnl_class *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/red.h0000644000175000017500000000062413023014600016072 00000000000000/* * netlink/route/sch/red.h RED Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_RED_H_ #define NETLINK_RED_H_ #include #endif libnl-3.2.29/include/netlink/route/qdisc/cbq.h0000644000175000017500000000121213023014600016057 00000000000000/* * netlink/route/sch/cbq.h Class Based Queueing * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_CBQ_H_ #define NETLINK_CBQ_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif extern char * nl_ovl_strategy2str(int, char *, size_t); extern int nl_str2ovl_strategy(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/sfq.h0000644000175000017500000000160613023014600016112 00000000000000/* * netlink/route/sch/sfq.c SFQ Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_SFQ_H_ #define NETLINK_SFQ_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern void rtnl_sfq_set_quantum(struct rtnl_qdisc *, int); extern int rtnl_sfq_get_quantum(struct rtnl_qdisc *); extern void rtnl_sfq_set_limit(struct rtnl_qdisc *, int); extern int rtnl_sfq_get_limit(struct rtnl_qdisc *); extern void rtnl_sfq_set_perturb(struct rtnl_qdisc *, int); extern int rtnl_sfq_get_perturb(struct rtnl_qdisc *); extern int rtnl_sfq_get_divisor(struct rtnl_qdisc *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/plug.h0000644000175000017500000000140213023014600016262 00000000000000/* * netlink/route/qdisc/plug.c PLUG Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Shriram Rajagopalan */ #ifndef NETLINK_PLUG_H_ #define NETLINK_PLUG_H_ #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_qdisc_plug_set_limit(struct rtnl_qdisc *, int); extern int rtnl_qdisc_plug_buffer(struct rtnl_qdisc *); extern int rtnl_qdisc_plug_release_one(struct rtnl_qdisc *); extern int rtnl_qdisc_plug_release_indefinite(struct rtnl_qdisc *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/qdisc/hfsc.h0000644000175000017500000000241713023014600016245 00000000000000/* * netlink/route/sch/hfsc.h HFSC Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Cong Wang */ #ifndef NETLINK_HFSC_H_ #define NETLINK_HFSC_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern uint32_t rtnl_qdisc_hfsc_get_defcls(const struct rtnl_qdisc *); extern int rtnl_qdisc_hfsc_set_defcls(struct rtnl_qdisc *, uint32_t); extern int rtnl_class_hfsc_get_rsc(const struct rtnl_class *cls, struct tc_service_curve *tsc); extern int rtnl_class_hfsc_set_rsc(struct rtnl_class *cls, const struct tc_service_curve *tsc); extern int rtnl_class_hfsc_get_fsc(const struct rtnl_class *cls, struct tc_service_curve *tsc); extern int rtnl_class_hfsc_set_fsc(struct rtnl_class *cls, const struct tc_service_curve *tsc); extern int rtnl_class_hfsc_get_usc(const struct rtnl_class *cls, struct tc_service_curve *tsc); extern int rtnl_class_hfsc_set_usc(struct rtnl_class *cls, const struct tc_service_curve *tsc); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/tc.h0000644000175000017500000000667613023014600014640 00000000000000/* * netlink/route/tc.h Traffic Control * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #ifndef NETLINK_TC_H_ #define NETLINK_TC_H_ #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif enum rtnl_tc_type { RTNL_TC_TYPE_QDISC, RTNL_TC_TYPE_CLASS, RTNL_TC_TYPE_CLS, RTNL_TC_TYPE_ACT, __RTNL_TC_TYPE_MAX, }; #define RTNL_TC_TYPE_MAX (__RTNL_TC_TYPE_MAX - 1) /** * Compute tc handle based on major and minor parts * @ingroup tc */ #define TC_HANDLE(maj, min) (TC_H_MAJ((maj) << 16) | TC_H_MIN(min)) /** * Traffic control object * @ingroup tc */ struct rtnl_tc; /** * Macro to cast qdisc/class/classifier to tc object * @ingroup tc * * @code * rtnl_tc_set_mpu(TC_CAST(qdisc), 40); * @endcode */ #define TC_CAST(ptr) ((struct rtnl_tc *) (ptr)) /** * Traffic control statistical identifier * @ingroup tc * * @code * uint64_t n = rtnl_tc_get_stat(TC_CAST(class), RTNL_TC_PACKETS); * @endcode */ enum rtnl_tc_stat { RTNL_TC_PACKETS, /**< Number of packets seen */ RTNL_TC_BYTES, /**< Total bytes seen */ RTNL_TC_RATE_BPS, /**< Current bits/s (rate estimator) */ RTNL_TC_RATE_PPS, /**< Current packet/s (rate estimator) */ RTNL_TC_QLEN, /**< Current queue length */ RTNL_TC_BACKLOG, /**< Current backlog length */ RTNL_TC_DROPS, /**< Total number of packets dropped */ RTNL_TC_REQUEUES, /**< Total number of requeues */ RTNL_TC_OVERLIMITS, /**< Total number of overlimits */ __RTNL_TC_STATS_MAX, }; #define RTNL_TC_STATS_MAX (__RTNL_TC_STATS_MAX - 1) extern void rtnl_tc_set_ifindex(struct rtnl_tc *, int); extern int rtnl_tc_get_ifindex(struct rtnl_tc *); extern void rtnl_tc_set_link(struct rtnl_tc *, struct rtnl_link *); extern struct rtnl_link *rtnl_tc_get_link(struct rtnl_tc *); extern void rtnl_tc_set_mtu(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_mtu(struct rtnl_tc *); extern void rtnl_tc_set_mpu(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_mpu(struct rtnl_tc *); extern void rtnl_tc_set_overhead(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_overhead(struct rtnl_tc *); extern void rtnl_tc_set_linktype(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_linktype(struct rtnl_tc *); extern void rtnl_tc_set_handle(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_handle(struct rtnl_tc *); extern void rtnl_tc_set_parent(struct rtnl_tc *, uint32_t); extern uint32_t rtnl_tc_get_parent(struct rtnl_tc *); extern int rtnl_tc_set_kind(struct rtnl_tc *, const char *); extern char * rtnl_tc_get_kind(struct rtnl_tc *); extern uint64_t rtnl_tc_get_stat(struct rtnl_tc *, enum rtnl_tc_stat); extern char * rtnl_tc_stat2str(enum rtnl_tc_stat, char *, size_t); extern int rtnl_tc_str2stat(const char *); extern int rtnl_tc_calc_txtime(int, int); extern int rtnl_tc_calc_bufsize(int, int); extern int rtnl_tc_calc_cell_log(int); extern int rtnl_tc_read_classid_file(void); extern char * rtnl_tc_handle2str(uint32_t, char *, size_t); extern int rtnl_tc_str2handle(const char *, uint32_t *); extern int rtnl_classid_generate(const char *, uint32_t *, uint32_t); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/tc-api.h0000644000175000017500000000106713023014600015374 00000000000000/* * netlink/route/tc-api.h Traffic Control API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Thomas Graf */ #ifndef NETLINK_DUMMY_TC_API_H_ #define NETLINK_DUMMY_TC_API_H_ #include #include #include #warning "You are including a deprecated header file, include ." #endif libnl-3.2.29/include/netlink/route/nexthop.h0000644000175000017500000000371013023014600015701 00000000000000/* * netlink/route/nexthop.h Routing Nexthop * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_ROUTE_NEXTHOP_H_ #define NETLINK_ROUTE_NEXTHOP_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct rtnl_nexthop; enum { NH_DUMP_FROM_ONELINE = -2, NH_DUMP_FROM_DETAILS = -1, NH_DUMP_FROM_ENV = 0, /* > 0 reserved for nexthop index */ }; extern struct rtnl_nexthop * rtnl_route_nh_alloc(void); extern struct rtnl_nexthop * rtnl_route_nh_clone(struct rtnl_nexthop *); extern void rtnl_route_nh_free(struct rtnl_nexthop *); extern int rtnl_route_nh_compare(struct rtnl_nexthop *, struct rtnl_nexthop *, uint32_t, int); extern void rtnl_route_nh_dump(struct rtnl_nexthop *, struct nl_dump_params *); extern void rtnl_route_nh_set_weight(struct rtnl_nexthop *, uint8_t); extern uint8_t rtnl_route_nh_get_weight(struct rtnl_nexthop *); extern void rtnl_route_nh_set_ifindex(struct rtnl_nexthop *, int); extern int rtnl_route_nh_get_ifindex(struct rtnl_nexthop *); extern void rtnl_route_nh_set_gateway(struct rtnl_nexthop *, struct nl_addr *); extern struct nl_addr * rtnl_route_nh_get_gateway(struct rtnl_nexthop *); extern void rtnl_route_nh_set_flags(struct rtnl_nexthop *, unsigned int); extern void rtnl_route_nh_unset_flags(struct rtnl_nexthop *, unsigned int); extern unsigned int rtnl_route_nh_get_flags(struct rtnl_nexthop *); extern void rtnl_route_nh_set_realms(struct rtnl_nexthop *, uint32_t); extern uint32_t rtnl_route_nh_get_realms(struct rtnl_nexthop *); extern char * rtnl_route_nh_flags2str(int, char *, size_t); extern int rtnl_route_nh_str2flags(const char *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/act/0000755000175000017500000000000013031473756014715 500000000000000libnl-3.2.29/include/netlink/route/act/mirred.h0000644000175000017500000000165313023014600016251 00000000000000/* * netlink/route/cls/mirred.h mirred action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ #ifndef NETLINK_MIRRED_H_ #define NETLINK_MIRRED_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_mirred_set_action(struct rtnl_act *, int); extern int rtnl_mirred_get_action(struct rtnl_act *); extern int rtnl_mirred_set_ifindex(struct rtnl_act *, uint32_t); extern uint32_t rtnl_mirred_get_ifindex(struct rtnl_act *); extern int rtnl_mirred_set_policy(struct rtnl_act *, int); extern int rtnl_mirred_get_policy(struct rtnl_act *); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/act/skbedit.h0000644000175000017500000000223213023014600016406 00000000000000/* * netlink/route/act/skbedit.h skbedit action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2015 Cong Wang */ #ifndef NETLINK_SKBEDIT_H_ #define NETLINK_SKBEDIT_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_skbedit_set_action(struct rtnl_act *act, int action); extern int rtnl_skbedit_get_action(struct rtnl_act *act); extern int rtnl_skbedit_set_queue_mapping(struct rtnl_act *act, uint16_t index); extern int rtnl_skbedit_get_queue_mapping(struct rtnl_act *act, uint16_t *index); extern int rtnl_skbedit_set_mark(struct rtnl_act *act, uint32_t mark); extern int rtnl_skbedit_get_mark(struct rtnl_act *act, uint32_t *mark); extern int rtnl_skbedit_set_priority(struct rtnl_act *act, uint32_t prio); extern int rtnl_skbedit_get_priority(struct rtnl_act *act, uint32_t *prio); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/route/act/gact.h0000644000175000017500000000130113023014600015673 00000000000000/* * netlink/route/act/gact.h gact action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Sushma Sitaram */ #ifndef NETLINK_GACT_H_ #define NETLINK_GACT_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif extern int rtnl_gact_set_action(struct rtnl_act *act, int action); extern int rtnl_gact_get_action(struct rtnl_act *act); #ifdef __cplusplus } #endif #endif libnl-3.2.29/include/netlink/list.h0000644000175000017500000000471713023014600014041 00000000000000/* * netlink/list.h Netlink List Utilities * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ #ifndef NETLINK_LIST_H_ #define NETLINK_LIST_H_ #include struct nl_list_head { struct nl_list_head * next; struct nl_list_head * prev; }; static inline void NL_INIT_LIST_HEAD(struct nl_list_head *list) { list->next = list; list->prev = list; } static inline void __nl_list_add(struct nl_list_head *obj, struct nl_list_head *prev, struct nl_list_head *next) { prev->next = obj; obj->prev = prev; next->prev = obj; obj->next = next; } static inline void nl_list_add_tail(struct nl_list_head *obj, struct nl_list_head *head) { __nl_list_add(obj, head->prev, head); } static inline void nl_list_add_head(struct nl_list_head *obj, struct nl_list_head *head) { __nl_list_add(obj, head, head->next); } static inline void nl_list_del(struct nl_list_head *obj) { obj->next->prev = obj->prev; obj->prev->next = obj->next; } static inline int nl_list_empty(struct nl_list_head *head) { return head->next == head; } #define nl_container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - (offsetof(type, member)));}) #define nl_list_entry(ptr, type, member) \ nl_container_of(ptr, type, member) #define nl_list_at_tail(pos, head, member) \ ((pos)->member.next == (head)) #define nl_list_at_head(pos, head, member) \ ((pos)->member.prev == (head)) #define NL_LIST_HEAD(name) \ struct nl_list_head name = { &(name), &(name) } #define nl_list_first_entry(head, type, member) \ nl_list_entry((head)->next, type, member) #define nl_list_for_each_entry(pos, head, member) \ for (pos = nl_list_entry((head)->next, typeof(*pos), member); \ &(pos)->member != (head); \ (pos) = nl_list_entry((pos)->member.next, typeof(*(pos)), member)) #define nl_list_for_each_entry_safe(pos, n, head, member) \ for (pos = nl_list_entry((head)->next, typeof(*pos), member), \ n = nl_list_entry(pos->member.next, typeof(*pos), member); \ &(pos)->member != (head); \ pos = n, n = nl_list_entry(n->member.next, typeof(*n), member)) #define nl_init_list_head(head) \ do { (head)->next = (head); (head)->prev = (head); } while (0) #endif libnl-3.2.29/include/linux-private/0000755000175000017500000000000013031473755014152 500000000000000libnl-3.2.29/include/linux-private/linux/0000755000175000017500000000000013031473756015312 500000000000000libnl-3.2.29/include/linux-private/linux/if_macsec.h0000644000175000017500000001266013023014600017275 00000000000000/* * include/uapi/linux/if_macsec.h - MACsec device * * Copyright (c) 2015 Sabrina Dubroca * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef _MACSEC_H #define _MACSEC_H #include #define MACSEC_GENL_NAME "macsec" #define MACSEC_GENL_VERSION 1 #define MACSEC_MAX_KEY_LEN 128 #define MACSEC_KEYID_LEN 16 #define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL #define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL #define MACSEC_MIN_ICV_LEN 8 #define MACSEC_MAX_ICV_LEN 32 /* upper limit for ICV length as recommended by IEEE802.1AE-2006 */ #define MACSEC_STD_ICV_LEN 16 enum macsec_attrs { MACSEC_ATTR_UNSPEC, MACSEC_ATTR_IFINDEX, /* u32, ifindex of the MACsec netdevice */ MACSEC_ATTR_RXSC_CONFIG, /* config, nested macsec_rxsc_attrs */ MACSEC_ATTR_SA_CONFIG, /* config, nested macsec_sa_attrs */ MACSEC_ATTR_SECY, /* dump, nested macsec_secy_attrs */ MACSEC_ATTR_TXSA_LIST, /* dump, nested, macsec_sa_attrs for each TXSA */ MACSEC_ATTR_RXSC_LIST, /* dump, nested, macsec_rxsc_attrs for each RXSC */ MACSEC_ATTR_TXSC_STATS, /* dump, nested, macsec_txsc_stats_attr */ MACSEC_ATTR_SECY_STATS, /* dump, nested, macsec_secy_stats_attr */ __MACSEC_ATTR_END, NUM_MACSEC_ATTR = __MACSEC_ATTR_END, MACSEC_ATTR_MAX = __MACSEC_ATTR_END - 1, }; enum macsec_secy_attrs { MACSEC_SECY_ATTR_UNSPEC, MACSEC_SECY_ATTR_SCI, MACSEC_SECY_ATTR_ENCODING_SA, MACSEC_SECY_ATTR_WINDOW, MACSEC_SECY_ATTR_CIPHER_SUITE, MACSEC_SECY_ATTR_ICV_LEN, MACSEC_SECY_ATTR_PROTECT, MACSEC_SECY_ATTR_REPLAY, MACSEC_SECY_ATTR_OPER, MACSEC_SECY_ATTR_VALIDATE, MACSEC_SECY_ATTR_ENCRYPT, MACSEC_SECY_ATTR_INC_SCI, MACSEC_SECY_ATTR_ES, MACSEC_SECY_ATTR_SCB, MACSEC_SECY_ATTR_PAD, __MACSEC_SECY_ATTR_END, NUM_MACSEC_SECY_ATTR = __MACSEC_SECY_ATTR_END, MACSEC_SECY_ATTR_MAX = __MACSEC_SECY_ATTR_END - 1, }; enum macsec_rxsc_attrs { MACSEC_RXSC_ATTR_UNSPEC, MACSEC_RXSC_ATTR_SCI, /* config/dump, u64 */ MACSEC_RXSC_ATTR_ACTIVE, /* config/dump, u8 0..1 */ MACSEC_RXSC_ATTR_SA_LIST, /* dump, nested */ MACSEC_RXSC_ATTR_STATS, /* dump, nested, macsec_rxsc_stats_attr */ MACSEC_RXSC_ATTR_PAD, __MACSEC_RXSC_ATTR_END, NUM_MACSEC_RXSC_ATTR = __MACSEC_RXSC_ATTR_END, MACSEC_RXSC_ATTR_MAX = __MACSEC_RXSC_ATTR_END - 1, }; enum macsec_sa_attrs { MACSEC_SA_ATTR_UNSPEC, MACSEC_SA_ATTR_AN, /* config/dump, u8 0..3 */ MACSEC_SA_ATTR_ACTIVE, /* config/dump, u8 0..1 */ MACSEC_SA_ATTR_PN, /* config/dump, u32 */ MACSEC_SA_ATTR_KEY, /* config, data */ MACSEC_SA_ATTR_KEYID, /* config/dump, 128-bit */ MACSEC_SA_ATTR_STATS, /* dump, nested, macsec_sa_stats_attr */ MACSEC_SA_ATTR_PAD, __MACSEC_SA_ATTR_END, NUM_MACSEC_SA_ATTR = __MACSEC_SA_ATTR_END, MACSEC_SA_ATTR_MAX = __MACSEC_SA_ATTR_END - 1, }; enum macsec_nl_commands { MACSEC_CMD_GET_TXSC, MACSEC_CMD_ADD_RXSC, MACSEC_CMD_DEL_RXSC, MACSEC_CMD_UPD_RXSC, MACSEC_CMD_ADD_TXSA, MACSEC_CMD_DEL_TXSA, MACSEC_CMD_UPD_TXSA, MACSEC_CMD_ADD_RXSA, MACSEC_CMD_DEL_RXSA, MACSEC_CMD_UPD_RXSA, }; /* u64 per-RXSC stats */ enum macsec_rxsc_stats_attr { MACSEC_RXSC_STATS_ATTR_UNSPEC, MACSEC_RXSC_STATS_ATTR_IN_OCTETS_VALIDATED, MACSEC_RXSC_STATS_ATTR_IN_OCTETS_DECRYPTED, MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNCHECKED, MACSEC_RXSC_STATS_ATTR_IN_PKTS_DELAYED, MACSEC_RXSC_STATS_ATTR_IN_PKTS_OK, MACSEC_RXSC_STATS_ATTR_IN_PKTS_INVALID, MACSEC_RXSC_STATS_ATTR_IN_PKTS_LATE, MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_VALID, MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_USING_SA, MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNUSED_SA, MACSEC_RXSC_STATS_ATTR_PAD, __MACSEC_RXSC_STATS_ATTR_END, NUM_MACSEC_RXSC_STATS_ATTR = __MACSEC_RXSC_STATS_ATTR_END, MACSEC_RXSC_STATS_ATTR_MAX = __MACSEC_RXSC_STATS_ATTR_END - 1, }; /* u32 per-{RX,TX}SA stats */ enum macsec_sa_stats_attr { MACSEC_SA_STATS_ATTR_UNSPEC, MACSEC_SA_STATS_ATTR_IN_PKTS_OK, MACSEC_SA_STATS_ATTR_IN_PKTS_INVALID, MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_VALID, MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_USING_SA, MACSEC_SA_STATS_ATTR_IN_PKTS_UNUSED_SA, MACSEC_SA_STATS_ATTR_OUT_PKTS_PROTECTED, MACSEC_SA_STATS_ATTR_OUT_PKTS_ENCRYPTED, __MACSEC_SA_STATS_ATTR_END, NUM_MACSEC_SA_STATS_ATTR = __MACSEC_SA_STATS_ATTR_END, MACSEC_SA_STATS_ATTR_MAX = __MACSEC_SA_STATS_ATTR_END - 1, }; /* u64 per-TXSC stats */ enum macsec_txsc_stats_attr { MACSEC_TXSC_STATS_ATTR_UNSPEC, MACSEC_TXSC_STATS_ATTR_OUT_PKTS_PROTECTED, MACSEC_TXSC_STATS_ATTR_OUT_PKTS_ENCRYPTED, MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_PROTECTED, MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_ENCRYPTED, MACSEC_TXSC_STATS_ATTR_PAD, __MACSEC_TXSC_STATS_ATTR_END, NUM_MACSEC_TXSC_STATS_ATTR = __MACSEC_TXSC_STATS_ATTR_END, MACSEC_TXSC_STATS_ATTR_MAX = __MACSEC_TXSC_STATS_ATTR_END - 1, }; /* u64 per-SecY stats */ enum macsec_secy_stats_attr { MACSEC_SECY_STATS_ATTR_UNSPEC, MACSEC_SECY_STATS_ATTR_OUT_PKTS_UNTAGGED, MACSEC_SECY_STATS_ATTR_IN_PKTS_UNTAGGED, MACSEC_SECY_STATS_ATTR_OUT_PKTS_TOO_LONG, MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_TAG, MACSEC_SECY_STATS_ATTR_IN_PKTS_BAD_TAG, MACSEC_SECY_STATS_ATTR_IN_PKTS_UNKNOWN_SCI, MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_SCI, MACSEC_SECY_STATS_ATTR_IN_PKTS_OVERRUN, MACSEC_SECY_STATS_ATTR_PAD, __MACSEC_SECY_STATS_ATTR_END, NUM_MACSEC_SECY_STATS_ATTR = __MACSEC_SECY_STATS_ATTR_END, MACSEC_SECY_STATS_ATTR_MAX = __MACSEC_SECY_STATS_ATTR_END - 1, }; #endif /* _MACSEC_H */ libnl-3.2.29/include/linux-private/linux/genetlink.h0000644000175000017500000000322213023014600017336 00000000000000#ifndef __LINUX_GENERIC_NETLINK_H #define __LINUX_GENERIC_NETLINK_H #include #include #define GENL_NAMSIZ 16 /* length of family name */ #define GENL_MIN_ID NLMSG_MIN_TYPE #define GENL_MAX_ID 1023 struct genlmsghdr { __u8 cmd; __u8 version; __u16 reserved; }; #define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) #define GENL_ADMIN_PERM 0x01 #define GENL_CMD_CAP_DO 0x02 #define GENL_CMD_CAP_DUMP 0x04 #define GENL_CMD_CAP_HASPOL 0x08 /* * List of reserved static generic netlink identifiers: */ #define GENL_ID_GENERATE 0 #define GENL_ID_CTRL NLMSG_MIN_TYPE /************************************************************************** * Controller **************************************************************************/ enum { CTRL_CMD_UNSPEC, CTRL_CMD_NEWFAMILY, CTRL_CMD_DELFAMILY, CTRL_CMD_GETFAMILY, CTRL_CMD_NEWOPS, CTRL_CMD_DELOPS, CTRL_CMD_GETOPS, CTRL_CMD_NEWMCAST_GRP, CTRL_CMD_DELMCAST_GRP, CTRL_CMD_GETMCAST_GRP, /* unused */ __CTRL_CMD_MAX, }; #define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1) enum { CTRL_ATTR_UNSPEC, CTRL_ATTR_FAMILY_ID, CTRL_ATTR_FAMILY_NAME, CTRL_ATTR_VERSION, CTRL_ATTR_HDRSIZE, CTRL_ATTR_MAXATTR, CTRL_ATTR_OPS, CTRL_ATTR_MCAST_GROUPS, __CTRL_ATTR_MAX, }; #define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) enum { CTRL_ATTR_OP_UNSPEC, CTRL_ATTR_OP_ID, CTRL_ATTR_OP_FLAGS, __CTRL_ATTR_OP_MAX, }; #define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1) enum { CTRL_ATTR_MCAST_GRP_UNSPEC, CTRL_ATTR_MCAST_GRP_NAME, CTRL_ATTR_MCAST_GRP_ID, __CTRL_ATTR_MCAST_GRP_MAX, }; #define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1) #endif /* __LINUX_GENERIC_NETLINK_H */ libnl-3.2.29/include/linux-private/linux/snmp.h0000644000175000017500000002645713023014600016352 00000000000000/* * Definitions for MIBs * * Author: Hideaki YOSHIFUJI */ #ifndef _LINUX_SNMP_H #define _LINUX_SNMP_H /* ipstats mib definitions */ /* * RFC 1213: MIB-II * RFC 2011 (updates 1213): SNMPv2-MIB-IP * RFC 2863: Interfaces Group MIB * RFC 2465: IPv6 MIB: General Group * draft-ietf-ipv6-rfc2011-update-10.txt: MIB for IP: IP Statistics Tables */ enum { IPSTATS_MIB_NUM = 0, /* frequently written fields in fast path, kept in same cache line */ IPSTATS_MIB_INPKTS, /* InReceives */ IPSTATS_MIB_INOCTETS, /* InOctets */ IPSTATS_MIB_INDELIVERS, /* InDelivers */ IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */ IPSTATS_MIB_OUTPKTS, /* OutRequests */ IPSTATS_MIB_OUTOCTETS, /* OutOctets */ /* other fields */ IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */ IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */ IPSTATS_MIB_INNOROUTES, /* InNoRoutes */ IPSTATS_MIB_INADDRERRORS, /* InAddrErrors */ IPSTATS_MIB_INUNKNOWNPROTOS, /* InUnknownProtos */ IPSTATS_MIB_INTRUNCATEDPKTS, /* InTruncatedPkts */ IPSTATS_MIB_INDISCARDS, /* InDiscards */ IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */ IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */ IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */ IPSTATS_MIB_REASMREQDS, /* ReasmReqds */ IPSTATS_MIB_REASMOKS, /* ReasmOKs */ IPSTATS_MIB_REASMFAILS, /* ReasmFails */ IPSTATS_MIB_FRAGOKS, /* FragOKs */ IPSTATS_MIB_FRAGFAILS, /* FragFails */ IPSTATS_MIB_FRAGCREATES, /* FragCreates */ IPSTATS_MIB_INMCASTPKTS, /* InMcastPkts */ IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */ IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */ IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */ IPSTATS_MIB_INMCASTOCTETS, /* InMcastOctets */ IPSTATS_MIB_OUTMCASTOCTETS, /* OutMcastOctets */ IPSTATS_MIB_INBCASTOCTETS, /* InBcastOctets */ IPSTATS_MIB_OUTBCASTOCTETS, /* OutBcastOctets */ IPSTATS_MIB_CSUMERRORS, /* InCsumErrors */ IPSTATS_MIB_NOECTPKTS, /* InNoECTPkts */ IPSTATS_MIB_ECT1PKTS, /* InECT1Pkts */ IPSTATS_MIB_ECT0PKTS, /* InECT0Pkts */ IPSTATS_MIB_CEPKTS, /* InCEPkts */ __IPSTATS_MIB_MAX }; /* icmp mib definitions */ /* * RFC 1213: MIB-II ICMP Group * RFC 2011 (updates 1213): SNMPv2 MIB for IP: ICMP group */ enum { ICMP_MIB_NUM = 0, ICMP_MIB_INMSGS, /* InMsgs */ ICMP_MIB_INERRORS, /* InErrors */ ICMP_MIB_INDESTUNREACHS, /* InDestUnreachs */ ICMP_MIB_INTIMEEXCDS, /* InTimeExcds */ ICMP_MIB_INPARMPROBS, /* InParmProbs */ ICMP_MIB_INSRCQUENCHS, /* InSrcQuenchs */ ICMP_MIB_INREDIRECTS, /* InRedirects */ ICMP_MIB_INECHOS, /* InEchos */ ICMP_MIB_INECHOREPS, /* InEchoReps */ ICMP_MIB_INTIMESTAMPS, /* InTimestamps */ ICMP_MIB_INTIMESTAMPREPS, /* InTimestampReps */ ICMP_MIB_INADDRMASKS, /* InAddrMasks */ ICMP_MIB_INADDRMASKREPS, /* InAddrMaskReps */ ICMP_MIB_OUTMSGS, /* OutMsgs */ ICMP_MIB_OUTERRORS, /* OutErrors */ ICMP_MIB_OUTDESTUNREACHS, /* OutDestUnreachs */ ICMP_MIB_OUTTIMEEXCDS, /* OutTimeExcds */ ICMP_MIB_OUTPARMPROBS, /* OutParmProbs */ ICMP_MIB_OUTSRCQUENCHS, /* OutSrcQuenchs */ ICMP_MIB_OUTREDIRECTS, /* OutRedirects */ ICMP_MIB_OUTECHOS, /* OutEchos */ ICMP_MIB_OUTECHOREPS, /* OutEchoReps */ ICMP_MIB_OUTTIMESTAMPS, /* OutTimestamps */ ICMP_MIB_OUTTIMESTAMPREPS, /* OutTimestampReps */ ICMP_MIB_OUTADDRMASKS, /* OutAddrMasks */ ICMP_MIB_OUTADDRMASKREPS, /* OutAddrMaskReps */ ICMP_MIB_CSUMERRORS, /* InCsumErrors */ __ICMP_MIB_MAX }; #define __ICMPMSG_MIB_MAX 512 /* Out+In for all 8-bit ICMP types */ /* icmp6 mib definitions */ /* * RFC 2466: ICMPv6-MIB */ enum { ICMP6_MIB_NUM = 0, ICMP6_MIB_INMSGS, /* InMsgs */ ICMP6_MIB_INERRORS, /* InErrors */ ICMP6_MIB_OUTMSGS, /* OutMsgs */ ICMP6_MIB_OUTERRORS, /* OutErrors */ ICMP6_MIB_CSUMERRORS, /* InCsumErrors */ __ICMP6_MIB_MAX }; #define __ICMP6MSG_MIB_MAX 512 /* Out+In for all 8-bit ICMPv6 types */ /* tcp mib definitions */ /* * RFC 1213: MIB-II TCP group * RFC 2012 (updates 1213): SNMPv2-MIB-TCP */ enum { TCP_MIB_NUM = 0, TCP_MIB_RTOALGORITHM, /* RtoAlgorithm */ TCP_MIB_RTOMIN, /* RtoMin */ TCP_MIB_RTOMAX, /* RtoMax */ TCP_MIB_MAXCONN, /* MaxConn */ TCP_MIB_ACTIVEOPENS, /* ActiveOpens */ TCP_MIB_PASSIVEOPENS, /* PassiveOpens */ TCP_MIB_ATTEMPTFAILS, /* AttemptFails */ TCP_MIB_ESTABRESETS, /* EstabResets */ TCP_MIB_CURRESTAB, /* CurrEstab */ TCP_MIB_INSEGS, /* InSegs */ TCP_MIB_OUTSEGS, /* OutSegs */ TCP_MIB_RETRANSSEGS, /* RetransSegs */ TCP_MIB_INERRS, /* InErrs */ TCP_MIB_OUTRSTS, /* OutRsts */ TCP_MIB_CSUMERRORS, /* InCsumErrors */ __TCP_MIB_MAX }; /* udp mib definitions */ /* * RFC 1213: MIB-II UDP group * RFC 2013 (updates 1213): SNMPv2-MIB-UDP */ enum { UDP_MIB_NUM = 0, UDP_MIB_INDATAGRAMS, /* InDatagrams */ UDP_MIB_NOPORTS, /* NoPorts */ UDP_MIB_INERRORS, /* InErrors */ UDP_MIB_OUTDATAGRAMS, /* OutDatagrams */ UDP_MIB_RCVBUFERRORS, /* RcvbufErrors */ UDP_MIB_SNDBUFERRORS, /* SndbufErrors */ UDP_MIB_CSUMERRORS, /* InCsumErrors */ __UDP_MIB_MAX }; /* linux mib definitions */ enum { LINUX_MIB_NUM = 0, LINUX_MIB_SYNCOOKIESSENT, /* SyncookiesSent */ LINUX_MIB_SYNCOOKIESRECV, /* SyncookiesRecv */ LINUX_MIB_SYNCOOKIESFAILED, /* SyncookiesFailed */ LINUX_MIB_EMBRYONICRSTS, /* EmbryonicRsts */ LINUX_MIB_PRUNECALLED, /* PruneCalled */ LINUX_MIB_RCVPRUNED, /* RcvPruned */ LINUX_MIB_OFOPRUNED, /* OfoPruned */ LINUX_MIB_OUTOFWINDOWICMPS, /* OutOfWindowIcmps */ LINUX_MIB_LOCKDROPPEDICMPS, /* LockDroppedIcmps */ LINUX_MIB_ARPFILTER, /* ArpFilter */ LINUX_MIB_TIMEWAITED, /* TimeWaited */ LINUX_MIB_TIMEWAITRECYCLED, /* TimeWaitRecycled */ LINUX_MIB_TIMEWAITKILLED, /* TimeWaitKilled */ LINUX_MIB_PAWSPASSIVEREJECTED, /* PAWSPassiveRejected */ LINUX_MIB_PAWSACTIVEREJECTED, /* PAWSActiveRejected */ LINUX_MIB_PAWSESTABREJECTED, /* PAWSEstabRejected */ LINUX_MIB_DELAYEDACKS, /* DelayedACKs */ LINUX_MIB_DELAYEDACKLOCKED, /* DelayedACKLocked */ LINUX_MIB_DELAYEDACKLOST, /* DelayedACKLost */ LINUX_MIB_LISTENOVERFLOWS, /* ListenOverflows */ LINUX_MIB_LISTENDROPS, /* ListenDrops */ LINUX_MIB_TCPPREQUEUED, /* TCPPrequeued */ LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG, /* TCPDirectCopyFromBacklog */ LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, /* TCPDirectCopyFromPrequeue */ LINUX_MIB_TCPPREQUEUEDROPPED, /* TCPPrequeueDropped */ LINUX_MIB_TCPHPHITS, /* TCPHPHits */ LINUX_MIB_TCPHPHITSTOUSER, /* TCPHPHitsToUser */ LINUX_MIB_TCPPUREACKS, /* TCPPureAcks */ LINUX_MIB_TCPHPACKS, /* TCPHPAcks */ LINUX_MIB_TCPRENORECOVERY, /* TCPRenoRecovery */ LINUX_MIB_TCPSACKRECOVERY, /* TCPSackRecovery */ LINUX_MIB_TCPSACKRENEGING, /* TCPSACKReneging */ LINUX_MIB_TCPFACKREORDER, /* TCPFACKReorder */ LINUX_MIB_TCPSACKREORDER, /* TCPSACKReorder */ LINUX_MIB_TCPRENOREORDER, /* TCPRenoReorder */ LINUX_MIB_TCPTSREORDER, /* TCPTSReorder */ LINUX_MIB_TCPFULLUNDO, /* TCPFullUndo */ LINUX_MIB_TCPPARTIALUNDO, /* TCPPartialUndo */ LINUX_MIB_TCPDSACKUNDO, /* TCPDSACKUndo */ LINUX_MIB_TCPLOSSUNDO, /* TCPLossUndo */ LINUX_MIB_TCPLOSTRETRANSMIT, /* TCPLostRetransmit */ LINUX_MIB_TCPRENOFAILURES, /* TCPRenoFailures */ LINUX_MIB_TCPSACKFAILURES, /* TCPSackFailures */ LINUX_MIB_TCPLOSSFAILURES, /* TCPLossFailures */ LINUX_MIB_TCPFASTRETRANS, /* TCPFastRetrans */ LINUX_MIB_TCPFORWARDRETRANS, /* TCPForwardRetrans */ LINUX_MIB_TCPSLOWSTARTRETRANS, /* TCPSlowStartRetrans */ LINUX_MIB_TCPTIMEOUTS, /* TCPTimeouts */ LINUX_MIB_TCPLOSSPROBES, /* TCPLossProbes */ LINUX_MIB_TCPLOSSPROBERECOVERY, /* TCPLossProbeRecovery */ LINUX_MIB_TCPRENORECOVERYFAIL, /* TCPRenoRecoveryFail */ LINUX_MIB_TCPSACKRECOVERYFAIL, /* TCPSackRecoveryFail */ LINUX_MIB_TCPSCHEDULERFAILED, /* TCPSchedulerFailed */ LINUX_MIB_TCPRCVCOLLAPSED, /* TCPRcvCollapsed */ LINUX_MIB_TCPDSACKOLDSENT, /* TCPDSACKOldSent */ LINUX_MIB_TCPDSACKOFOSENT, /* TCPDSACKOfoSent */ LINUX_MIB_TCPDSACKRECV, /* TCPDSACKRecv */ LINUX_MIB_TCPDSACKOFORECV, /* TCPDSACKOfoRecv */ LINUX_MIB_TCPABORTONDATA, /* TCPAbortOnData */ LINUX_MIB_TCPABORTONCLOSE, /* TCPAbortOnClose */ LINUX_MIB_TCPABORTONMEMORY, /* TCPAbortOnMemory */ LINUX_MIB_TCPABORTONTIMEOUT, /* TCPAbortOnTimeout */ LINUX_MIB_TCPABORTONLINGER, /* TCPAbortOnLinger */ LINUX_MIB_TCPABORTFAILED, /* TCPAbortFailed */ LINUX_MIB_TCPMEMORYPRESSURES, /* TCPMemoryPressures */ LINUX_MIB_TCPSACKDISCARD, /* TCPSACKDiscard */ LINUX_MIB_TCPDSACKIGNOREDOLD, /* TCPSACKIgnoredOld */ LINUX_MIB_TCPDSACKIGNOREDNOUNDO, /* TCPSACKIgnoredNoUndo */ LINUX_MIB_TCPSPURIOUSRTOS, /* TCPSpuriousRTOs */ LINUX_MIB_TCPMD5NOTFOUND, /* TCPMD5NotFound */ LINUX_MIB_TCPMD5UNEXPECTED, /* TCPMD5Unexpected */ LINUX_MIB_SACKSHIFTED, LINUX_MIB_SACKMERGED, LINUX_MIB_SACKSHIFTFALLBACK, LINUX_MIB_TCPBACKLOGDROP, LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */ LINUX_MIB_TCPDEFERACCEPTDROP, LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */ LINUX_MIB_TCPREQQFULLDOCOOKIES, /* TCPReqQFullDoCookies */ LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */ LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */ LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */ LINUX_MIB_TCPOFOQUEUE, /* TCPOFOQueue */ LINUX_MIB_TCPOFODROP, /* TCPOFODrop */ LINUX_MIB_TCPOFOMERGE, /* TCPOFOMerge */ LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */ LINUX_MIB_TCPFASTOPENACTIVE, /* TCPFastOpenActive */ LINUX_MIB_TCPFASTOPENPASSIVE, /* TCPFastOpenPassive*/ LINUX_MIB_TCPFASTOPENPASSIVEFAIL, /* TCPFastOpenPassiveFail */ LINUX_MIB_TCPFASTOPENLISTENOVERFLOW, /* TCPFastOpenListenOverflow */ LINUX_MIB_TCPFASTOPENCOOKIEREQD, /* TCPFastOpenCookieReqd */ LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES, /* TCPSpuriousRtxHostQueues */ LINUX_MIB_BUSYPOLLRXPACKETS, /* BusyPollRxPackets */ __LINUX_MIB_MAX }; /* linux Xfrm mib definitions */ enum { LINUX_MIB_XFRMNUM = 0, LINUX_MIB_XFRMINERROR, /* XfrmInError */ LINUX_MIB_XFRMINBUFFERERROR, /* XfrmInBufferError */ LINUX_MIB_XFRMINHDRERROR, /* XfrmInHdrError */ LINUX_MIB_XFRMINNOSTATES, /* XfrmInNoStates */ LINUX_MIB_XFRMINSTATEPROTOERROR, /* XfrmInStateProtoError */ LINUX_MIB_XFRMINSTATEMODEERROR, /* XfrmInStateModeError */ LINUX_MIB_XFRMINSTATESEQERROR, /* XfrmInStateSeqError */ LINUX_MIB_XFRMINSTATEEXPIRED, /* XfrmInStateExpired */ LINUX_MIB_XFRMINSTATEMISMATCH, /* XfrmInStateMismatch */ LINUX_MIB_XFRMINSTATEINVALID, /* XfrmInStateInvalid */ LINUX_MIB_XFRMINTMPLMISMATCH, /* XfrmInTmplMismatch */ LINUX_MIB_XFRMINNOPOLS, /* XfrmInNoPols */ LINUX_MIB_XFRMINPOLBLOCK, /* XfrmInPolBlock */ LINUX_MIB_XFRMINPOLERROR, /* XfrmInPolError */ LINUX_MIB_XFRMOUTERROR, /* XfrmOutError */ LINUX_MIB_XFRMOUTBUNDLEGENERROR, /* XfrmOutBundleGenError */ LINUX_MIB_XFRMOUTBUNDLECHECKERROR, /* XfrmOutBundleCheckError */ LINUX_MIB_XFRMOUTNOSTATES, /* XfrmOutNoStates */ LINUX_MIB_XFRMOUTSTATEPROTOERROR, /* XfrmOutStateProtoError */ LINUX_MIB_XFRMOUTSTATEMODEERROR, /* XfrmOutStateModeError */ LINUX_MIB_XFRMOUTSTATESEQERROR, /* XfrmOutStateSeqError */ LINUX_MIB_XFRMOUTSTATEEXPIRED, /* XfrmOutStateExpired */ LINUX_MIB_XFRMOUTPOLBLOCK, /* XfrmOutPolBlock */ LINUX_MIB_XFRMOUTPOLDEAD, /* XfrmOutPolDead */ LINUX_MIB_XFRMOUTPOLERROR, /* XfrmOutPolError */ LINUX_MIB_XFRMFWDHDRERROR, /* XfrmFwdHdrError*/ LINUX_MIB_XFRMOUTSTATEINVALID, /* XfrmOutStateInvalid */ LINUX_MIB_XFRMACQUIREERROR, /* XfrmAcquireError */ __LINUX_MIB_XFRMMAX }; #endif /* _LINUX_SNMP_H */ libnl-3.2.29/include/linux-private/linux/netfilter.h0000644000175000017500000000231013023014600017347 00000000000000#ifndef __LINUX_NETFILTER_H #define __LINUX_NETFILTER_H #include /* Responses from hook functions. */ #define NF_DROP 0 #define NF_ACCEPT 1 #define NF_STOLEN 2 #define NF_QUEUE 3 #define NF_REPEAT 4 #define NF_STOP 5 #define NF_MAX_VERDICT NF_STOP /* we overload the higher bits for encoding auxiliary data such as the queue * number. Not nice, but better than additional function arguments. */ #define NF_VERDICT_MASK 0x0000ffff #define NF_VERDICT_BITS 16 #define NF_VERDICT_QMASK 0xffff0000 #define NF_VERDICT_QBITS 16 #define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE) /* Generic cache responses from hook functions. <= 0x2000 is used for protocol-flags. */ #define NFC_UNKNOWN 0x4000 #define NFC_ALTERED 0x8000 enum nf_inet_hooks { NF_INET_PRE_ROUTING, NF_INET_LOCAL_IN, NF_INET_FORWARD, NF_INET_LOCAL_OUT, NF_INET_POST_ROUTING, NF_INET_NUMHOOKS }; enum { NFPROTO_UNSPEC = 0, NFPROTO_IPV4 = 2, NFPROTO_ARP = 3, NFPROTO_BRIDGE = 7, NFPROTO_IPV6 = 10, NFPROTO_DECNET = 12, NFPROTO_NUMPROTO, }; union nf_inet_addr { __u32 all[4]; __be32 ip; __be32 ip6[4]; struct in_addr in; struct in6_addr in6; }; #endif /*__LINUX_NETFILTER_H*/ libnl-3.2.29/include/linux-private/linux/tc_act/0000755000175000017500000000000013031473756016547 500000000000000libnl-3.2.29/include/linux-private/linux/tc_act/tc_gact.h0000644000175000017500000000111013023014600020211 00000000000000#ifndef __LINUX_TC_GACT_H #define __LINUX_TC_GACT_H #include #include #define TCA_ACT_GACT 5 struct tc_gact { tc_gen; }; struct tc_gact_p { #define PGACT_NONE 0 #define PGACT_NETRAND 1 #define PGACT_DETERM 2 #define MAX_RAND (PGACT_DETERM + 1 ) __u16 ptype; __u16 pval; int paction; }; enum { TCA_GACT_UNSPEC, TCA_GACT_TM, TCA_GACT_PARMS, TCA_GACT_PROB, TCA_GACT_PAD, __TCA_GACT_MAX }; #define TCA_GACT_MAX (__TCA_GACT_MAX - 1) #endif libnl-3.2.29/include/linux-private/linux/tc_act/tc_mirred.h0000644000175000017500000000162113023014600020564 00000000000000#ifndef __LINUX_TC_MIR_H #define __LINUX_TC_MIR_H #include #include #define TCA_ACT_MIRRED 8 #define TCA_EGRESS_REDIR 1 /* packet redirect to EGRESS*/ #define TCA_EGRESS_MIRROR 2 /* mirror packet to EGRESS */ #define TCA_INGRESS_REDIR 3 /* packet redirect to INGRESS*/ #define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */ struct tc_mirred { tc_gen; int eaction; /* one of IN/EGRESS_MIRROR/REDIR */ __u32 ifindex; /* ifindex of egress port */ }; enum { TCA_MIRRED_UNSPEC, TCA_MIRRED_TM, TCA_MIRRED_PARMS, __TCA_MIRRED_MAX }; #define TCA_MIRRED_MAX (__TCA_MIRRED_MAX - 1) #endif libnl-3.2.29/include/linux-private/linux/tc_act/tc_skbedit.h0000644000175000017500000000232113023014600020725 00000000000000/* * Copyright (c) 2008, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. * * Author: Alexander Duyck */ #ifndef __LINUX_TC_SKBEDIT_H #define __LINUX_TC_SKBEDIT_H #include #define TCA_ACT_SKBEDIT 11 #define SKBEDIT_F_PRIORITY 0x1 #define SKBEDIT_F_QUEUE_MAPPING 0x2 #define SKBEDIT_F_MARK 0x4 struct tc_skbedit { tc_gen; }; enum { TCA_SKBEDIT_UNSPEC, TCA_SKBEDIT_TM, TCA_SKBEDIT_PARMS, TCA_SKBEDIT_PRIORITY, TCA_SKBEDIT_QUEUE_MAPPING, TCA_SKBEDIT_MARK, __TCA_SKBEDIT_MAX }; #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1) #endif libnl-3.2.29/include/linux-private/linux/pkt_sched.h0000644000175000017500000003360313023014600017330 00000000000000#ifndef __LINUX_PKT_SCHED_H #define __LINUX_PKT_SCHED_H #include /* Logical priority bands not depending on specific packet scheduler. Every scheduler will map them to real traffic classes, if it has no more precise mechanism to classify packets. These numbers have no special meaning, though their coincidence with obsolete IPv6 values is not occasional :-). New IPv6 drafts preferred full anarchy inspired by diffserv group. Note: TC_PRIO_BESTEFFORT does not mean that it is the most unhappy class, actually, as rule it will be handled with more care than filler or even bulk. */ #define TC_PRIO_BESTEFFORT 0 #define TC_PRIO_FILLER 1 #define TC_PRIO_BULK 2 #define TC_PRIO_INTERACTIVE_BULK 4 #define TC_PRIO_INTERACTIVE 6 #define TC_PRIO_CONTROL 7 #define TC_PRIO_MAX 15 /* Generic queue statistics, available for all the elements. Particular schedulers may have also their private records. */ struct tc_stats { __u64 bytes; /* NUmber of enqueues bytes */ __u32 packets; /* Number of enqueued packets */ __u32 drops; /* Packets dropped because of lack of resources */ __u32 overlimits; /* Number of throttle events when this * flow goes out of allocated bandwidth */ __u32 bps; /* Current flow byte rate */ __u32 pps; /* Current flow packet rate */ __u32 qlen; __u32 backlog; }; struct tc_estimator { signed char interval; unsigned char ewma_log; }; /* "Handles" --------- All the traffic control objects have 32bit identifiers, or "handles". They can be considered as opaque numbers from user API viewpoint, but actually they always consist of two fields: major and minor numbers, which are interpreted by kernel specially, that may be used by applications, though not recommended. F.e. qdisc handles always have minor number equal to zero, classes (or flows) have major equal to parent qdisc major, and minor uniquely identifying class inside qdisc. Macros to manipulate handles: */ #define TC_H_MAJ_MASK (0xFFFF0000U) #define TC_H_MIN_MASK (0x0000FFFFU) #define TC_H_MAJ(h) ((h)&TC_H_MAJ_MASK) #define TC_H_MIN(h) ((h)&TC_H_MIN_MASK) #define TC_H_MAKE(maj,min) (((maj)&TC_H_MAJ_MASK)|((min)&TC_H_MIN_MASK)) #define TC_H_UNSPEC (0U) #define TC_H_ROOT (0xFFFFFFFFU) #define TC_H_INGRESS (0xFFFFFFF1U) struct tc_ratespec { unsigned char cell_log; unsigned char __reserved; unsigned short overhead; short cell_align; unsigned short mpu; __u32 rate; }; #define TC_RTAB_SIZE 1024 struct tc_sizespec { unsigned char cell_log; unsigned char size_log; short cell_align; int overhead; unsigned int linklayer; unsigned int mpu; unsigned int mtu; unsigned int tsize; }; enum { TCA_STAB_UNSPEC, TCA_STAB_BASE, TCA_STAB_DATA, __TCA_STAB_MAX }; #define TCA_STAB_MAX (__TCA_STAB_MAX - 1) /* FIFO section */ struct tc_fifo_qopt { __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ }; /* PRIO section */ #define TCQ_PRIO_BANDS 16 #define TCQ_MIN_PRIO_BANDS 2 struct tc_prio_qopt { int bands; /* Number of bands */ __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ }; /* MULTIQ section */ struct tc_multiq_qopt { __u16 bands; /* Number of bands */ __u16 max_bands; /* Maximum number of queues */ }; /* PLUG section */ #define TCQ_PLUG_BUFFER 0 #define TCQ_PLUG_RELEASE_ONE 1 #define TCQ_PLUG_RELEASE_INDEFINITE 2 #define TCQ_PLUG_LIMIT 3 struct tc_plug_qopt { /* TCQ_PLUG_BUFFER: Inset a plug into the queue and * buffer any incoming packets * TCQ_PLUG_RELEASE_ONE: Dequeue packets from queue head * to beginning of the next plug. * TCQ_PLUG_RELEASE_INDEFINITE: Dequeue all packets from queue. * Stop buffering packets until the next TCQ_PLUG_BUFFER * command is received (just act as a pass-thru queue). * TCQ_PLUG_LIMIT: Increase/decrease queue size */ int action; __u32 limit; }; /* TBF section */ struct tc_tbf_qopt { struct tc_ratespec rate; struct tc_ratespec peakrate; __u32 limit; __u32 buffer; __u32 mtu; }; enum { TCA_TBF_UNSPEC, TCA_TBF_PARMS, TCA_TBF_RTAB, TCA_TBF_PTAB, __TCA_TBF_MAX, }; #define TCA_TBF_MAX (__TCA_TBF_MAX - 1) /* TEQL section */ /* TEQL does not require any parameters */ /* SFQ section */ struct tc_sfq_qopt { unsigned quantum; /* Bytes per round allocated to flow */ int perturb_period; /* Period of hash perturbation */ __u32 limit; /* Maximal packets in queue */ unsigned divisor; /* Hash divisor */ unsigned flows; /* Maximal number of flows */ }; struct tc_sfq_xstats { __s32 allot; }; /* * NOTE: limit, divisor and flows are hardwired to code at the moment. * * limit=flows=128, divisor=1024; * * The only reason for this is efficiency, it is possible * to change these parameters in compile time. */ /* RED section */ enum { TCA_RED_UNSPEC, TCA_RED_PARMS, TCA_RED_STAB, __TCA_RED_MAX, }; #define TCA_RED_MAX (__TCA_RED_MAX - 1) struct tc_red_qopt { __u32 limit; /* HARD maximal queue length (bytes) */ __u32 qth_min; /* Min average length threshold (bytes) */ __u32 qth_max; /* Max average length threshold (bytes) */ unsigned char Wlog; /* log(W) */ unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */ unsigned char Scell_log; /* cell size for idle damping */ unsigned char flags; #define TC_RED_ECN 1 #define TC_RED_HARDDROP 2 }; struct tc_red_xstats { __u32 early; /* Early drops */ __u32 pdrop; /* Drops due to queue limits */ __u32 other; /* Drops due to drop() calls */ __u32 marked; /* Marked packets */ }; /* GRED section */ #define MAX_DPs 16 enum { TCA_GRED_UNSPEC, TCA_GRED_PARMS, TCA_GRED_STAB, TCA_GRED_DPS, __TCA_GRED_MAX, }; #define TCA_GRED_MAX (__TCA_GRED_MAX - 1) struct tc_gred_qopt { __u32 limit; /* HARD maximal queue length (bytes) */ __u32 qth_min; /* Min average length threshold (bytes) */ __u32 qth_max; /* Max average length threshold (bytes) */ __u32 DP; /* up to 2^32 DPs */ __u32 backlog; __u32 qave; __u32 forced; __u32 early; __u32 other; __u32 pdrop; __u8 Wlog; /* log(W) */ __u8 Plog; /* log(P_max/(qth_max-qth_min)) */ __u8 Scell_log; /* cell size for idle damping */ __u8 prio; /* prio of this VQ */ __u32 packets; __u32 bytesin; }; /* gred setup */ struct tc_gred_sopt { __u32 DPs; __u32 def_DP; __u8 grio; __u8 flags; __u16 pad1; }; /* CHOKe section */ enum { TCA_CHOKE_UNSPEC, TCA_CHOKE_PARMS, TCA_CHOKE_STAB, __TCA_CHOKE_MAX, }; #define TCA_CHOKE_MAX (__TCA_CHOKE_MAX - 1) struct tc_choke_qopt { __u32 limit; /* Hard queue length (packets) */ __u32 qth_min; /* Min average threshold (packets) */ __u32 qth_max; /* Max average threshold (packets) */ unsigned char Wlog; /* log(W) */ unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */ unsigned char Scell_log; /* cell size for idle damping */ unsigned char flags; /* see RED flags */ }; struct tc_choke_xstats { __u32 early; /* Early drops */ __u32 pdrop; /* Drops due to queue limits */ __u32 other; /* Drops due to drop() calls */ __u32 marked; /* Marked packets */ __u32 matched; /* Drops due to flow match */ }; /* HTB section */ #define TC_HTB_NUMPRIO 8 #define TC_HTB_MAXDEPTH 8 #define TC_HTB_PROTOVER 3 /* the same as HTB and TC's major */ struct tc_htb_opt { struct tc_ratespec rate; struct tc_ratespec ceil; __u32 buffer; __u32 cbuffer; __u32 quantum; __u32 level; /* out only */ __u32 prio; }; struct tc_htb_glob { __u32 version; /* to match HTB/TC */ __u32 rate2quantum; /* bps->quantum divisor */ __u32 defcls; /* default class number */ __u32 debug; /* debug flags */ /* stats */ __u32 direct_pkts; /* count of non shapped packets */ }; enum { TCA_HTB_UNSPEC, TCA_HTB_PARMS, TCA_HTB_INIT, TCA_HTB_CTAB, TCA_HTB_RTAB, __TCA_HTB_MAX, }; #define TCA_HTB_MAX (__TCA_HTB_MAX - 1) struct tc_htb_xstats { __u32 lends; __u32 borrows; __u32 giants; /* too big packets (rate will not be accurate) */ __u32 tokens; __u32 ctokens; }; /* HFSC section */ struct tc_hfsc_qopt { __u16 defcls; /* default class */ }; struct tc_service_curve { __u32 m1; /* slope of the first segment in bps */ __u32 d; /* x-projection of the first segment in us */ __u32 m2; /* slope of the second segment in bps */ }; struct tc_hfsc_stats { __u64 work; /* total work done */ __u64 rtwork; /* work done by real-time criteria */ __u32 period; /* current period */ __u32 level; /* class level in hierarchy */ }; enum { TCA_HFSC_UNSPEC, TCA_HFSC_RSC, TCA_HFSC_FSC, TCA_HFSC_USC, __TCA_HFSC_MAX, }; #define TCA_HFSC_MAX (__TCA_HFSC_MAX - 1) /* CBQ section */ #define TC_CBQ_MAXPRIO 8 #define TC_CBQ_MAXLEVEL 8 #define TC_CBQ_DEF_EWMA 5 struct tc_cbq_lssopt { unsigned char change; unsigned char flags; #define TCF_CBQ_LSS_BOUNDED 1 #define TCF_CBQ_LSS_ISOLATED 2 unsigned char ewma_log; unsigned char level; #define TCF_CBQ_LSS_FLAGS 1 #define TCF_CBQ_LSS_EWMA 2 #define TCF_CBQ_LSS_MAXIDLE 4 #define TCF_CBQ_LSS_MINIDLE 8 #define TCF_CBQ_LSS_OFFTIME 0x10 #define TCF_CBQ_LSS_AVPKT 0x20 __u32 maxidle; __u32 minidle; __u32 offtime; __u32 avpkt; }; struct tc_cbq_wrropt { unsigned char flags; unsigned char priority; unsigned char cpriority; unsigned char __reserved; __u32 allot; __u32 weight; }; struct tc_cbq_ovl { unsigned char strategy; #define TC_CBQ_OVL_CLASSIC 0 #define TC_CBQ_OVL_DELAY 1 #define TC_CBQ_OVL_LOWPRIO 2 #define TC_CBQ_OVL_DROP 3 #define TC_CBQ_OVL_RCLASSIC 4 unsigned char priority2; __u16 pad; __u32 penalty; }; struct tc_cbq_police { unsigned char police; unsigned char __res1; unsigned short __res2; }; struct tc_cbq_fopt { __u32 split; __u32 defmap; __u32 defchange; }; struct tc_cbq_xstats { __u32 borrows; __u32 overactions; __s32 avgidle; __s32 undertime; }; enum { TCA_CBQ_UNSPEC, TCA_CBQ_LSSOPT, TCA_CBQ_WRROPT, TCA_CBQ_FOPT, TCA_CBQ_OVL_STRATEGY, TCA_CBQ_RATE, TCA_CBQ_RTAB, TCA_CBQ_POLICE, __TCA_CBQ_MAX, }; #define TCA_CBQ_MAX (__TCA_CBQ_MAX - 1) /* dsmark section */ enum { TCA_DSMARK_UNSPEC, TCA_DSMARK_INDICES, TCA_DSMARK_DEFAULT_INDEX, TCA_DSMARK_SET_TC_INDEX, TCA_DSMARK_MASK, TCA_DSMARK_VALUE, __TCA_DSMARK_MAX, }; #define TCA_DSMARK_MAX (__TCA_DSMARK_MAX - 1) /* fq_codel section */ enum { TCA_FQ_CODEL_UNSPEC, TCA_FQ_CODEL_TARGET, TCA_FQ_CODEL_LIMIT, TCA_FQ_CODEL_INTERVAL, TCA_FQ_CODEL_ECN, TCA_FQ_CODEL_FLOWS, TCA_FQ_CODEL_QUANTUM, __TCA_FQ_CODEL_MAX }; #define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1) /* ATM section */ enum { TCA_ATM_UNSPEC, TCA_ATM_FD, /* file/socket descriptor */ TCA_ATM_PTR, /* pointer to descriptor - later */ TCA_ATM_HDR, /* LL header */ TCA_ATM_EXCESS, /* excess traffic class (0 for CLP) */ TCA_ATM_ADDR, /* PVC address (for output only) */ TCA_ATM_STATE, /* VC state (ATM_VS_*; for output only) */ __TCA_ATM_MAX, }; #define TCA_ATM_MAX (__TCA_ATM_MAX - 1) /* Network emulator */ enum { TCA_NETEM_UNSPEC, TCA_NETEM_CORR, TCA_NETEM_DELAY_DIST, TCA_NETEM_REORDER, TCA_NETEM_CORRUPT, TCA_NETEM_LOSS, __TCA_NETEM_MAX, }; #define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1) struct tc_netem_qopt { __u32 latency; /* added delay (us) */ __u32 limit; /* fifo limit (packets) */ __u32 loss; /* random packet loss (0=none ~0=100%) */ __u32 gap; /* re-ordering gap (0 for none) */ __u32 duplicate; /* random packet dup (0=none ~0=100%) */ __u32 jitter; /* random jitter in latency (us) */ }; struct tc_netem_corr { __u32 delay_corr; /* delay correlation */ __u32 loss_corr; /* packet loss correlation */ __u32 dup_corr; /* duplicate correlation */ }; struct tc_netem_reorder { __u32 probability; __u32 correlation; }; struct tc_netem_corrupt { __u32 probability; __u32 correlation; }; enum { NETEM_LOSS_UNSPEC, NETEM_LOSS_GI, /* General Intuitive - 4 state model */ NETEM_LOSS_GE, /* Gilbert Elliot models */ __NETEM_LOSS_MAX }; #define NETEM_LOSS_MAX (__NETEM_LOSS_MAX - 1) /* State transition probablities for 4 state model */ struct tc_netem_gimodel { __u32 p13; __u32 p31; __u32 p32; __u32 p14; __u32 p23; }; /* Gilbert-Elliot models */ struct tc_netem_gemodel { __u32 p; __u32 r; __u32 h; __u32 k1; }; #define NETEM_DIST_SCALE 8192 #define NETEM_DIST_MAX 16384 /* DRR */ enum { TCA_DRR_UNSPEC, TCA_DRR_QUANTUM, __TCA_DRR_MAX }; #define TCA_DRR_MAX (__TCA_DRR_MAX - 1) struct tc_drr_stats { __u32 deficit; }; /* MQPRIO */ #define TC_QOPT_BITMASK 15 #define TC_QOPT_MAX_QUEUE 16 struct tc_mqprio_qopt { __u8 num_tc; __u8 prio_tc_map[TC_QOPT_BITMASK + 1]; __u8 hw; __u16 count[TC_QOPT_MAX_QUEUE]; __u16 offset[TC_QOPT_MAX_QUEUE]; }; /* SFB */ enum { TCA_SFB_UNSPEC, TCA_SFB_PARMS, __TCA_SFB_MAX, }; #define TCA_SFB_MAX (__TCA_SFB_MAX - 1) /* * Note: increment, decrement are Q0.16 fixed-point values. */ struct tc_sfb_qopt { __u32 rehash_interval; /* delay between hash move, in ms */ __u32 warmup_time; /* double buffering warmup time in ms (warmup_time < rehash_interval) */ __u32 max; /* max len of qlen_min */ __u32 bin_size; /* maximum queue length per bin */ __u32 increment; /* probability increment, (d1 in Blue) */ __u32 decrement; /* probability decrement, (d2 in Blue) */ __u32 limit; /* max SFB queue length */ __u32 penalty_rate; /* inelastic flows are rate limited to 'rate' pps */ __u32 penalty_burst; }; struct tc_sfb_xstats { __u32 earlydrop; __u32 penaltydrop; __u32 bucketdrop; __u32 queuedrop; __u32 childdrop; /* drops in child qdisc */ __u32 marked; __u32 maxqlen; __u32 maxprob; __u32 avgprob; }; #define SFB_MAX_PROB 0xFFFF /* QFQ */ enum { TCA_QFQ_UNSPEC, TCA_QFQ_WEIGHT, TCA_QFQ_LMAX, __TCA_QFQ_MAX }; #define TCA_QFQ_MAX (__TCA_QFQ_MAX - 1) struct tc_qfq_stats { __u32 weight; __u32 lmax; }; #endif libnl-3.2.29/include/linux-private/linux/netfilter/0000755000175000017500000000000013031473756017306 500000000000000libnl-3.2.29/include/linux-private/linux/netfilter/nfnetlink_compat.h0000644000175000017500000000457213023014600022716 00000000000000#ifndef _NFNETLINK_COMPAT_H #define _NFNETLINK_COMPAT_H #include #ifndef __KERNEL__ /* Old nfnetlink macros for userspace */ /* nfnetlink groups: Up to 32 maximum */ #define NF_NETLINK_CONNTRACK_NEW 0x00000001 #define NF_NETLINK_CONNTRACK_UPDATE 0x00000002 #define NF_NETLINK_CONNTRACK_DESTROY 0x00000004 #define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008 #define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010 #define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020 /* Generic structure for encapsulation optional netfilter information. * It is reminiscent of sockaddr, but with sa_family replaced * with attribute type. * ! This should someday be put somewhere generic as now rtnetlink and * ! nfnetlink use the same attributes methods. - J. Schulist. */ struct nfattr { __u16 nfa_len; __u16 nfa_type; /* we use 15 bits for the type, and the highest * bit to indicate whether the payload is nested */ }; /* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from * rtnetlink.h, it's time to put this in a generic file */ #define NFNL_NFA_NEST 0x8000 #define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff) #define NFA_ALIGNTO 4 #define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1)) #define NFA_OK(nfa,len) ((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr) \ && (nfa)->nfa_len <= (len)) #define NFA_NEXT(nfa,attrlen) ((attrlen) -= NFA_ALIGN((nfa)->nfa_len), \ (struct nfattr *)(((char *)(nfa)) + NFA_ALIGN((nfa)->nfa_len))) #define NFA_LENGTH(len) (NFA_ALIGN(sizeof(struct nfattr)) + (len)) #define NFA_SPACE(len) NFA_ALIGN(NFA_LENGTH(len)) #define NFA_DATA(nfa) ((void *)(((char *)(nfa)) + NFA_LENGTH(0))) #define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0)) #define NFA_NEST(skb, type) \ ({ struct nfattr *__start = (struct nfattr *)skb_tail_pointer(skb); \ NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \ __start; }) #define NFA_NEST_END(skb, start) \ ({ (start)->nfa_len = skb_tail_pointer(skb) - (unsigned char *)(start); \ (skb)->len; }) #define NFA_NEST_CANCEL(skb, start) \ ({ if (start) \ skb_trim(skb, (unsigned char *) (start) - (skb)->data); \ -1; }) #define NFM_NFA(n) ((struct nfattr *)(((char *)(n)) \ + NLMSG_ALIGN(sizeof(struct nfgenmsg)))) #define NFM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg)) #endif /* ! __KERNEL__ */ #endif /* _NFNETLINK_COMPAT_H */ libnl-3.2.29/include/linux-private/linux/netfilter/nfnetlink_log.h0000644000175000017500000000515213023014600022207 00000000000000#ifndef _NFNETLINK_LOG_H #define _NFNETLINK_LOG_H /* This file describes the netlink messages (i.e. 'protocol packets'), * and not any kind of function definitions. It is shared between kernel and * userspace. Don't put kernel specific stuff in here */ #ifndef __aligned_be64 #define __aligned_be64 u_int64_t __attribute__((aligned(8))) #endif #include #include enum nfulnl_msg_types { NFULNL_MSG_PACKET, /* packet from kernel to userspace */ NFULNL_MSG_CONFIG, /* connect to a particular queue */ NFULNL_MSG_MAX }; struct nfulnl_msg_packet_hdr { __be16 hw_protocol; /* hw protocol (network order) */ __u8 hook; /* netfilter hook */ __u8 _pad; }; struct nfulnl_msg_packet_hw { __be16 hw_addrlen; __u16 _pad; __u8 hw_addr[8]; }; struct nfulnl_msg_packet_timestamp { __aligned_be64 sec; __aligned_be64 usec; }; enum nfulnl_attr_type { NFULA_UNSPEC, NFULA_PACKET_HDR, NFULA_MARK, /* __u32 nfmark */ NFULA_TIMESTAMP, /* nfulnl_msg_packet_timestamp */ NFULA_IFINDEX_INDEV, /* __u32 ifindex */ NFULA_IFINDEX_OUTDEV, /* __u32 ifindex */ NFULA_IFINDEX_PHYSINDEV, /* __u32 ifindex */ NFULA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */ NFULA_HWADDR, /* nfulnl_msg_packet_hw */ NFULA_PAYLOAD, /* opaque data payload */ NFULA_PREFIX, /* string prefix */ NFULA_UID, /* user id of socket */ NFULA_SEQ, /* instance-local sequence number */ NFULA_SEQ_GLOBAL, /* global sequence number */ NFULA_GID, /* group id of socket */ NFULA_HWTYPE, /* hardware type */ NFULA_HWHEADER, /* hardware header */ NFULA_HWLEN, /* hardware header length */ __NFULA_MAX }; #define NFULA_MAX (__NFULA_MAX - 1) enum nfulnl_msg_config_cmds { NFULNL_CFG_CMD_NONE, NFULNL_CFG_CMD_BIND, NFULNL_CFG_CMD_UNBIND, NFULNL_CFG_CMD_PF_BIND, NFULNL_CFG_CMD_PF_UNBIND, }; struct nfulnl_msg_config_cmd { __u8 command; /* nfulnl_msg_config_cmds */ } __attribute__ ((packed)); struct nfulnl_msg_config_mode { __be32 copy_range; __u8 copy_mode; __u8 _pad; } __attribute__ ((packed)); enum nfulnl_attr_config { NFULA_CFG_UNSPEC, NFULA_CFG_CMD, /* nfulnl_msg_config_cmd */ NFULA_CFG_MODE, /* nfulnl_msg_config_mode */ NFULA_CFG_NLBUFSIZ, /* __u32 buffer size */ NFULA_CFG_TIMEOUT, /* __u32 in 1/100 s */ NFULA_CFG_QTHRESH, /* __u32 */ NFULA_CFG_FLAGS, /* __u16 */ __NFULA_CFG_MAX }; #define NFULA_CFG_MAX (__NFULA_CFG_MAX -1) #define NFULNL_COPY_NONE 0x00 #define NFULNL_COPY_META 0x01 #define NFULNL_COPY_PACKET 0x02 /* 0xff is reserved, don't use it for new copy modes. */ #define NFULNL_CFG_F_SEQ 0x0001 #define NFULNL_CFG_F_SEQ_GLOBAL 0x0002 #endif /* _NFNETLINK_LOG_H */ libnl-3.2.29/include/linux-private/linux/netfilter/nfnetlink_conntrack.h0000644000175000017500000001177113023014600023414 00000000000000#ifndef _IPCONNTRACK_NETLINK_H #define _IPCONNTRACK_NETLINK_H #include enum cntl_msg_types { IPCTNL_MSG_CT_NEW, IPCTNL_MSG_CT_GET, IPCTNL_MSG_CT_DELETE, IPCTNL_MSG_CT_GET_CTRZERO, IPCTNL_MSG_CT_GET_STATS_CPU, IPCTNL_MSG_CT_GET_STATS, IPCTNL_MSG_MAX }; enum ctnl_exp_msg_types { IPCTNL_MSG_EXP_NEW, IPCTNL_MSG_EXP_GET, IPCTNL_MSG_EXP_DELETE, IPCTNL_MSG_EXP_GET_STATS_CPU, IPCTNL_MSG_EXP_MAX }; enum ctattr_type { CTA_UNSPEC, CTA_TUPLE_ORIG, CTA_TUPLE_REPLY, CTA_STATUS, CTA_PROTOINFO, CTA_HELP, CTA_NAT_SRC, #define CTA_NAT CTA_NAT_SRC /* backwards compatibility */ CTA_TIMEOUT, CTA_MARK, CTA_COUNTERS_ORIG, CTA_COUNTERS_REPLY, CTA_USE, CTA_ID, CTA_NAT_DST, CTA_TUPLE_MASTER, CTA_NAT_SEQ_ADJ_ORIG, CTA_NAT_SEQ_ADJ_REPLY, CTA_SECMARK, /* obsolete */ CTA_ZONE, CTA_SECCTX, CTA_TIMESTAMP, CTA_MARK_MASK, __CTA_MAX }; #define CTA_MAX (__CTA_MAX - 1) enum ctattr_tuple { CTA_TUPLE_UNSPEC, CTA_TUPLE_IP, CTA_TUPLE_PROTO, __CTA_TUPLE_MAX }; #define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1) enum ctattr_ip { CTA_IP_UNSPEC, CTA_IP_V4_SRC, CTA_IP_V4_DST, CTA_IP_V6_SRC, CTA_IP_V6_DST, __CTA_IP_MAX }; #define CTA_IP_MAX (__CTA_IP_MAX - 1) enum ctattr_l4proto { CTA_PROTO_UNSPEC, CTA_PROTO_NUM, CTA_PROTO_SRC_PORT, CTA_PROTO_DST_PORT, CTA_PROTO_ICMP_ID, CTA_PROTO_ICMP_TYPE, CTA_PROTO_ICMP_CODE, CTA_PROTO_ICMPV6_ID, CTA_PROTO_ICMPV6_TYPE, CTA_PROTO_ICMPV6_CODE, __CTA_PROTO_MAX }; #define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1) enum ctattr_protoinfo { CTA_PROTOINFO_UNSPEC, CTA_PROTOINFO_TCP, CTA_PROTOINFO_DCCP, CTA_PROTOINFO_SCTP, __CTA_PROTOINFO_MAX }; #define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1) enum ctattr_protoinfo_tcp { CTA_PROTOINFO_TCP_UNSPEC, CTA_PROTOINFO_TCP_STATE, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, CTA_PROTOINFO_TCP_WSCALE_REPLY, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, CTA_PROTOINFO_TCP_FLAGS_REPLY, __CTA_PROTOINFO_TCP_MAX }; #define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1) enum ctattr_protoinfo_dccp { CTA_PROTOINFO_DCCP_UNSPEC, CTA_PROTOINFO_DCCP_STATE, CTA_PROTOINFO_DCCP_ROLE, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ, __CTA_PROTOINFO_DCCP_MAX, }; #define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1) enum ctattr_protoinfo_sctp { CTA_PROTOINFO_SCTP_UNSPEC, CTA_PROTOINFO_SCTP_STATE, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL, CTA_PROTOINFO_SCTP_VTAG_REPLY, __CTA_PROTOINFO_SCTP_MAX }; #define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1) enum ctattr_counters { CTA_COUNTERS_UNSPEC, CTA_COUNTERS_PACKETS, /* 64bit counters */ CTA_COUNTERS_BYTES, /* 64bit counters */ CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */ CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */ __CTA_COUNTERS_MAX }; #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1) enum ctattr_tstamp { CTA_TIMESTAMP_UNSPEC, CTA_TIMESTAMP_START, CTA_TIMESTAMP_STOP, __CTA_TIMESTAMP_MAX }; #define CTA_TIMESTAMP_MAX (__CTA_TIMESTAMP_MAX - 1) enum ctattr_nat { CTA_NAT_UNSPEC, CTA_NAT_V4_MINIP, #define CTA_NAT_MINIP CTA_NAT_V4_MINIP CTA_NAT_V4_MAXIP, #define CTA_NAT_MAXIP CTA_NAT_V4_MAXIP CTA_NAT_PROTO, CTA_NAT_V6_MINIP, CTA_NAT_V6_MAXIP, __CTA_NAT_MAX }; #define CTA_NAT_MAX (__CTA_NAT_MAX - 1) enum ctattr_protonat { CTA_PROTONAT_UNSPEC, CTA_PROTONAT_PORT_MIN, CTA_PROTONAT_PORT_MAX, __CTA_PROTONAT_MAX }; #define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1) enum ctattr_natseq { CTA_NAT_SEQ_UNSPEC, CTA_NAT_SEQ_CORRECTION_POS, CTA_NAT_SEQ_OFFSET_BEFORE, CTA_NAT_SEQ_OFFSET_AFTER, __CTA_NAT_SEQ_MAX }; #define CTA_NAT_SEQ_MAX (__CTA_NAT_SEQ_MAX - 1) enum ctattr_expect { CTA_EXPECT_UNSPEC, CTA_EXPECT_MASTER, CTA_EXPECT_TUPLE, CTA_EXPECT_MASK, CTA_EXPECT_TIMEOUT, CTA_EXPECT_ID, CTA_EXPECT_HELP_NAME, CTA_EXPECT_ZONE, CTA_EXPECT_FLAGS, CTA_EXPECT_CLASS, CTA_EXPECT_NAT, CTA_EXPECT_FN, __CTA_EXPECT_MAX }; #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1) enum ctattr_expect_nat { CTA_EXPECT_NAT_UNSPEC, CTA_EXPECT_NAT_DIR, CTA_EXPECT_NAT_TUPLE, __CTA_EXPECT_NAT_MAX }; #define CTA_EXPECT_NAT_MAX (__CTA_EXPECT_NAT_MAX - 1) enum ctattr_help { CTA_HELP_UNSPEC, CTA_HELP_NAME, CTA_HELP_INFO, __CTA_HELP_MAX }; #define CTA_HELP_MAX (__CTA_HELP_MAX - 1) enum ctattr_secctx { CTA_SECCTX_UNSPEC, CTA_SECCTX_NAME, __CTA_SECCTX_MAX }; #define CTA_SECCTX_MAX (__CTA_SECCTX_MAX - 1) enum ctattr_stats_cpu { CTA_STATS_UNSPEC, CTA_STATS_SEARCHED, CTA_STATS_FOUND, CTA_STATS_NEW, CTA_STATS_INVALID, CTA_STATS_IGNORE, CTA_STATS_DELETE, CTA_STATS_DELETE_LIST, CTA_STATS_INSERT, CTA_STATS_INSERT_FAILED, CTA_STATS_DROP, CTA_STATS_EARLY_DROP, CTA_STATS_ERROR, CTA_STATS_SEARCH_RESTART, __CTA_STATS_MAX, }; #define CTA_STATS_MAX (__CTA_STATS_MAX - 1) enum ctattr_stats_global { CTA_STATS_GLOBAL_UNSPEC, CTA_STATS_GLOBAL_ENTRIES, __CTA_STATS_GLOBAL_MAX, }; #define CTA_STATS_GLOBAL_MAX (__CTA_STATS_GLOBAL_MAX - 1) enum ctattr_expect_stats { CTA_STATS_EXP_UNSPEC, CTA_STATS_EXP_NEW, CTA_STATS_EXP_CREATE, CTA_STATS_EXP_DELETE, __CTA_STATS_EXP_MAX, }; #define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1) #endif /* _IPCONNTRACK_NETLINK_H */ libnl-3.2.29/include/linux-private/linux/netfilter/nfnetlink_queue.h0000644000175000017500000000503513023014600022552 00000000000000#ifndef _NFNETLINK_QUEUE_H #define _NFNETLINK_QUEUE_H #include #include #ifndef __aligned_be64 #define __aligned_be64 u_int64_t __attribute__((aligned(8))) #endif enum nfqnl_msg_types { NFQNL_MSG_PACKET, /* packet from kernel to userspace */ NFQNL_MSG_VERDICT, /* verdict from userspace to kernel */ NFQNL_MSG_CONFIG, /* connect to a particular queue */ NFQNL_MSG_VERDICT_BATCH, /* batchv from userspace to kernel */ NFQNL_MSG_MAX }; struct nfqnl_msg_packet_hdr { __be32 packet_id; /* unique ID of packet in queue */ __be16 hw_protocol; /* hw protocol (network order) */ __u8 hook; /* netfilter hook */ } __attribute__ ((packed)); struct nfqnl_msg_packet_hw { __be16 hw_addrlen; __u16 _pad; __u8 hw_addr[8]; }; struct nfqnl_msg_packet_timestamp { __aligned_be64 sec; __aligned_be64 usec; }; enum nfqnl_attr_type { NFQA_UNSPEC, NFQA_PACKET_HDR, NFQA_VERDICT_HDR, /* nfqnl_msg_verdict_hrd */ NFQA_MARK, /* __u32 nfmark */ NFQA_TIMESTAMP, /* nfqnl_msg_packet_timestamp */ NFQA_IFINDEX_INDEV, /* __u32 ifindex */ NFQA_IFINDEX_OUTDEV, /* __u32 ifindex */ NFQA_IFINDEX_PHYSINDEV, /* __u32 ifindex */ NFQA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */ NFQA_HWADDR, /* nfqnl_msg_packet_hw */ NFQA_PAYLOAD, /* opaque data payload */ NFQA_CT, /* nf_conntrack_netlink.h */ NFQA_CT_INFO, /* enum ip_conntrack_info */ NFQA_CAP_LEN, /* __u32 length of captured packet */ __NFQA_MAX }; #define NFQA_MAX (__NFQA_MAX - 1) struct nfqnl_msg_verdict_hdr { __be32 verdict; __be32 id; }; enum nfqnl_msg_config_cmds { NFQNL_CFG_CMD_NONE, NFQNL_CFG_CMD_BIND, NFQNL_CFG_CMD_UNBIND, NFQNL_CFG_CMD_PF_BIND, NFQNL_CFG_CMD_PF_UNBIND, }; struct nfqnl_msg_config_cmd { __u8 command; /* nfqnl_msg_config_cmds */ __u8 _pad; __be16 pf; /* AF_xxx for PF_[UN]BIND */ }; enum nfqnl_config_mode { NFQNL_COPY_NONE, NFQNL_COPY_META, NFQNL_COPY_PACKET, }; struct nfqnl_msg_config_params { __be32 copy_range; __u8 copy_mode; /* enum nfqnl_config_mode */ } __attribute__ ((packed)); enum nfqnl_attr_config { NFQA_CFG_UNSPEC, NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */ NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */ NFQA_CFG_QUEUE_MAXLEN, /* __u32 */ NFQA_CFG_MASK, /* identify which flags to change */ NFQA_CFG_FLAGS, /* value of these flags (__u32) */ __NFQA_CFG_MAX }; #define NFQA_CFG_MAX (__NFQA_CFG_MAX-1) /* Flags for NFQA_CFG_FLAGS */ #define NFQA_CFG_F_FAIL_OPEN (1 << 0) #define NFQA_CFG_F_CONNTRACK (1 << 1) #define NFQA_CFG_F_MAX (1 << 2) #endif /* _NFNETLINK_QUEUE_H */ libnl-3.2.29/include/linux-private/linux/netfilter/nf_conntrack_common.h0000644000175000017500000000706313023014600023376 00000000000000#ifndef _UAPI_NF_CONNTRACK_COMMON_H #define _UAPI_NF_CONNTRACK_COMMON_H /* Connection state tracking for netfilter. This is separated from, but required by, the NAT layer; it can also be used by an iptables extension. */ enum ip_conntrack_info { /* Part of an established connection (either direction). */ IP_CT_ESTABLISHED, /* Like NEW, but related to an existing connection, or ICMP error (in either direction). */ IP_CT_RELATED, /* Started a new connection to track (only IP_CT_DIR_ORIGINAL); may be a retransmission. */ IP_CT_NEW, /* >= this indicates reply direction */ IP_CT_IS_REPLY, IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY, IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY, IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY, /* Number of distinct IP_CT types (no NEW in reply dirn). */ IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1 }; /* Bitset representing status of connection. */ enum ip_conntrack_status { /* It's an expected connection: bit 0 set. This bit never changed */ IPS_EXPECTED_BIT = 0, IPS_EXPECTED = (1 << IPS_EXPECTED_BIT), /* We've seen packets both ways: bit 1 set. Can be set, not unset. */ IPS_SEEN_REPLY_BIT = 1, IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT), /* Conntrack should never be early-expired. */ IPS_ASSURED_BIT = 2, IPS_ASSURED = (1 << IPS_ASSURED_BIT), /* Connection is confirmed: originating packet has left box */ IPS_CONFIRMED_BIT = 3, IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT), /* Connection needs src nat in orig dir. This bit never changed. */ IPS_SRC_NAT_BIT = 4, IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT), /* Connection needs dst nat in orig dir. This bit never changed. */ IPS_DST_NAT_BIT = 5, IPS_DST_NAT = (1 << IPS_DST_NAT_BIT), /* Both together. */ IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT), /* Connection needs TCP sequence adjusted. */ IPS_SEQ_ADJUST_BIT = 6, IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT), /* NAT initialization bits. */ IPS_SRC_NAT_DONE_BIT = 7, IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT), IPS_DST_NAT_DONE_BIT = 8, IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT), /* Both together */ IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE), /* Connection is dying (removed from lists), can not be unset. */ IPS_DYING_BIT = 9, IPS_DYING = (1 << IPS_DYING_BIT), /* Connection has fixed timeout. */ IPS_FIXED_TIMEOUT_BIT = 10, IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT), /* Conntrack is a template */ IPS_TEMPLATE_BIT = 11, IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT), /* Conntrack is a fake untracked entry */ IPS_UNTRACKED_BIT = 12, IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT), /* Conntrack got a helper explicitly attached via CT target. */ IPS_HELPER_BIT = 13, IPS_HELPER = (1 << IPS_HELPER_BIT), }; /* Connection tracking event types */ enum ip_conntrack_events { IPCT_NEW, /* new conntrack */ IPCT_RELATED, /* related conntrack */ IPCT_DESTROY, /* destroyed conntrack */ IPCT_REPLY, /* connection has seen two-way traffic */ IPCT_ASSURED, /* connection status has changed to assured */ IPCT_PROTOINFO, /* protocol information has changed */ IPCT_HELPER, /* new helper has been set */ IPCT_MARK, /* new mark has been set */ IPCT_NATSEQADJ, /* NAT is doing sequence adjustment */ IPCT_SECMARK, /* new security mark has been set */ }; enum ip_conntrack_expect_events { IPEXP_NEW, /* new expectation */ IPEXP_DESTROY, /* destroyed expectation */ }; /* expectation flags */ #define NF_CT_EXPECT_PERMANENT 0x1 #define NF_CT_EXPECT_INACTIVE 0x2 #define NF_CT_EXPECT_USERSPACE 0x4 #endif /* _UAPI_NF_CONNTRACK_COMMON_H */ libnl-3.2.29/include/linux-private/linux/netfilter/nfnetlink.h0000644000175000017500000000321113023014600021340 00000000000000#ifndef _UAPI_NFNETLINK_H #define _UAPI_NFNETLINK_H #include #include enum nfnetlink_groups { NFNLGRP_NONE, #define NFNLGRP_NONE NFNLGRP_NONE NFNLGRP_CONNTRACK_NEW, #define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_UPDATE, #define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_DESTROY, #define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_EXP_NEW, #define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_UPDATE, #define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_DESTROY, #define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY __NFNLGRP_MAX, }; #define NFNLGRP_MAX (__NFNLGRP_MAX - 1) /* General form of address family dependent message. */ struct nfgenmsg { __u8 nfgen_family; /* AF_xxx */ __u8 version; /* nfnetlink version */ __be16 res_id; /* resource id */ }; #define NFNETLINK_V0 0 /* netfilter netlink message types are split in two pieces: * 8 bit subsystem, 8bit operation. */ #define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8) #define NFNL_MSG_TYPE(x) (x & 0x00ff) /* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS() * won't work anymore */ #define NFNL_SUBSYS_NONE 0 #define NFNL_SUBSYS_CTNETLINK 1 #define NFNL_SUBSYS_CTNETLINK_EXP 2 #define NFNL_SUBSYS_QUEUE 3 #define NFNL_SUBSYS_ULOG 4 #define NFNL_SUBSYS_OSF 5 #define NFNL_SUBSYS_IPSET 6 #define NFNL_SUBSYS_ACCT 7 #define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8 #define NFNL_SUBSYS_CTHELPER 9 #define NFNL_SUBSYS_COUNT 10 #endif /* _UAPI_NFNETLINK_H */ libnl-3.2.29/include/linux-private/linux/xfrm.h0000644000175000017500000002514413023014600016341 00000000000000#ifndef _LINUX_XFRM_H #define _LINUX_XFRM_H #include /* All of the structures in this file may not change size as they are * passed into the kernel from userspace via netlink sockets. */ /* Structure to encapsulate addresses. I do not want to use * "standard" structure. My apologies. */ typedef union { __be32 a4; __be32 a6[4]; } xfrm_address_t; /* Ident of a specific xfrm_state. It is used on input to lookup * the state by (spi,daddr,ah/esp) or to store information about * spi, protocol and tunnel address on output. */ struct xfrm_id { xfrm_address_t daddr; __be32 spi; __u8 proto; }; struct xfrm_sec_ctx { __u8 ctx_doi; __u8 ctx_alg; __u16 ctx_len; __u32 ctx_sid; char ctx_str[0]; }; /* Security Context Domains of Interpretation */ #define XFRM_SC_DOI_RESERVED 0 #define XFRM_SC_DOI_LSM 1 /* Security Context Algorithms */ #define XFRM_SC_ALG_RESERVED 0 #define XFRM_SC_ALG_SELINUX 1 /* Selector, used as selector both on policy rules (SPD) and SAs. */ struct xfrm_selector { xfrm_address_t daddr; xfrm_address_t saddr; __be16 dport; __be16 dport_mask; __be16 sport; __be16 sport_mask; __u16 family; __u8 prefixlen_d; __u8 prefixlen_s; __u8 proto; int ifindex; __kernel_uid32_t user; }; #define XFRM_INF (~(__u64)0) struct xfrm_lifetime_cfg { __u64 soft_byte_limit; __u64 hard_byte_limit; __u64 soft_packet_limit; __u64 hard_packet_limit; __u64 soft_add_expires_seconds; __u64 hard_add_expires_seconds; __u64 soft_use_expires_seconds; __u64 hard_use_expires_seconds; }; struct xfrm_lifetime_cur { __u64 bytes; __u64 packets; __u64 add_time; __u64 use_time; }; struct xfrm_replay_state { __u32 oseq; __u32 seq; __u32 bitmap; }; struct xfrm_replay_state_esn { unsigned int bmp_len; __u32 oseq; __u32 seq; __u32 oseq_hi; __u32 seq_hi; __u32 replay_window; __u32 bmp[0]; }; struct xfrm_algo { char alg_name[64]; unsigned int alg_key_len; /* in bits */ char alg_key[0]; }; struct xfrm_algo_auth { char alg_name[64]; unsigned int alg_key_len; /* in bits */ unsigned int alg_trunc_len; /* in bits */ char alg_key[0]; }; struct xfrm_algo_aead { char alg_name[64]; unsigned int alg_key_len; /* in bits */ unsigned int alg_icv_len; /* in bits */ char alg_key[0]; }; struct xfrm_stats { __u32 replay_window; __u32 replay; __u32 integrity_failed; }; enum { XFRM_POLICY_TYPE_MAIN = 0, XFRM_POLICY_TYPE_SUB = 1, XFRM_POLICY_TYPE_MAX = 2, XFRM_POLICY_TYPE_ANY = 255 }; enum { XFRM_POLICY_IN = 0, XFRM_POLICY_OUT = 1, XFRM_POLICY_FWD = 2, XFRM_POLICY_MASK = 3, XFRM_POLICY_MAX = 3 }; enum { XFRM_SHARE_ANY, /* No limitations */ XFRM_SHARE_SESSION, /* For this session only */ XFRM_SHARE_USER, /* For this user only */ XFRM_SHARE_UNIQUE /* Use once */ }; #define XFRM_MODE_TRANSPORT 0 #define XFRM_MODE_TUNNEL 1 #define XFRM_MODE_ROUTEOPTIMIZATION 2 #define XFRM_MODE_IN_TRIGGER 3 #define XFRM_MODE_BEET 4 #define XFRM_MODE_MAX 5 /* Netlink configuration messages. */ enum { XFRM_MSG_BASE = 0x10, XFRM_MSG_NEWSA = 0x10, #define XFRM_MSG_NEWSA XFRM_MSG_NEWSA XFRM_MSG_DELSA, #define XFRM_MSG_DELSA XFRM_MSG_DELSA XFRM_MSG_GETSA, #define XFRM_MSG_GETSA XFRM_MSG_GETSA XFRM_MSG_NEWPOLICY, #define XFRM_MSG_NEWPOLICY XFRM_MSG_NEWPOLICY XFRM_MSG_DELPOLICY, #define XFRM_MSG_DELPOLICY XFRM_MSG_DELPOLICY XFRM_MSG_GETPOLICY, #define XFRM_MSG_GETPOLICY XFRM_MSG_GETPOLICY XFRM_MSG_ALLOCSPI, #define XFRM_MSG_ALLOCSPI XFRM_MSG_ALLOCSPI XFRM_MSG_ACQUIRE, #define XFRM_MSG_ACQUIRE XFRM_MSG_ACQUIRE XFRM_MSG_EXPIRE, #define XFRM_MSG_EXPIRE XFRM_MSG_EXPIRE XFRM_MSG_UPDPOLICY, #define XFRM_MSG_UPDPOLICY XFRM_MSG_UPDPOLICY XFRM_MSG_UPDSA, #define XFRM_MSG_UPDSA XFRM_MSG_UPDSA XFRM_MSG_POLEXPIRE, #define XFRM_MSG_POLEXPIRE XFRM_MSG_POLEXPIRE XFRM_MSG_FLUSHSA, #define XFRM_MSG_FLUSHSA XFRM_MSG_FLUSHSA XFRM_MSG_FLUSHPOLICY, #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY XFRM_MSG_NEWAE, #define XFRM_MSG_NEWAE XFRM_MSG_NEWAE XFRM_MSG_GETAE, #define XFRM_MSG_GETAE XFRM_MSG_GETAE XFRM_MSG_REPORT, #define XFRM_MSG_REPORT XFRM_MSG_REPORT XFRM_MSG_MIGRATE, #define XFRM_MSG_MIGRATE XFRM_MSG_MIGRATE XFRM_MSG_NEWSADINFO, #define XFRM_MSG_NEWSADINFO XFRM_MSG_NEWSADINFO XFRM_MSG_GETSADINFO, #define XFRM_MSG_GETSADINFO XFRM_MSG_GETSADINFO XFRM_MSG_NEWSPDINFO, #define XFRM_MSG_NEWSPDINFO XFRM_MSG_NEWSPDINFO XFRM_MSG_GETSPDINFO, #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO XFRM_MSG_MAPPING, #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING __XFRM_MSG_MAX }; #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) /* * Generic LSM security context for comunicating to user space * NOTE: Same format as sadb_x_sec_ctx */ struct xfrm_user_sec_ctx { __u16 len; __u16 exttype; __u8 ctx_alg; /* LSMs: e.g., selinux == 1 */ __u8 ctx_doi; __u16 ctx_len; }; struct xfrm_user_tmpl { struct xfrm_id id; __u16 family; xfrm_address_t saddr; __u32 reqid; __u8 mode; __u8 share; __u8 optional; __u32 aalgos; __u32 ealgos; __u32 calgos; }; struct xfrm_encap_tmpl { __u16 encap_type; __be16 encap_sport; __be16 encap_dport; xfrm_address_t encap_oa; }; /* AEVENT flags */ enum xfrm_ae_ftype_t { XFRM_AE_UNSPEC, XFRM_AE_RTHR=1, /* replay threshold*/ XFRM_AE_RVAL=2, /* replay value */ XFRM_AE_LVAL=4, /* lifetime value */ XFRM_AE_ETHR=8, /* expiry timer threshold */ XFRM_AE_CR=16, /* Event cause is replay update */ XFRM_AE_CE=32, /* Event cause is timer expiry */ XFRM_AE_CU=64, /* Event cause is policy update */ __XFRM_AE_MAX #define XFRM_AE_MAX (__XFRM_AE_MAX - 1) }; struct xfrm_userpolicy_type { __u8 type; __u16 reserved1; __u8 reserved2; }; /* Netlink message attributes. */ enum xfrm_attr_type_t { XFRMA_UNSPEC, XFRMA_ALG_AUTH, /* struct xfrm_algo */ XFRMA_ALG_CRYPT, /* struct xfrm_algo */ XFRMA_ALG_COMP, /* struct xfrm_algo */ XFRMA_ENCAP, /* struct xfrm_algo + struct xfrm_encap_tmpl */ XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ XFRMA_SA, /* struct xfrm_usersa_info */ XFRMA_POLICY, /*struct xfrm_userpolicy_info */ XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */ XFRMA_LTIME_VAL, XFRMA_REPLAY_VAL, XFRMA_REPLAY_THRESH, XFRMA_ETIMER_THRESH, XFRMA_SRCADDR, /* xfrm_address_t */ XFRMA_COADDR, /* xfrm_address_t */ XFRMA_LASTUSED, /* unsigned long */ XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */ XFRMA_MIGRATE, XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */ XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */ XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */ XFRMA_MARK, /* struct xfrm_mark */ XFRMA_TFCPAD, /* __u32 */ XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_esn */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) }; struct xfrm_mark { __u32 v; /* value */ __u32 m; /* mask */ }; enum xfrm_sadattr_type_t { XFRMA_SAD_UNSPEC, XFRMA_SAD_CNT, XFRMA_SAD_HINFO, __XFRMA_SAD_MAX #define XFRMA_SAD_MAX (__XFRMA_SAD_MAX - 1) }; struct xfrmu_sadhinfo { __u32 sadhcnt; /* current hash bkts */ __u32 sadhmcnt; /* max allowed hash bkts */ }; enum xfrm_spdattr_type_t { XFRMA_SPD_UNSPEC, XFRMA_SPD_INFO, XFRMA_SPD_HINFO, __XFRMA_SPD_MAX #define XFRMA_SPD_MAX (__XFRMA_SPD_MAX - 1) }; struct xfrmu_spdinfo { __u32 incnt; __u32 outcnt; __u32 fwdcnt; __u32 inscnt; __u32 outscnt; __u32 fwdscnt; }; struct xfrmu_spdhinfo { __u32 spdhcnt; __u32 spdhmcnt; }; struct xfrm_usersa_info { struct xfrm_selector sel; struct xfrm_id id; xfrm_address_t saddr; struct xfrm_lifetime_cfg lft; struct xfrm_lifetime_cur curlft; struct xfrm_stats stats; __u32 seq; __u32 reqid; __u16 family; __u8 mode; /* XFRM_MODE_xxx */ __u8 replay_window; __u8 flags; #define XFRM_STATE_NOECN 1 #define XFRM_STATE_DECAP_DSCP 2 #define XFRM_STATE_NOPMTUDISC 4 #define XFRM_STATE_WILDRECV 8 #define XFRM_STATE_ICMP 16 #define XFRM_STATE_AF_UNSPEC 32 #define XFRM_STATE_ALIGN4 64 #define XFRM_STATE_ESN 128 }; struct xfrm_usersa_id { xfrm_address_t daddr; __be32 spi; __u16 family; __u8 proto; }; struct xfrm_aevent_id { struct xfrm_usersa_id sa_id; xfrm_address_t saddr; __u32 flags; __u32 reqid; }; struct xfrm_userspi_info { struct xfrm_usersa_info info; __u32 min; __u32 max; }; struct xfrm_userpolicy_info { struct xfrm_selector sel; struct xfrm_lifetime_cfg lft; struct xfrm_lifetime_cur curlft; __u32 priority; __u32 index; __u8 dir; __u8 action; #define XFRM_POLICY_ALLOW 0 #define XFRM_POLICY_BLOCK 1 __u8 flags; #define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */ /* Automatically expand selector to include matching ICMP payloads. */ #define XFRM_POLICY_ICMP 2 __u8 share; }; struct xfrm_userpolicy_id { struct xfrm_selector sel; __u32 index; __u8 dir; }; struct xfrm_user_acquire { struct xfrm_id id; xfrm_address_t saddr; struct xfrm_selector sel; struct xfrm_userpolicy_info policy; __u32 aalgos; __u32 ealgos; __u32 calgos; __u32 seq; }; struct xfrm_user_expire { struct xfrm_usersa_info state; __u8 hard; }; struct xfrm_user_polexpire { struct xfrm_userpolicy_info pol; __u8 hard; }; struct xfrm_usersa_flush { __u8 proto; }; struct xfrm_user_report { __u8 proto; struct xfrm_selector sel; }; /* Used by MIGRATE to pass addresses IKE should use to perform * SA negotiation with the peer */ struct xfrm_user_kmaddress { xfrm_address_t local; xfrm_address_t remote; __u32 reserved; __u16 family; }; struct xfrm_user_migrate { xfrm_address_t old_daddr; xfrm_address_t old_saddr; xfrm_address_t new_daddr; xfrm_address_t new_saddr; __u8 proto; __u8 mode; __u16 reserved; __u32 reqid; __u16 old_family; __u16 new_family; }; struct xfrm_user_mapping { struct xfrm_usersa_id id; __u32 reqid; xfrm_address_t old_saddr; xfrm_address_t new_saddr; __be16 old_sport; __be16 new_sport; }; /* backwards compatibility for userspace */ #define XFRMGRP_ACQUIRE 1 #define XFRMGRP_EXPIRE 2 #define XFRMGRP_SA 4 #define XFRMGRP_POLICY 8 #define XFRMGRP_REPORT 0x20 enum xfrm_nlgroups { XFRMNLGRP_NONE, #define XFRMNLGRP_NONE XFRMNLGRP_NONE XFRMNLGRP_ACQUIRE, #define XFRMNLGRP_ACQUIRE XFRMNLGRP_ACQUIRE XFRMNLGRP_EXPIRE, #define XFRMNLGRP_EXPIRE XFRMNLGRP_EXPIRE XFRMNLGRP_SA, #define XFRMNLGRP_SA XFRMNLGRP_SA XFRMNLGRP_POLICY, #define XFRMNLGRP_POLICY XFRMNLGRP_POLICY XFRMNLGRP_AEVENTS, #define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS XFRMNLGRP_REPORT, #define XFRMNLGRP_REPORT XFRMNLGRP_REPORT XFRMNLGRP_MIGRATE, #define XFRMNLGRP_MIGRATE XFRMNLGRP_MIGRATE XFRMNLGRP_MAPPING, #define XFRMNLGRP_MAPPING XFRMNLGRP_MAPPING __XFRMNLGRP_MAX }; #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1) #endif /* _LINUX_XFRM_H */ libnl-3.2.29/include/linux-private/linux/if_bridge.h0000644000175000017500000001062113023014600017271 00000000000000/* * Linux ethernet bridge * * Authors: * Lennert Buytenhek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #ifndef _LINUX_IF_BRIDGE_H #define _LINUX_IF_BRIDGE_H #include #include #include #define SYSFS_BRIDGE_ATTR "bridge" #define SYSFS_BRIDGE_FDB "brforward" #define SYSFS_BRIDGE_PORT_SUBDIR "brif" #define SYSFS_BRIDGE_PORT_ATTR "brport" #define SYSFS_BRIDGE_PORT_LINK "bridge" #define BRCTL_VERSION 1 #define BRCTL_GET_VERSION 0 #define BRCTL_GET_BRIDGES 1 #define BRCTL_ADD_BRIDGE 2 #define BRCTL_DEL_BRIDGE 3 #define BRCTL_ADD_IF 4 #define BRCTL_DEL_IF 5 #define BRCTL_GET_BRIDGE_INFO 6 #define BRCTL_GET_PORT_LIST 7 #define BRCTL_SET_BRIDGE_FORWARD_DELAY 8 #define BRCTL_SET_BRIDGE_HELLO_TIME 9 #define BRCTL_SET_BRIDGE_MAX_AGE 10 #define BRCTL_SET_AGEING_TIME 11 #define BRCTL_SET_GC_INTERVAL 12 #define BRCTL_GET_PORT_INFO 13 #define BRCTL_SET_BRIDGE_STP_STATE 14 #define BRCTL_SET_BRIDGE_PRIORITY 15 #define BRCTL_SET_PORT_PRIORITY 16 #define BRCTL_SET_PATH_COST 17 #define BRCTL_GET_FDB_ENTRIES 18 #define BR_STATE_DISABLED 0 #define BR_STATE_LISTENING 1 #define BR_STATE_LEARNING 2 #define BR_STATE_FORWARDING 3 #define BR_STATE_BLOCKING 4 struct __bridge_info { __u64 designated_root; __u64 bridge_id; __u32 root_path_cost; __u32 max_age; __u32 hello_time; __u32 forward_delay; __u32 bridge_max_age; __u32 bridge_hello_time; __u32 bridge_forward_delay; __u8 topology_change; __u8 topology_change_detected; __u8 root_port; __u8 stp_enabled; __u32 ageing_time; __u32 gc_interval; __u32 hello_timer_value; __u32 tcn_timer_value; __u32 topology_change_timer_value; __u32 gc_timer_value; }; struct __port_info { __u64 designated_root; __u64 designated_bridge; __u16 port_id; __u16 designated_port; __u32 path_cost; __u32 designated_cost; __u8 state; __u8 top_change_ack; __u8 config_pending; __u8 unused0; __u32 message_age_timer_value; __u32 forward_delay_timer_value; __u32 hold_timer_value; }; struct __fdb_entry { __u8 mac_addr[ETH_ALEN]; __u8 port_no; __u8 is_local; __u32 ageing_timer_value; __u8 port_hi; __u8 pad0; __u16 unused; }; /* Bridge Flags */ #define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */ #define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */ #define BRIDGE_MODE_VEB 0 /* Default loopback mode */ #define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */ #define BRIDGE_MODE_UNDEF 0xFFFF /* mode undefined */ /* Bridge management nested attributes * [IFLA_AF_SPEC] = { * [IFLA_BRIDGE_FLAGS] * [IFLA_BRIDGE_MODE] * [IFLA_BRIDGE_VLAN_INFO] * } */ enum { IFLA_BRIDGE_FLAGS, IFLA_BRIDGE_MODE, IFLA_BRIDGE_VLAN_INFO, __IFLA_BRIDGE_MAX, }; #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) #define BRIDGE_VLAN_INFO_MASTER (1<<0) /* Operate on Bridge device as well */ #define BRIDGE_VLAN_INFO_PVID (1<<1) /* VLAN is PVID, ingress untagged */ #define BRIDGE_VLAN_INFO_UNTAGGED (1<<2) /* VLAN egresses untagged */ #define BRIDGE_VLAN_INFO_RANGE_BEGIN (1<<3) /* VLAN is start of vlan range */ #define BRIDGE_VLAN_INFO_RANGE_END (1<<4) /* VLAN is end of vlan range */ struct bridge_vlan_info { __u16 flags; __u16 vid; }; /* Bridge multicast database attributes * [MDBA_MDB] = { * [MDBA_MDB_ENTRY] = { * [MDBA_MDB_ENTRY_INFO] * } * } * [MDBA_ROUTER] = { * [MDBA_ROUTER_PORT] * } */ enum { MDBA_UNSPEC, MDBA_MDB, MDBA_ROUTER, __MDBA_MAX, }; #define MDBA_MAX (__MDBA_MAX - 1) enum { MDBA_MDB_UNSPEC, MDBA_MDB_ENTRY, __MDBA_MDB_MAX, }; #define MDBA_MDB_MAX (__MDBA_MDB_MAX - 1) enum { MDBA_MDB_ENTRY_UNSPEC, MDBA_MDB_ENTRY_INFO, __MDBA_MDB_ENTRY_MAX, }; #define MDBA_MDB_ENTRY_MAX (__MDBA_MDB_ENTRY_MAX - 1) enum { MDBA_ROUTER_UNSPEC, MDBA_ROUTER_PORT, __MDBA_ROUTER_MAX, }; #define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1) struct br_port_msg { __u8 family; __u32 ifindex; }; struct br_mdb_entry { __u32 ifindex; #define MDB_TEMPORARY 0 #define MDB_PERMANENT 1 __u8 state; __u16 vid; struct { union { __be32 ip4; struct in6_addr ip6; } u; __be16 proto; } addr; }; enum { MDBA_SET_ENTRY_UNSPEC, MDBA_SET_ENTRY, __MDBA_SET_ENTRY_MAX, }; #define MDBA_SET_ENTRY_MAX (__MDBA_SET_ENTRY_MAX - 1) #endif /* _LINUX_IF_BRIDGE_H */ libnl-3.2.29/include/linux-private/linux/tc_ematch/0000755000175000017500000000000013031473756017241 500000000000000libnl-3.2.29/include/linux-private/linux/tc_ematch/tc_em_meta.h0000644000175000017500000000365013023014600021407 00000000000000#ifndef __LINUX_TC_EM_META_H #define __LINUX_TC_EM_META_H enum { TCA_EM_META_UNSPEC, TCA_EM_META_HDR, TCA_EM_META_LVALUE, TCA_EM_META_RVALUE, __TCA_EM_META_MAX }; #define TCA_EM_META_MAX (__TCA_EM_META_MAX - 1) struct tcf_meta_val { __u16 kind; __u8 shift; __u8 op; }; #define TCF_META_TYPE_MASK (0xf << 12) #define TCF_META_TYPE(kind) (((kind) & TCF_META_TYPE_MASK) >> 12) #define TCF_META_ID_MASK 0x7ff #define TCF_META_ID(kind) ((kind) & TCF_META_ID_MASK) enum { TCF_META_TYPE_VAR, TCF_META_TYPE_INT, __TCF_META_TYPE_MAX }; #define TCF_META_TYPE_MAX (__TCF_META_TYPE_MAX - 1) enum { TCF_META_ID_VALUE, TCF_META_ID_RANDOM, TCF_META_ID_LOADAVG_0, TCF_META_ID_LOADAVG_1, TCF_META_ID_LOADAVG_2, TCF_META_ID_DEV, TCF_META_ID_PRIORITY, TCF_META_ID_PROTOCOL, TCF_META_ID_PKTTYPE, TCF_META_ID_PKTLEN, TCF_META_ID_DATALEN, TCF_META_ID_MACLEN, TCF_META_ID_NFMARK, TCF_META_ID_TCINDEX, TCF_META_ID_RTCLASSID, TCF_META_ID_RTIIF, TCF_META_ID_SK_FAMILY, TCF_META_ID_SK_STATE, TCF_META_ID_SK_REUSE, TCF_META_ID_SK_BOUND_IF, TCF_META_ID_SK_REFCNT, TCF_META_ID_SK_SHUTDOWN, TCF_META_ID_SK_PROTO, TCF_META_ID_SK_TYPE, TCF_META_ID_SK_RCVBUF, TCF_META_ID_SK_RMEM_ALLOC, TCF_META_ID_SK_WMEM_ALLOC, TCF_META_ID_SK_OMEM_ALLOC, TCF_META_ID_SK_WMEM_QUEUED, TCF_META_ID_SK_RCV_QLEN, TCF_META_ID_SK_SND_QLEN, TCF_META_ID_SK_ERR_QLEN, TCF_META_ID_SK_FORWARD_ALLOCS, TCF_META_ID_SK_SNDBUF, TCF_META_ID_SK_ALLOCS, TCF_META_ID_SK_ROUTE_CAPS, TCF_META_ID_SK_HASH, TCF_META_ID_SK_LINGERTIME, TCF_META_ID_SK_ACK_BACKLOG, TCF_META_ID_SK_MAX_ACK_BACKLOG, TCF_META_ID_SK_PRIO, TCF_META_ID_SK_RCVLOWAT, TCF_META_ID_SK_RCVTIMEO, TCF_META_ID_SK_SNDTIMEO, TCF_META_ID_SK_SENDMSG_OFF, TCF_META_ID_SK_WRITE_PENDING, TCF_META_ID_VLAN_TAG, TCF_META_ID_RXHASH, __TCF_META_ID_MAX }; #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) struct tcf_meta_hdr { struct tcf_meta_val left; struct tcf_meta_val right; }; #endif libnl-3.2.29/include/linux-private/linux/if.h0000644000175000017500000001273213023014600015762 00000000000000/* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * Global definitions for the INET interface module. * * Version: @(#)if.h 1.0.2 04/18/93 * * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988 * Ross Biro * Fred N. van Kempen, * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #ifndef _LINUX_IF_H #define _LINUX_IF_H #define IFNAMSIZ 16 #define IFALIASZ 256 /* Standard interface flags (netdevice->flags). */ #define IFF_UP 0x1 /* interface is up */ #define IFF_BROADCAST 0x2 /* broadcast address valid */ #define IFF_DEBUG 0x4 /* turn on debugging */ #define IFF_LOOPBACK 0x8 /* is a loopback net */ #define IFF_POINTOPOINT 0x10 /* interface is has p-p link */ #define IFF_NOTRAILERS 0x20 /* avoid use of trailers */ #define IFF_RUNNING 0x40 /* interface RFC2863 OPER_UP */ #define IFF_NOARP 0x80 /* no ARP protocol */ #define IFF_PROMISC 0x100 /* receive all packets */ #define IFF_ALLMULTI 0x200 /* receive all multicast packets*/ #define IFF_MASTER 0x400 /* master of a load balancer */ #define IFF_SLAVE 0x800 /* slave of a load balancer */ #define IFF_MULTICAST 0x1000 /* Supports multicast */ #define IFF_PORTSEL 0x2000 /* can set media type */ #define IFF_AUTOMEDIA 0x4000 /* auto media select active */ #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/ #define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ #define IFF_DORMANT 0x20000 /* driver signals dormant */ #define IFF_ECHO 0x40000 /* echo sent packets */ #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) /* Private (from user) interface flags (netdevice->priv_flags). */ #define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */ #define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */ #define IFF_SLAVE_INACTIVE 0x4 /* bonding slave not the curr. active */ #define IFF_MASTER_8023AD 0x8 /* bonding master, 802.3ad. */ #define IFF_MASTER_ALB 0x10 /* bonding master, balance-alb. */ #define IFF_BONDING 0x20 /* bonding master or slave */ #define IFF_SLAVE_NEEDARP 0x40 /* need ARPs for validation */ #define IFF_ISATAP 0x80 /* ISATAP interface (RFC4214) */ #define IFF_MASTER_ARPMON 0x100 /* bonding master, ARP mon in use */ #define IFF_WAN_HDLC 0x200 /* WAN HDLC device */ #define IFF_XMIT_DST_RELEASE 0x400 /* dev_hard_start_xmit() is allowed to * release skb->dst */ #define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */ #define IFF_IN_NETPOLL 0x1000 /* whether we are processing netpoll */ #define IFF_DISABLE_NETPOLL 0x2000 /* disable netpoll at run-time */ #define IFF_MACVLAN_PORT 0x4000 /* device used as macvlan port */ #define IFF_BRIDGE_PORT 0x8000 /* device used as bridge port */ #define IFF_OVS_DATAPATH 0x10000 /* device used as Open vSwitch * datapath port */ #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 /* For definitions see hdlc.h */ #define IF_IFACE_V35 0x1000 /* V.35 serial interface */ #define IF_IFACE_V24 0x1001 /* V.24 serial interface */ #define IF_IFACE_X21 0x1002 /* X.21 serial interface */ #define IF_IFACE_T1 0x1003 /* T1 telco serial interface */ #define IF_IFACE_E1 0x1004 /* E1 telco serial interface */ #define IF_IFACE_SYNC_SERIAL 0x1005 /* can't be set by software */ #define IF_IFACE_X21D 0x1006 /* X.21 Dual Clocking (FarSite) */ /* For definitions see hdlc.h */ #define IF_PROTO_HDLC 0x2000 /* raw HDLC protocol */ #define IF_PROTO_PPP 0x2001 /* PPP protocol */ #define IF_PROTO_CISCO 0x2002 /* Cisco HDLC protocol */ #define IF_PROTO_FR 0x2003 /* Frame Relay protocol */ #define IF_PROTO_FR_ADD_PVC 0x2004 /* Create FR PVC */ #define IF_PROTO_FR_DEL_PVC 0x2005 /* Delete FR PVC */ #define IF_PROTO_X25 0x2006 /* X.25 */ #define IF_PROTO_HDLC_ETH 0x2007 /* raw HDLC, Ethernet emulation */ #define IF_PROTO_FR_ADD_ETH_PVC 0x2008 /* Create FR Ethernet-bridged PVC */ #define IF_PROTO_FR_DEL_ETH_PVC 0x2009 /* Delete FR Ethernet-bridged PVC */ #define IF_PROTO_FR_PVC 0x200A /* for reading PVC status */ #define IF_PROTO_FR_ETH_PVC 0x200B #define IF_PROTO_RAW 0x200C /* RAW Socket */ /* RFC 2863 operational status */ enum { IF_OPER_UNKNOWN, IF_OPER_NOTPRESENT, IF_OPER_DOWN, IF_OPER_LOWERLAYERDOWN, IF_OPER_TESTING, IF_OPER_DORMANT, IF_OPER_UP, }; /* link modes */ enum { IF_LINK_MODE_DEFAULT, IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */ }; /* carrier state */ enum { IF_CARRIER_DOWN, IF_CARRIER_UP }; /* * Device mapping structure. I'd just gone off and designed a * beautiful scheme using only loadable modules with arguments * for driver options and along come the PCMCIA people 8) * * Ah well. The get() side of this is good for WDSETUP, and it'll * be handy for debugging things. The set side is fine for now and * being very small might be worth keeping for clean configuration. */ struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; /* 3 bytes spare */ }; #endif /* _LINUX_IF_H */ libnl-3.2.29/include/linux-private/linux/ip_mp_alg.h0000644000175000017500000000071113023014600017305 00000000000000/* ip_mp_alg.h: IPV4 multipath algorithm support, user-visible values. * * Copyright (C) 2004, 2005 Einar Lueck * Copyright (C) 2005 David S. Miller */ #ifndef _LINUX_IP_MP_ALG_H #define _LINUX_IP_MP_ALG_H enum ip_mp_alg { IP_MP_ALG_NONE, IP_MP_ALG_RR, IP_MP_ALG_DRR, IP_MP_ALG_RANDOM, IP_MP_ALG_WRANDOM, __IP_MP_ALG_MAX }; #define IP_MP_ALG_MAX (__IP_MP_ALG_MAX - 1) #endif /* _LINUX_IP_MP_ALG_H */ libnl-3.2.29/include/linux-private/linux/neighbour.h0000644000175000017500000000767013023014600017353 00000000000000#ifndef __LINUX_NEIGHBOUR_H #define __LINUX_NEIGHBOUR_H #include #include struct ndmsg { __u8 ndm_family; __u8 ndm_pad1; __u16 ndm_pad2; __s32 ndm_ifindex; __u16 ndm_state; __u8 ndm_flags; __u8 ndm_type; }; enum { NDA_UNSPEC, NDA_DST, NDA_LLADDR, NDA_CACHEINFO, NDA_PROBES, NDA_VLAN, __NDA_MAX }; #define NDA_MAX (__NDA_MAX - 1) /* * Neighbor Cache Entry Flags */ #define NTF_USE 0x01 #define NTF_SELF 0x02 #define NTF_MASTER 0x04 #define NTF_PROXY 0x08 /* == ATF_PUBL */ #define NTF_ROUTER 0x80 /* * Neighbor Cache Entry States. */ #define NUD_INCOMPLETE 0x01 #define NUD_REACHABLE 0x02 #define NUD_STALE 0x04 #define NUD_DELAY 0x08 #define NUD_PROBE 0x10 #define NUD_FAILED 0x20 /* Dummy states */ #define NUD_NOARP 0x40 #define NUD_PERMANENT 0x80 #define NUD_NONE 0x00 /* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change and make no address resolution or NUD. NUD_PERMANENT is also cannot be deleted by garbage collectors. */ struct nda_cacheinfo { __u32 ndm_confirmed; __u32 ndm_used; __u32 ndm_updated; __u32 ndm_refcnt; }; /***************************************************************** * Neighbour tables specific messages. * * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the * NLM_F_DUMP flag set. Every neighbour table configuration is * spread over multiple messages to avoid running into message * size limits on systems with many interfaces. The first message * in the sequence transports all not device specific data such as * statistics, configuration, and the default parameter set. * This message is followed by 0..n messages carrying device * specific parameter sets. * Although the ordering should be sufficient, NDTA_NAME can be * used to identify sequences. The initial message can be identified * by checking for NDTA_CONFIG. The device specific messages do * not contain this TLV but have NDTPA_IFINDEX set to the * corresponding interface index. * * To change neighbour table attributes, send RTM_SETNEIGHTBL * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3], * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked * otherwise. Device specific parameter sets can be changed by * setting NDTPA_IFINDEX to the interface index of the corresponding * device. ****/ struct ndt_stats { __u64 ndts_allocs; __u64 ndts_destroys; __u64 ndts_hash_grows; __u64 ndts_res_failed; __u64 ndts_lookups; __u64 ndts_hits; __u64 ndts_rcv_probes_mcast; __u64 ndts_rcv_probes_ucast; __u64 ndts_periodic_gc_runs; __u64 ndts_forced_gc_runs; }; enum { NDTPA_UNSPEC, NDTPA_IFINDEX, /* u32, unchangeable */ NDTPA_REFCNT, /* u32, read-only */ NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */ NDTPA_BASE_REACHABLE_TIME, /* u64, msecs */ NDTPA_RETRANS_TIME, /* u64, msecs */ NDTPA_GC_STALETIME, /* u64, msecs */ NDTPA_DELAY_PROBE_TIME, /* u64, msecs */ NDTPA_QUEUE_LEN, /* u32 */ NDTPA_APP_PROBES, /* u32 */ NDTPA_UCAST_PROBES, /* u32 */ NDTPA_MCAST_PROBES, /* u32 */ NDTPA_ANYCAST_DELAY, /* u64, msecs */ NDTPA_PROXY_DELAY, /* u64, msecs */ NDTPA_PROXY_QLEN, /* u32 */ NDTPA_LOCKTIME, /* u64, msecs */ __NDTPA_MAX }; #define NDTPA_MAX (__NDTPA_MAX - 1) struct ndtmsg { __u8 ndtm_family; __u8 ndtm_pad1; __u16 ndtm_pad2; }; struct ndt_config { __u16 ndtc_key_len; __u16 ndtc_entry_size; __u32 ndtc_entries; __u32 ndtc_last_flush; /* delta to now in msecs */ __u32 ndtc_last_rand; /* delta to now in msecs */ __u32 ndtc_hash_rnd; __u32 ndtc_hash_mask; __u32 ndtc_hash_chain_gc; __u32 ndtc_proxy_qlen; }; enum { NDTA_UNSPEC, NDTA_NAME, /* char *, unchangeable */ NDTA_THRESH1, /* u32 */ NDTA_THRESH2, /* u32 */ NDTA_THRESH3, /* u32 */ NDTA_CONFIG, /* struct ndt_config, read-only */ NDTA_PARMS, /* nested TLV NDTPA_* */ NDTA_STATS, /* struct ndt_stats, read-only */ NDTA_GC_INTERVAL, /* u64, msecs */ __NDTA_MAX }; #define NDTA_MAX (__NDTA_MAX - 1) #endif libnl-3.2.29/include/linux-private/linux/ip.h0000644000175000017500000001066013023014600015772 00000000000000/* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * Definitions for the IP protocol. * * Version: @(#)ip.h 1.0.2 04/28/93 * * Authors: Fred N. van Kempen, * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #ifndef _UAPI_LINUX_IP_H #define _UAPI_LINUX_IP_H #include #include #define IPTOS_TOS_MASK 0x1E #define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK) #define IPTOS_LOWDELAY 0x10 #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 #define IPTOS_MINCOST 0x02 #define IPTOS_PREC_MASK 0xE0 #define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK) #define IPTOS_PREC_NETCONTROL 0xe0 #define IPTOS_PREC_INTERNETCONTROL 0xc0 #define IPTOS_PREC_CRITIC_ECP 0xa0 #define IPTOS_PREC_FLASHOVERRIDE 0x80 #define IPTOS_PREC_FLASH 0x60 #define IPTOS_PREC_IMMEDIATE 0x40 #define IPTOS_PREC_PRIORITY 0x20 #define IPTOS_PREC_ROUTINE 0x00 /* IP options */ #define IPOPT_COPY 0x80 #define IPOPT_CLASS_MASK 0x60 #define IPOPT_NUMBER_MASK 0x1f #define IPOPT_COPIED(o) ((o)&IPOPT_COPY) #define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK) #define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK) #define IPOPT_CONTROL 0x00 #define IPOPT_RESERVED1 0x20 #define IPOPT_MEASUREMENT 0x40 #define IPOPT_RESERVED2 0x60 #define IPOPT_END (0 |IPOPT_CONTROL) #define IPOPT_NOOP (1 |IPOPT_CONTROL) #define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY) #define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY) #define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT) #define IPOPT_CIPSO (6 |IPOPT_CONTROL|IPOPT_COPY) #define IPOPT_RR (7 |IPOPT_CONTROL) #define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY) #define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY) #define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY) #define IPVERSION 4 #define MAXTTL 255 #define IPDEFTTL 64 #define IPOPT_OPTVAL 0 #define IPOPT_OLEN 1 #define IPOPT_OFFSET 2 #define IPOPT_MINOFF 4 #define MAX_IPOPTLEN 40 #define IPOPT_NOP IPOPT_NOOP #define IPOPT_EOL IPOPT_END #define IPOPT_TS IPOPT_TIMESTAMP #define IPOPT_TS_TSONLY 0 /* timestamps only */ #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ #define IPOPT_TS_PRESPEC 3 /* specified modules only */ #define IPV4_BEET_PHMAXLEN 8 struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else #error "Please fix " #endif __u8 tos; __be16 tot_len; __be16 id; __be16 frag_off; __u8 ttl; __u8 protocol; __sum16 check; __be32 saddr; __be32 daddr; /*The options start here. */ }; struct ip_auth_hdr { __u8 nexthdr; __u8 hdrlen; /* This one is measured in 32 bit units! */ __be16 reserved; __be32 spi; __be32 seq_no; /* Sequence number */ __u8 auth_data[0]; /* Variable len but >=4. Mind the 64 bit alignment! */ }; struct ip_esp_hdr { __be32 spi; __be32 seq_no; /* Sequence number */ __u8 enc_data[0]; /* Variable len but >=8. Mind the 64 bit alignment! */ }; struct ip_comp_hdr { __u8 nexthdr; __u8 flags; __be16 cpi; }; struct ip_beet_phdr { __u8 nexthdr; __u8 hdrlen; __u8 padlen; __u8 reserved; }; /* index values for the variables in ipv4_devconf */ enum { IPV4_DEVCONF_FORWARDING=1, IPV4_DEVCONF_MC_FORWARDING, IPV4_DEVCONF_PROXY_ARP, IPV4_DEVCONF_ACCEPT_REDIRECTS, IPV4_DEVCONF_SECURE_REDIRECTS, IPV4_DEVCONF_SEND_REDIRECTS, IPV4_DEVCONF_SHARED_MEDIA, IPV4_DEVCONF_RP_FILTER, IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, IPV4_DEVCONF_BOOTP_RELAY, IPV4_DEVCONF_LOG_MARTIANS, IPV4_DEVCONF_TAG, IPV4_DEVCONF_ARPFILTER, IPV4_DEVCONF_MEDIUM_ID, IPV4_DEVCONF_NOXFRM, IPV4_DEVCONF_NOPOLICY, IPV4_DEVCONF_FORCE_IGMP_VERSION, IPV4_DEVCONF_ARP_ANNOUNCE, IPV4_DEVCONF_ARP_IGNORE, IPV4_DEVCONF_PROMOTE_SECONDARIES, IPV4_DEVCONF_ARP_ACCEPT, IPV4_DEVCONF_ARP_NOTIFY, IPV4_DEVCONF_ACCEPT_LOCAL, IPV4_DEVCONF_SRC_VMARK, IPV4_DEVCONF_PROXY_ARP_PVLAN, IPV4_DEVCONF_ROUTE_LOCALNET, IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL, IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL, __IPV4_DEVCONF_MAX }; #define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1) #endif /* _UAPI_LINUX_IP_H */ libnl-3.2.29/include/linux-private/linux/if_ether.h0000644000175000017500000001325713023014600017154 00000000000000/* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * Global definitions for the Ethernet IEEE 802.3 interface. * * Version: @(#)if_ether.h 1.0.1a 02/08/94 * * Author: Fred N. van Kempen, * Donald Becker, * Alan Cox, * Steve Whitehouse, * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #ifndef _LINUX_IF_ETHER_H #define _LINUX_IF_ETHER_H #include /* * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble * and FCS/CRC (frame check sequence). */ #define ETH_ALEN 6 /* Octets in one ethernet addr */ #define ETH_HLEN 14 /* Total octets in header. */ #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ #define ETH_FCS_LEN 4 /* Octets in the FCS */ /* * These are the defined Ethernet Protocol ID's. */ #define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ #define ETH_P_PUP 0x0200 /* Xerox PUP packet */ #define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ #define ETH_P_IP 0x0800 /* Internet Protocol packet */ #define ETH_P_X25 0x0805 /* CCITT X.25 */ #define ETH_P_ARP 0x0806 /* Address Resolution packet */ #define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ #define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */ #define ETH_P_DEC 0x6000 /* DEC Assigned proto */ #define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ #define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ #define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ #define ETH_P_LAT 0x6004 /* DEC LAT */ #define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ #define ETH_P_CUST 0x6006 /* DEC Customer use */ #define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ #define ETH_P_TEB 0x6558 /* Trans Ether Bridging */ #define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ #define ETH_P_ATALK 0x809B /* Appletalk DDP */ #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ #define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ #define ETH_P_IPX 0x8137 /* IPX over DIX */ #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ #define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */ #define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */ #define ETH_P_WCCP 0x883E /* Web-cache coordination protocol * defined in draft-wilson-wrec-wccp-v2-00.txt */ #define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ #define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ #define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */ #define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */ #define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ #define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */ #define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport * over Ethernet */ #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ #define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ #define ETH_P_TIPC 0x88CA /* TIPC */ #define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ #define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */ #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ /* * Non DIX types. Won't clash for 1500 types. */ #define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ #define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ #define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ #define ETH_P_802_2 0x0004 /* 802.2 frames */ #define ETH_P_SNAP 0x0005 /* Internal only */ #define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ #define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ #define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ #define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ #define ETH_P_CAN 0x000C /* Controller Area Network */ #define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ #define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ #define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ #define ETH_P_CONTROL 0x0016 /* Card specific control frames */ #define ETH_P_IRDA 0x0017 /* Linux-IrDA */ #define ETH_P_ECONET 0x0018 /* Acorn Econet */ #define ETH_P_HDLC 0x0019 /* HDLC frames */ #define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */ #define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ #define ETH_P_TRAILER 0x001C /* Trailer switch tagging */ #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ #define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ #define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */ /* * This is an Ethernet frame header. */ struct ethhdr { unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ unsigned char h_source[ETH_ALEN]; /* source ether addr */ __be16 h_proto; /* packet type ID field */ } __attribute__((packed)); #endif /* _LINUX_IF_ETHER_H */ libnl-3.2.29/include/linux-private/linux/can/0000755000175000017500000000000013031473756016053 500000000000000libnl-3.2.29/include/linux-private/linux/can/netlink.h0000644000175000017500000000572213023014600017572 00000000000000/* * linux/can/netlink.h * * Definitions for the CAN netlink interface * * Copyright (c) 2009 Wolfgang Grandegger * */ #ifndef CAN_NETLINK_H #define CAN_NETLINK_H #include /* * CAN bit-timing parameters * * For further information, please read chapter "8 BIT TIMING * REQUIREMENTS" of the "Bosch CAN Specification version 2.0" * at http://www.semiconductors.bosch.de/pdf/can2spec.pdf. */ struct can_bittiming { __u32 bitrate; /* Bit-rate in bits/second */ __u32 sample_point; /* Sample point in one-tenth of a percent */ __u32 tq; /* Time quanta (TQ) in nanoseconds */ __u32 prop_seg; /* Propagation segment in TQs */ __u32 phase_seg1; /* Phase buffer segment 1 in TQs */ __u32 phase_seg2; /* Phase buffer segment 2 in TQs */ __u32 sjw; /* Synchronisation jump width in TQs */ __u32 brp; /* Bit-rate prescaler */ }; /* * CAN harware-dependent bit-timing constant * * Used for calculating and checking bit-timing parameters */ struct can_bittiming_const { char name[16]; /* Name of the CAN controller hardware */ __u32 tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */ __u32 tseg1_max; __u32 tseg2_min; /* Time segement 2 = phase_seg2 */ __u32 tseg2_max; __u32 sjw_max; /* Synchronisation jump width */ __u32 brp_min; /* Bit-rate prescaler */ __u32 brp_max; __u32 brp_inc; }; /* * CAN clock parameters */ struct can_clock { __u32 freq; /* CAN system clock frequency in Hz */ }; /* * CAN operational and error states */ enum can_state { CAN_STATE_ERROR_ACTIVE = 0, /* RX/TX error count < 96 */ CAN_STATE_ERROR_WARNING, /* RX/TX error count < 128 */ CAN_STATE_ERROR_PASSIVE, /* RX/TX error count < 256 */ CAN_STATE_BUS_OFF, /* RX/TX error count >= 256 */ CAN_STATE_STOPPED, /* Device is stopped */ CAN_STATE_SLEEPING, /* Device is sleeping */ CAN_STATE_MAX }; /* * CAN bus error counters */ struct can_berr_counter { __u16 txerr; __u16 rxerr; }; /* * CAN controller mode */ struct can_ctrlmode { __u32 mask; __u32 flags; }; #define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */ #define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */ #define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */ #define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */ #define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ /* * CAN device statistics */ struct can_device_stats { __u32 bus_error; /* Bus errors */ __u32 error_warning; /* Changes to error warning state */ __u32 error_passive; /* Changes to error passive state */ __u32 bus_off; /* Changes to bus off state */ __u32 arbitration_lost; /* Arbitration lost errors */ __u32 restarts; /* CAN controller re-starts */ }; /* * CAN netlink interface */ enum { IFLA_CAN_UNSPEC, IFLA_CAN_BITTIMING, IFLA_CAN_BITTIMING_CONST, IFLA_CAN_CLOCK, IFLA_CAN_STATE, IFLA_CAN_CTRLMODE, IFLA_CAN_RESTART_MS, IFLA_CAN_RESTART, IFLA_CAN_BERR_COUNTER, __IFLA_CAN_MAX }; #define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1) #endif /* CAN_NETLINK_H */ libnl-3.2.29/include/linux-private/linux/pkt_cls.h0000644000175000017500000002213713023014600017023 00000000000000#ifndef __LINUX_PKT_CLS_H #define __LINUX_PKT_CLS_H #include #include /* I think i could have done better macros ; for now this is stolen from * some arch/mips code - jhs */ #define _TC_MAKE32(x) ((x)) #define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) #define _TC_MAKEMASK(v,n) (_TC_MAKE32((_TC_MAKE32(1)<<(v))-1) << _TC_MAKE32(n)) #define _TC_MAKEVALUE(v,n) (_TC_MAKE32(v) << _TC_MAKE32(n)) #define _TC_GETVALUE(v,n,m) ((_TC_MAKE32(v) & _TC_MAKE32(m)) >> _TC_MAKE32(n)) /* verdict bit breakdown * bit 0: when set -> this packet has been munged already bit 1: when set -> It is ok to munge this packet bit 2,3,4,5: Reclassify counter - sort of reverse TTL - if exceeded assume loop bit 6,7: Where this packet was last seen 0: Above the transmit example at the socket level 1: on the Ingress 2: on the Egress bit 8: when set --> Request not to classify on ingress. bits 9,10,11: redirect counter - redirect TTL. Loop avoidance * * */ #define TC_MUNGED _TC_MAKEMASK1(0) #define SET_TC_MUNGED(v) ( TC_MUNGED | (v & ~TC_MUNGED)) #define CLR_TC_MUNGED(v) ( v & ~TC_MUNGED) #define TC_OK2MUNGE _TC_MAKEMASK1(1) #define SET_TC_OK2MUNGE(v) ( TC_OK2MUNGE | (v & ~TC_OK2MUNGE)) #define CLR_TC_OK2MUNGE(v) ( v & ~TC_OK2MUNGE) #define S_TC_VERD _TC_MAKE32(2) #define M_TC_VERD _TC_MAKEMASK(4,S_TC_VERD) #define G_TC_VERD(x) _TC_GETVALUE(x,S_TC_VERD,M_TC_VERD) #define V_TC_VERD(x) _TC_MAKEVALUE(x,S_TC_VERD) #define SET_TC_VERD(v,n) ((V_TC_VERD(n)) | (v & ~M_TC_VERD)) #define S_TC_FROM _TC_MAKE32(6) #define M_TC_FROM _TC_MAKEMASK(2,S_TC_FROM) #define G_TC_FROM(x) _TC_GETVALUE(x,S_TC_FROM,M_TC_FROM) #define V_TC_FROM(x) _TC_MAKEVALUE(x,S_TC_FROM) #define SET_TC_FROM(v,n) ((V_TC_FROM(n)) | (v & ~M_TC_FROM)) #define AT_STACK 0x0 #define AT_INGRESS 0x1 #define AT_EGRESS 0x2 #define TC_NCLS _TC_MAKEMASK1(8) #define SET_TC_NCLS(v) ( TC_NCLS | (v & ~TC_NCLS)) #define CLR_TC_NCLS(v) ( v & ~TC_NCLS) #define S_TC_RTTL _TC_MAKE32(9) #define M_TC_RTTL _TC_MAKEMASK(3,S_TC_RTTL) #define G_TC_RTTL(x) _TC_GETVALUE(x,S_TC_RTTL,M_TC_RTTL) #define V_TC_RTTL(x) _TC_MAKEVALUE(x,S_TC_RTTL) #define SET_TC_RTTL(v,n) ((V_TC_RTTL(n)) | (v & ~M_TC_RTTL)) #define S_TC_AT _TC_MAKE32(12) #define M_TC_AT _TC_MAKEMASK(2,S_TC_AT) #define G_TC_AT(x) _TC_GETVALUE(x,S_TC_AT,M_TC_AT) #define V_TC_AT(x) _TC_MAKEVALUE(x,S_TC_AT) #define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT)) /* Action attributes */ enum { TCA_ACT_UNSPEC, TCA_ACT_KIND, TCA_ACT_OPTIONS, TCA_ACT_INDEX, TCA_ACT_STATS, __TCA_ACT_MAX }; #define TCA_ACT_MAX __TCA_ACT_MAX #define TCA_OLD_COMPAT (TCA_ACT_MAX+1) #define TCA_ACT_MAX_PRIO 32 #define TCA_ACT_BIND 1 #define TCA_ACT_NOBIND 0 #define TCA_ACT_UNBIND 1 #define TCA_ACT_NOUNBIND 0 #define TCA_ACT_REPLACE 1 #define TCA_ACT_NOREPLACE 0 #define MAX_REC_LOOP 4 #define MAX_RED_LOOP 4 #define TC_ACT_UNSPEC (-1) #define TC_ACT_OK 0 #define TC_ACT_RECLASSIFY 1 #define TC_ACT_SHOT 2 #define TC_ACT_PIPE 3 #define TC_ACT_STOLEN 4 #define TC_ACT_QUEUED 5 #define TC_ACT_REPEAT 6 #define TC_ACT_JUMP 0x10000000 /* Action type identifiers*/ enum { TCA_ID_UNSPEC=0, TCA_ID_POLICE=1, /* other actions go here */ __TCA_ID_MAX=255 }; #define TCA_ID_MAX __TCA_ID_MAX struct tc_police { __u32 index; int action; #define TC_POLICE_UNSPEC TC_ACT_UNSPEC #define TC_POLICE_OK TC_ACT_OK #define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY #define TC_POLICE_SHOT TC_ACT_SHOT #define TC_POLICE_PIPE TC_ACT_PIPE __u32 limit; __u32 burst; __u32 mtu; struct tc_ratespec rate; struct tc_ratespec peakrate; int refcnt; int bindcnt; __u32 capab; }; struct tcf_t { __u64 install; __u64 lastuse; __u64 expires; }; struct tc_cnt { int refcnt; int bindcnt; }; #define tc_gen \ __u32 index; \ __u32 capab; \ int action; \ int refcnt; \ int bindcnt enum { TCA_POLICE_UNSPEC, TCA_POLICE_TBF, TCA_POLICE_RATE, TCA_POLICE_PEAKRATE, TCA_POLICE_AVRATE, TCA_POLICE_RESULT, __TCA_POLICE_MAX #define TCA_POLICE_RESULT TCA_POLICE_RESULT }; #define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1) /* U32 filters */ #define TC_U32_HTID(h) ((h)&0xFFF00000) #define TC_U32_USERHTID(h) (TC_U32_HTID(h)>>20) #define TC_U32_HASH(h) (((h)>>12)&0xFF) #define TC_U32_NODE(h) ((h)&0xFFF) #define TC_U32_KEY(h) ((h)&0xFFFFF) #define TC_U32_UNSPEC 0 #define TC_U32_ROOT (0xFFF00000) enum { TCA_U32_UNSPEC, TCA_U32_CLASSID, TCA_U32_HASH, TCA_U32_LINK, TCA_U32_DIVISOR, TCA_U32_SEL, TCA_U32_POLICE, TCA_U32_ACT, TCA_U32_INDEV, TCA_U32_PCNT, TCA_U32_MARK, __TCA_U32_MAX }; #define TCA_U32_MAX (__TCA_U32_MAX - 1) struct tc_u32_key { __be32 mask; __be32 val; int off; int offmask; }; struct tc_u32_sel { unsigned char flags; unsigned char offshift; unsigned char nkeys; __be16 offmask; __u16 off; short offoff; short hoff; __be32 hmask; struct tc_u32_key keys[0]; }; struct tc_u32_mark { __u32 val; __u32 mask; __u32 success; }; struct tc_u32_pcnt { __u64 rcnt; __u64 rhit; __u64 kcnts[0]; }; /* Flags */ #define TC_U32_TERMINAL 1 #define TC_U32_OFFSET 2 #define TC_U32_VAROFFSET 4 #define TC_U32_EAT 8 #define TC_U32_MAXDEPTH 8 /* RSVP filter */ enum { TCA_RSVP_UNSPEC, TCA_RSVP_CLASSID, TCA_RSVP_DST, TCA_RSVP_SRC, TCA_RSVP_PINFO, TCA_RSVP_POLICE, TCA_RSVP_ACT, __TCA_RSVP_MAX }; #define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 ) struct tc_rsvp_gpi { __u32 key; __u32 mask; int offset; }; struct tc_rsvp_pinfo { struct tc_rsvp_gpi dpi; struct tc_rsvp_gpi spi; __u8 protocol; __u8 tunnelid; __u8 tunnelhdr; __u8 pad; }; /* ROUTE filter */ enum { TCA_ROUTE4_UNSPEC, TCA_ROUTE4_CLASSID, TCA_ROUTE4_TO, TCA_ROUTE4_FROM, TCA_ROUTE4_IIF, TCA_ROUTE4_POLICE, TCA_ROUTE4_ACT, __TCA_ROUTE4_MAX }; #define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1) /* FW filter */ enum { TCA_FW_UNSPEC, TCA_FW_CLASSID, TCA_FW_POLICE, TCA_FW_INDEV, /* used by CONFIG_NET_CLS_IND */ TCA_FW_ACT, /* used by CONFIG_NET_CLS_ACT */ TCA_FW_MASK, __TCA_FW_MAX }; #define TCA_FW_MAX (__TCA_FW_MAX - 1) /* TC index filter */ enum { TCA_TCINDEX_UNSPEC, TCA_TCINDEX_HASH, TCA_TCINDEX_MASK, TCA_TCINDEX_SHIFT, TCA_TCINDEX_FALL_THROUGH, TCA_TCINDEX_CLASSID, TCA_TCINDEX_POLICE, TCA_TCINDEX_ACT, __TCA_TCINDEX_MAX }; #define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1) /* Flow filter */ enum { FLOW_KEY_SRC, FLOW_KEY_DST, FLOW_KEY_PROTO, FLOW_KEY_PROTO_SRC, FLOW_KEY_PROTO_DST, FLOW_KEY_IIF, FLOW_KEY_PRIORITY, FLOW_KEY_MARK, FLOW_KEY_NFCT, FLOW_KEY_NFCT_SRC, FLOW_KEY_NFCT_DST, FLOW_KEY_NFCT_PROTO_SRC, FLOW_KEY_NFCT_PROTO_DST, FLOW_KEY_RTCLASSID, FLOW_KEY_SKUID, FLOW_KEY_SKGID, FLOW_KEY_VLAN_TAG, FLOW_KEY_RXHASH, __FLOW_KEY_MAX, }; #define FLOW_KEY_MAX (__FLOW_KEY_MAX - 1) enum { FLOW_MODE_MAP, FLOW_MODE_HASH, }; enum { TCA_FLOW_UNSPEC, TCA_FLOW_KEYS, TCA_FLOW_MODE, TCA_FLOW_BASECLASS, TCA_FLOW_RSHIFT, TCA_FLOW_ADDEND, TCA_FLOW_MASK, TCA_FLOW_XOR, TCA_FLOW_DIVISOR, TCA_FLOW_ACT, TCA_FLOW_POLICE, TCA_FLOW_EMATCHES, TCA_FLOW_PERTURB, __TCA_FLOW_MAX }; #define TCA_FLOW_MAX (__TCA_FLOW_MAX - 1) /* Basic filter */ enum { TCA_BASIC_UNSPEC, TCA_BASIC_CLASSID, TCA_BASIC_EMATCHES, TCA_BASIC_ACT, TCA_BASIC_POLICE, __TCA_BASIC_MAX }; #define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1) /* Cgroup classifier */ enum { TCA_CGROUP_UNSPEC, TCA_CGROUP_ACT, TCA_CGROUP_POLICE, TCA_CGROUP_EMATCHES, __TCA_CGROUP_MAX, }; #define TCA_CGROUP_MAX (__TCA_CGROUP_MAX - 1) /* Extended Matches */ struct tcf_ematch_tree_hdr { __u16 nmatches; __u16 progid; }; enum { TCA_EMATCH_TREE_UNSPEC, TCA_EMATCH_TREE_HDR, TCA_EMATCH_TREE_LIST, __TCA_EMATCH_TREE_MAX }; #define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1) struct tcf_ematch_hdr { __u16 matchid; __u16 kind; __u16 flags; __u16 pad; /* currently unused */ }; /* 0 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +-----------------------+-+-+---+ * | Unused |S|I| R | * +-----------------------+-+-+---+ * * R(2) ::= relation to next ematch * where: 0 0 END (last ematch) * 0 1 AND * 1 0 OR * 1 1 Unused (invalid) * I(1) ::= invert result * S(1) ::= simple payload */ #define TCF_EM_REL_END 0 #define TCF_EM_REL_AND (1<<0) #define TCF_EM_REL_OR (1<<1) #define TCF_EM_INVERT (1<<2) #define TCF_EM_SIMPLE (1<<3) #define TCF_EM_REL_MASK 3 #define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK) enum { TCF_LAYER_LINK, TCF_LAYER_NETWORK, TCF_LAYER_TRANSPORT, __TCF_LAYER_MAX }; #define TCF_LAYER_MAX (__TCF_LAYER_MAX - 1) /* Ematch type assignments * 1..32767 Reserved for ematches inside kernel tree * 32768..65535 Free to use, not reliable */ #define TCF_EM_CONTAINER 0 #define TCF_EM_CMP 1 #define TCF_EM_NBYTE 2 #define TCF_EM_U32 3 #define TCF_EM_META 4 #define TCF_EM_TEXT 5 #define TCF_EM_VLAN 6 #define TCF_EM_MAX 6 enum { TCF_EM_PROG_TC }; enum { TCF_EM_OPND_EQ, TCF_EM_OPND_GT, TCF_EM_OPND_LT }; #endif libnl-3.2.29/include/linux-private/linux/sock_diag.h0000644000175000017500000000065313023014600017306 00000000000000#ifndef _UAPI__SOCK_DIAG_H__ #define _UAPI__SOCK_DIAG_H__ #include #define SOCK_DIAG_BY_FAMILY 20 struct sock_diag_req { __u8 sdiag_family; __u8 sdiag_protocol; }; enum { SK_MEMINFO_RMEM_ALLOC, SK_MEMINFO_RCVBUF, SK_MEMINFO_WMEM_ALLOC, SK_MEMINFO_SNDBUF, SK_MEMINFO_FWD_ALLOC, SK_MEMINFO_WMEM_QUEUED, SK_MEMINFO_OPTMEM, SK_MEMINFO_BACKLOG, SK_MEMINFO_VARS, }; #endif /* _UAPI__SOCK_DIAG_H__ */ libnl-3.2.29/include/linux-private/linux/inet_diag.h0000644000175000017500000000473113023014600017307 00000000000000#ifndef _UAPI_INET_DIAG_H_ #define _UAPI_INET_DIAG_H_ #include /* Just some random number */ #define TCPDIAG_GETSOCK 18 #define DCCPDIAG_GETSOCK 19 #define INET_DIAG_GETSOCK_MAX 24 /* Socket identity */ struct inet_diag_sockid { __be16 idiag_sport; __be16 idiag_dport; __be32 idiag_src[4]; __be32 idiag_dst[4]; __u32 idiag_if; __u32 idiag_cookie[2]; #define INET_DIAG_NOCOOKIE (~0U) }; /* Request structure */ struct inet_diag_req { __u8 idiag_family; /* Family of addresses. */ __u8 idiag_src_len; __u8 idiag_dst_len; __u8 idiag_ext; /* Query extended information */ struct inet_diag_sockid id; __u32 idiag_states; /* States to dump */ __u32 idiag_dbs; /* Tables to dump (NI) */ }; struct inet_diag_req_v2 { __u8 sdiag_family; __u8 sdiag_protocol; __u8 idiag_ext; __u8 pad; __u32 idiag_states; struct inet_diag_sockid id; }; enum { INET_DIAG_REQ_NONE, INET_DIAG_REQ_BYTECODE, }; #define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE /* Bytecode is sequence of 4 byte commands followed by variable arguments. * All the commands identified by "code" are conditional jumps forward: * to offset cc+"yes" or to offset cc+"no". "yes" is supposed to be * length of the command and its arguments. */ struct inet_diag_bc_op { unsigned char code; unsigned char yes; unsigned short no; }; enum { INET_DIAG_BC_NOP, INET_DIAG_BC_JMP, INET_DIAG_BC_S_GE, INET_DIAG_BC_S_LE, INET_DIAG_BC_D_GE, INET_DIAG_BC_D_LE, INET_DIAG_BC_AUTO, INET_DIAG_BC_S_COND, INET_DIAG_BC_D_COND, }; struct inet_diag_hostcond { __u8 family; __u8 prefix_len; int port; __be32 addr[0]; }; /* Base info structure. It contains socket identity (addrs/ports/cookie) * and, alas, the information shown by netstat. */ struct inet_diag_msg { __u8 idiag_family; __u8 idiag_state; __u8 idiag_timer; __u8 idiag_retrans; struct inet_diag_sockid id; __u32 idiag_expires; __u32 idiag_rqueue; __u32 idiag_wqueue; __u32 idiag_uid; __u32 idiag_inode; }; /* Extensions */ enum { INET_DIAG_NONE, INET_DIAG_MEMINFO, INET_DIAG_INFO, INET_DIAG_VEGASINFO, INET_DIAG_CONG, INET_DIAG_TOS, INET_DIAG_TCLASS, INET_DIAG_SKMEMINFO, INET_DIAG_SHUTDOWN, }; #define INET_DIAG_MAX INET_DIAG_SHUTDOWN /* INET_DIAG_MEM */ struct inet_diag_meminfo { __u32 idiag_rmem; __u32 idiag_wmem; __u32 idiag_fmem; __u32 idiag_tmem; }; /* INET_DIAG_VEGASINFO */ struct tcpvegas_info { __u32 tcpv_enabled; __u32 tcpv_rttcnt; __u32 tcpv_rtt; __u32 tcpv_minrtt; }; #endif /* _UAPI_INET_DIAG_H_ */ libnl-3.2.29/include/linux-private/linux/if_link.h0000644000175000017500000005000313023014600016770 00000000000000#ifndef _LINUX_IF_LINK_H #define _LINUX_IF_LINK_H #include #include /* This struct should be in sync with struct rtnl_link_stats64 */ struct rtnl_link_stats { __u32 rx_packets; /* total packets received */ __u32 tx_packets; /* total packets transmitted */ __u32 rx_bytes; /* total bytes received */ __u32 tx_bytes; /* total bytes transmitted */ __u32 rx_errors; /* bad packets received */ __u32 tx_errors; /* packet transmit problems */ __u32 rx_dropped; /* no space in linux buffers */ __u32 tx_dropped; /* no space available in linux */ __u32 multicast; /* multicast packets received */ __u32 collisions; /* detailed rx_errors: */ __u32 rx_length_errors; __u32 rx_over_errors; /* receiver ring buff overflow */ __u32 rx_crc_errors; /* recved pkt with crc error */ __u32 rx_frame_errors; /* recv'd frame alignment error */ __u32 rx_fifo_errors; /* recv'r fifo overrun */ __u32 rx_missed_errors; /* receiver missed packet */ /* detailed tx_errors */ __u32 tx_aborted_errors; __u32 tx_carrier_errors; __u32 tx_fifo_errors; __u32 tx_heartbeat_errors; __u32 tx_window_errors; /* for cslip etc */ __u32 rx_compressed; __u32 tx_compressed; __u32 rx_nohandler; /* dropped, no handler found */ }; /* The main device statistics structure */ struct rtnl_link_stats64 { __u64 rx_packets; /* total packets received */ __u64 tx_packets; /* total packets transmitted */ __u64 rx_bytes; /* total bytes received */ __u64 tx_bytes; /* total bytes transmitted */ __u64 rx_errors; /* bad packets received */ __u64 tx_errors; /* packet transmit problems */ __u64 rx_dropped; /* no space in linux buffers */ __u64 tx_dropped; /* no space available in linux */ __u64 multicast; /* multicast packets received */ __u64 collisions; /* detailed rx_errors: */ __u64 rx_length_errors; __u64 rx_over_errors; /* receiver ring buff overflow */ __u64 rx_crc_errors; /* recved pkt with crc error */ __u64 rx_frame_errors; /* recv'd frame alignment error */ __u64 rx_fifo_errors; /* recv'r fifo overrun */ __u64 rx_missed_errors; /* receiver missed packet */ /* detailed tx_errors */ __u64 tx_aborted_errors; __u64 tx_carrier_errors; __u64 tx_fifo_errors; __u64 tx_heartbeat_errors; __u64 tx_window_errors; /* for cslip etc */ __u64 rx_compressed; __u64 tx_compressed; __u64 rx_nohandler; /* dropped, no handler found */ }; /* The struct should be in sync with struct ifmap */ struct rtnl_link_ifmap { __u64 mem_start; __u64 mem_end; __u64 base_addr; __u16 irq; __u8 dma; __u8 port; }; /* * IFLA_AF_SPEC * Contains nested attributes for address family specific attributes. * Each address family may create a attribute with the address family * number as type and create its own attribute structure in it. * * Example: * [IFLA_AF_SPEC] = { * [AF_INET] = { * [IFLA_INET_CONF] = ..., * }, * [AF_INET6] = { * [IFLA_INET6_FLAGS] = ..., * [IFLA_INET6_CONF] = ..., * } * } */ enum { IFLA_UNSPEC, IFLA_ADDRESS, IFLA_BROADCAST, IFLA_IFNAME, IFLA_MTU, IFLA_LINK, IFLA_QDISC, IFLA_STATS, IFLA_COST, #define IFLA_COST IFLA_COST IFLA_PRIORITY, #define IFLA_PRIORITY IFLA_PRIORITY IFLA_MASTER, #define IFLA_MASTER IFLA_MASTER IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */ #define IFLA_WIRELESS IFLA_WIRELESS IFLA_PROTINFO, /* Protocol specific information for a link */ #define IFLA_PROTINFO IFLA_PROTINFO IFLA_TXQLEN, #define IFLA_TXQLEN IFLA_TXQLEN IFLA_MAP, #define IFLA_MAP IFLA_MAP IFLA_WEIGHT, #define IFLA_WEIGHT IFLA_WEIGHT IFLA_OPERSTATE, IFLA_LINKMODE, IFLA_LINKINFO, #define IFLA_LINKINFO IFLA_LINKINFO IFLA_NET_NS_PID, IFLA_IFALIAS, IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */ IFLA_VFINFO_LIST, IFLA_STATS64, IFLA_VF_PORTS, IFLA_PORT_SELF, IFLA_AF_SPEC, IFLA_GROUP, /* Group the device belongs to */ IFLA_NET_NS_FD, IFLA_EXT_MASK, /* Extended info mask, VFs, etc */ IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */ #define IFLA_PROMISCUITY IFLA_PROMISCUITY IFLA_NUM_TX_QUEUES, IFLA_NUM_RX_QUEUES, IFLA_CARRIER, IFLA_PHYS_PORT_ID, IFLA_CARRIER_CHANGES, IFLA_PHYS_SWITCH_ID, IFLA_LINK_NETNSID, IFLA_PHYS_PORT_NAME, IFLA_PROTO_DOWN, IFLA_GSO_MAX_SEGS, IFLA_GSO_MAX_SIZE, IFLA_PAD, IFLA_XDP, __IFLA_MAX }; #define IFLA_MAX (__IFLA_MAX - 1) /* backwards compatibility for userspace */ #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) enum { IFLA_INET_UNSPEC, IFLA_INET_CONF, __IFLA_INET_MAX, }; #define IFLA_INET_MAX (__IFLA_INET_MAX - 1) /* ifi_flags. IFF_* flags. The only change is: IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are more not changeable by user. They describe link media characteristics and set by device driver. Comments: - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid - If neither of these three flags are set; the interface is NBMA. - IFF_MULTICAST does not mean anything special: multicasts can be used on all not-NBMA links. IFF_MULTICAST means that this media uses special encapsulation for multicast frames. Apparently, all IFF_POINTOPOINT and IFF_BROADCAST devices are able to use multicasts too. */ /* IFLA_LINK. For usual devices it is equal ifi_index. If it is a "virtual interface" (f.e. tunnel), ifi_link can point to real physical interface (f.e. for bandwidth calculations), or maybe 0, what means, that real media is unknown (usual for IPIP tunnels, when route to endpoint is allowed to change) */ /* Subtype attributes for IFLA_PROTINFO */ enum { IFLA_INET6_UNSPEC, IFLA_INET6_FLAGS, /* link flags */ IFLA_INET6_CONF, /* sysctl parameters */ IFLA_INET6_STATS, /* statistics */ IFLA_INET6_MCAST, /* MC things. What of them? */ IFLA_INET6_CACHEINFO, /* time values and max reasm size */ IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */ IFLA_INET6_TOKEN, /* device token */ IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */ __IFLA_INET6_MAX }; #define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) enum in6_addr_gen_mode { IN6_ADDR_GEN_MODE_EUI64, IN6_ADDR_GEN_MODE_NONE, IN6_ADDR_GEN_MODE_STABLE_PRIVACY, IN6_ADDR_GEN_MODE_RANDOM, }; /* Bridge section */ enum { IFLA_BR_UNSPEC, IFLA_BR_FORWARD_DELAY, IFLA_BR_HELLO_TIME, IFLA_BR_MAX_AGE, IFLA_BR_AGEING_TIME, IFLA_BR_STP_STATE, IFLA_BR_PRIORITY, IFLA_BR_VLAN_FILTERING, IFLA_BR_VLAN_PROTOCOL, IFLA_BR_GROUP_FWD_MASK, IFLA_BR_ROOT_ID, IFLA_BR_BRIDGE_ID, IFLA_BR_ROOT_PORT, IFLA_BR_ROOT_PATH_COST, IFLA_BR_TOPOLOGY_CHANGE, IFLA_BR_TOPOLOGY_CHANGE_DETECTED, IFLA_BR_HELLO_TIMER, IFLA_BR_TCN_TIMER, IFLA_BR_TOPOLOGY_CHANGE_TIMER, IFLA_BR_GC_TIMER, IFLA_BR_GROUP_ADDR, IFLA_BR_FDB_FLUSH, IFLA_BR_MCAST_ROUTER, IFLA_BR_MCAST_SNOOPING, IFLA_BR_MCAST_QUERY_USE_IFADDR, IFLA_BR_MCAST_QUERIER, IFLA_BR_MCAST_HASH_ELASTICITY, IFLA_BR_MCAST_HASH_MAX, IFLA_BR_MCAST_LAST_MEMBER_CNT, IFLA_BR_MCAST_STARTUP_QUERY_CNT, IFLA_BR_MCAST_LAST_MEMBER_INTVL, IFLA_BR_MCAST_MEMBERSHIP_INTVL, IFLA_BR_MCAST_QUERIER_INTVL, IFLA_BR_MCAST_QUERY_INTVL, IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, IFLA_BR_MCAST_STARTUP_QUERY_INTVL, IFLA_BR_NF_CALL_IPTABLES, IFLA_BR_NF_CALL_IP6TABLES, IFLA_BR_NF_CALL_ARPTABLES, IFLA_BR_VLAN_DEFAULT_PVID, IFLA_BR_PAD, IFLA_BR_VLAN_STATS_ENABLED, IFLA_BR_MCAST_STATS_ENABLED, __IFLA_BR_MAX, }; #define IFLA_BR_MAX (__IFLA_BR_MAX - 1) struct ifla_bridge_id { __u8 prio[2]; __u8 addr[6]; /* ETH_ALEN */ }; enum { BRIDGE_MODE_UNSPEC, BRIDGE_MODE_HAIRPIN, }; enum { IFLA_BRPORT_UNSPEC, IFLA_BRPORT_STATE, /* Spanning tree state */ IFLA_BRPORT_PRIORITY, /* " priority */ IFLA_BRPORT_COST, /* " cost */ IFLA_BRPORT_MODE, /* mode (hairpin) */ IFLA_BRPORT_GUARD, /* bpdu guard */ IFLA_BRPORT_PROTECT, /* root port protection */ IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ IFLA_BRPORT_LEARNING, /* mac learning */ IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ IFLA_BRPORT_PROXYARP, /* proxy ARP */ IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */ IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */ IFLA_BRPORT_ROOT_ID, /* designated root */ IFLA_BRPORT_BRIDGE_ID, /* designated bridge */ IFLA_BRPORT_DESIGNATED_PORT, IFLA_BRPORT_DESIGNATED_COST, IFLA_BRPORT_ID, IFLA_BRPORT_NO, IFLA_BRPORT_TOPOLOGY_CHANGE_ACK, IFLA_BRPORT_CONFIG_PENDING, IFLA_BRPORT_MESSAGE_AGE_TIMER, IFLA_BRPORT_FORWARD_DELAY_TIMER, IFLA_BRPORT_HOLD_TIMER, IFLA_BRPORT_FLUSH, IFLA_BRPORT_MULTICAST_ROUTER, IFLA_BRPORT_PAD, IFLA_BRPORT_MCAST_FLOOD, __IFLA_BRPORT_MAX }; #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) struct ifla_cacheinfo { __u32 max_reasm_len; __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ __u32 reachable_time; __u32 retrans_time; }; enum { IFLA_INFO_UNSPEC, IFLA_INFO_KIND, IFLA_INFO_DATA, IFLA_INFO_XSTATS, IFLA_INFO_SLAVE_KIND, IFLA_INFO_SLAVE_DATA, __IFLA_INFO_MAX, }; #define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1) /* VLAN section */ enum { IFLA_VLAN_UNSPEC, IFLA_VLAN_ID, IFLA_VLAN_FLAGS, IFLA_VLAN_EGRESS_QOS, IFLA_VLAN_INGRESS_QOS, IFLA_VLAN_PROTOCOL, __IFLA_VLAN_MAX, }; #define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1) struct ifla_vlan_flags { __u32 flags; __u32 mask; }; enum { IFLA_VLAN_QOS_UNSPEC, IFLA_VLAN_QOS_MAPPING, __IFLA_VLAN_QOS_MAX }; #define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1) struct ifla_vlan_qos_mapping { __u32 from; __u32 to; }; /* MACVLAN section */ enum { IFLA_MACVLAN_UNSPEC, IFLA_MACVLAN_MODE, IFLA_MACVLAN_FLAGS, IFLA_MACVLAN_MACADDR_MODE, IFLA_MACVLAN_MACADDR, IFLA_MACVLAN_MACADDR_DATA, IFLA_MACVLAN_MACADDR_COUNT, __IFLA_MACVLAN_MAX, }; #define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) enum macvlan_mode { MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */ MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */ MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ MACVLAN_MODE_SOURCE = 16,/* use source MAC address list to assign */ }; enum macvlan_macaddr_mode { MACVLAN_MACADDR_ADD, MACVLAN_MACADDR_DEL, MACVLAN_MACADDR_FLUSH, MACVLAN_MACADDR_SET, }; #define MACVLAN_FLAG_NOPROMISC 1 /* VRF section */ enum { IFLA_VRF_UNSPEC, IFLA_VRF_TABLE, __IFLA_VRF_MAX }; #define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1) enum { IFLA_VRF_PORT_UNSPEC, IFLA_VRF_PORT_TABLE, __IFLA_VRF_PORT_MAX }; #define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1) /* MACSEC section */ enum { IFLA_MACSEC_UNSPEC, IFLA_MACSEC_SCI, IFLA_MACSEC_PORT, IFLA_MACSEC_ICV_LEN, IFLA_MACSEC_CIPHER_SUITE, IFLA_MACSEC_WINDOW, IFLA_MACSEC_ENCODING_SA, IFLA_MACSEC_ENCRYPT, IFLA_MACSEC_PROTECT, IFLA_MACSEC_INC_SCI, IFLA_MACSEC_ES, IFLA_MACSEC_SCB, IFLA_MACSEC_REPLAY_PROTECT, IFLA_MACSEC_VALIDATION, IFLA_MACSEC_PAD, __IFLA_MACSEC_MAX, }; #define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1) enum macsec_validation_type { MACSEC_VALIDATE_DISABLED = 0, MACSEC_VALIDATE_CHECK = 1, MACSEC_VALIDATE_STRICT = 2, __MACSEC_VALIDATE_END, MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1, }; /* IPVLAN section */ enum { IFLA_IPVLAN_UNSPEC, IFLA_IPVLAN_MODE, __IFLA_IPVLAN_MAX }; #define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) enum ipvlan_mode { IPVLAN_MODE_L2 = 0, IPVLAN_MODE_L3, IPVLAN_MODE_L3S, IPVLAN_MODE_MAX }; /* VXLAN section */ enum { IFLA_VXLAN_UNSPEC, IFLA_VXLAN_ID, IFLA_VXLAN_GROUP, /* group or remote address */ IFLA_VXLAN_LINK, IFLA_VXLAN_LOCAL, IFLA_VXLAN_TTL, IFLA_VXLAN_TOS, IFLA_VXLAN_LEARNING, IFLA_VXLAN_AGEING, IFLA_VXLAN_LIMIT, IFLA_VXLAN_PORT_RANGE, /* source port */ IFLA_VXLAN_PROXY, IFLA_VXLAN_RSC, IFLA_VXLAN_L2MISS, IFLA_VXLAN_L3MISS, IFLA_VXLAN_PORT, /* destination port */ IFLA_VXLAN_GROUP6, IFLA_VXLAN_LOCAL6, IFLA_VXLAN_UDP_CSUM, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, IFLA_VXLAN_REMCSUM_TX, IFLA_VXLAN_REMCSUM_RX, IFLA_VXLAN_GBP, IFLA_VXLAN_REMCSUM_NOPARTIAL, IFLA_VXLAN_COLLECT_METADATA, IFLA_VXLAN_LABEL, IFLA_VXLAN_GPE, __IFLA_VXLAN_MAX }; #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) struct ifla_vxlan_port_range { __be16 low; __be16 high; }; /* GENEVE section */ enum { IFLA_GENEVE_UNSPEC, IFLA_GENEVE_ID, IFLA_GENEVE_REMOTE, IFLA_GENEVE_TTL, IFLA_GENEVE_TOS, IFLA_GENEVE_PORT, /* destination port */ IFLA_GENEVE_COLLECT_METADATA, IFLA_GENEVE_REMOTE6, IFLA_GENEVE_UDP_CSUM, IFLA_GENEVE_UDP_ZERO_CSUM6_TX, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, IFLA_GENEVE_LABEL, __IFLA_GENEVE_MAX }; #define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1) /* PPP section */ enum { IFLA_PPP_UNSPEC, IFLA_PPP_DEV_FD, __IFLA_PPP_MAX }; #define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1) /* GTP section */ enum { IFLA_GTP_UNSPEC, IFLA_GTP_FD0, IFLA_GTP_FD1, IFLA_GTP_PDP_HASHSIZE, __IFLA_GTP_MAX, }; #define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1) /* Bonding section */ enum { IFLA_BOND_UNSPEC, IFLA_BOND_MODE, IFLA_BOND_ACTIVE_SLAVE, IFLA_BOND_MIIMON, IFLA_BOND_UPDELAY, IFLA_BOND_DOWNDELAY, IFLA_BOND_USE_CARRIER, IFLA_BOND_ARP_INTERVAL, IFLA_BOND_ARP_IP_TARGET, IFLA_BOND_ARP_VALIDATE, IFLA_BOND_ARP_ALL_TARGETS, IFLA_BOND_PRIMARY, IFLA_BOND_PRIMARY_RESELECT, IFLA_BOND_FAIL_OVER_MAC, IFLA_BOND_XMIT_HASH_POLICY, IFLA_BOND_RESEND_IGMP, IFLA_BOND_NUM_PEER_NOTIF, IFLA_BOND_ALL_SLAVES_ACTIVE, IFLA_BOND_MIN_LINKS, IFLA_BOND_LP_INTERVAL, IFLA_BOND_PACKETS_PER_SLAVE, IFLA_BOND_AD_LACP_RATE, IFLA_BOND_AD_SELECT, IFLA_BOND_AD_INFO, IFLA_BOND_AD_ACTOR_SYS_PRIO, IFLA_BOND_AD_USER_PORT_KEY, IFLA_BOND_AD_ACTOR_SYSTEM, IFLA_BOND_TLB_DYNAMIC_LB, __IFLA_BOND_MAX, }; #define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1) enum { IFLA_BOND_AD_INFO_UNSPEC, IFLA_BOND_AD_INFO_AGGREGATOR, IFLA_BOND_AD_INFO_NUM_PORTS, IFLA_BOND_AD_INFO_ACTOR_KEY, IFLA_BOND_AD_INFO_PARTNER_KEY, IFLA_BOND_AD_INFO_PARTNER_MAC, __IFLA_BOND_AD_INFO_MAX, }; #define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1) enum { IFLA_BOND_SLAVE_UNSPEC, IFLA_BOND_SLAVE_STATE, IFLA_BOND_SLAVE_MII_STATUS, IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, IFLA_BOND_SLAVE_PERM_HWADDR, IFLA_BOND_SLAVE_QUEUE_ID, IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, __IFLA_BOND_SLAVE_MAX, }; #define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1) /* SR-IOV virtual function management section */ enum { IFLA_VF_INFO_UNSPEC, IFLA_VF_INFO, __IFLA_VF_INFO_MAX, }; #define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1) enum { IFLA_VF_UNSPEC, IFLA_VF_MAC, /* Hardware queue specific attributes */ IFLA_VF_VLAN, /* VLAN ID and QoS */ IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */ IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query * on/off switch */ IFLA_VF_STATS, /* network device statistics */ IFLA_VF_TRUST, /* Trust VF */ IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */ IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */ IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */ __IFLA_VF_MAX, }; #define IFLA_VF_MAX (__IFLA_VF_MAX - 1) struct ifla_vf_mac { __u32 vf; __u8 mac[32]; /* MAX_ADDR_LEN */ }; struct ifla_vf_vlan { __u32 vf; __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ __u32 qos; }; enum { IFLA_VF_VLAN_INFO_UNSPEC, IFLA_VF_VLAN_INFO, /* VLAN ID, QoS and VLAN protocol */ __IFLA_VF_VLAN_INFO_MAX, }; #define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1) #define MAX_VLAN_LIST_LEN 1 struct ifla_vf_vlan_info { __u32 vf; __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ __u32 qos; __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */ }; struct ifla_vf_tx_rate { __u32 vf; __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ }; struct ifla_vf_rate { __u32 vf; __u32 min_tx_rate; /* Min Bandwidth in Mbps */ __u32 max_tx_rate; /* Max Bandwidth in Mbps */ }; struct ifla_vf_spoofchk { __u32 vf; __u32 setting; }; struct ifla_vf_guid { __u32 vf; __u64 guid; }; enum { IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */ IFLA_VF_LINK_STATE_ENABLE, /* link always up */ IFLA_VF_LINK_STATE_DISABLE, /* link always down */ __IFLA_VF_LINK_STATE_MAX, }; struct ifla_vf_link_state { __u32 vf; __u32 link_state; }; struct ifla_vf_rss_query_en { __u32 vf; __u32 setting; }; enum { IFLA_VF_STATS_RX_PACKETS, IFLA_VF_STATS_TX_PACKETS, IFLA_VF_STATS_RX_BYTES, IFLA_VF_STATS_TX_BYTES, IFLA_VF_STATS_BROADCAST, IFLA_VF_STATS_MULTICAST, IFLA_VF_STATS_PAD, __IFLA_VF_STATS_MAX, }; #define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1) struct ifla_vf_trust { __u32 vf; __u32 setting; }; /* VF ports management section * * Nested layout of set/get msg is: * * [IFLA_NUM_VF] * [IFLA_VF_PORTS] * [IFLA_VF_PORT] * [IFLA_PORT_*], ... * [IFLA_VF_PORT] * [IFLA_PORT_*], ... * ... * [IFLA_PORT_SELF] * [IFLA_PORT_*], ... */ enum { IFLA_VF_PORT_UNSPEC, IFLA_VF_PORT, /* nest */ __IFLA_VF_PORT_MAX, }; #define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1) enum { IFLA_PORT_UNSPEC, IFLA_PORT_VF, /* __u32 */ IFLA_PORT_PROFILE, /* string */ IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */ IFLA_PORT_INSTANCE_UUID, /* binary UUID */ IFLA_PORT_HOST_UUID, /* binary UUID */ IFLA_PORT_REQUEST, /* __u8 */ IFLA_PORT_RESPONSE, /* __u16, output only */ __IFLA_PORT_MAX, }; #define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1) #define PORT_PROFILE_MAX 40 #define PORT_UUID_MAX 16 #define PORT_SELF_VF -1 enum { PORT_REQUEST_PREASSOCIATE = 0, PORT_REQUEST_PREASSOCIATE_RR, PORT_REQUEST_ASSOCIATE, PORT_REQUEST_DISASSOCIATE, }; enum { PORT_VDP_RESPONSE_SUCCESS = 0, PORT_VDP_RESPONSE_INVALID_FORMAT, PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES, PORT_VDP_RESPONSE_UNUSED_VTID, PORT_VDP_RESPONSE_VTID_VIOLATION, PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION, PORT_VDP_RESPONSE_OUT_OF_SYNC, /* 0x08-0xFF reserved for future VDP use */ PORT_PROFILE_RESPONSE_SUCCESS = 0x100, PORT_PROFILE_RESPONSE_INPROGRESS, PORT_PROFILE_RESPONSE_INVALID, PORT_PROFILE_RESPONSE_BADSTATE, PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES, PORT_PROFILE_RESPONSE_ERROR, }; struct ifla_port_vsi { __u8 vsi_mgr_id; __u8 vsi_type_id[3]; __u8 vsi_type_version; __u8 pad[3]; }; /* IPoIB section */ enum { IFLA_IPOIB_UNSPEC, IFLA_IPOIB_PKEY, IFLA_IPOIB_MODE, IFLA_IPOIB_UMCAST, __IFLA_IPOIB_MAX }; enum { IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */ IPOIB_MODE_CONNECTED = 1, /* using connected QPs */ }; #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1) /* HSR section */ enum { IFLA_HSR_UNSPEC, IFLA_HSR_SLAVE1, IFLA_HSR_SLAVE2, IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */ IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ IFLA_HSR_SEQ_NR, IFLA_HSR_VERSION, /* HSR version */ __IFLA_HSR_MAX, }; #define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1) /* STATS section */ struct if_stats_msg { __u8 family; __u8 pad1; __u16 pad2; __u32 ifindex; __u32 filter_mask; }; /* A stats attribute can be netdev specific or a global stat. * For netdev stats, lets use the prefix IFLA_STATS_LINK_* */ enum { IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */ IFLA_STATS_LINK_64, IFLA_STATS_LINK_XSTATS, IFLA_STATS_LINK_XSTATS_SLAVE, IFLA_STATS_LINK_OFFLOAD_XSTATS, __IFLA_STATS_MAX, }; #define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1) #define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1)) /* These are embedded into IFLA_STATS_LINK_XSTATS: * [IFLA_STATS_LINK_XSTATS] * -> [LINK_XSTATS_TYPE_xxx] * -> [rtnl link type specific attributes] */ enum { LINK_XSTATS_TYPE_UNSPEC, LINK_XSTATS_TYPE_BRIDGE, __LINK_XSTATS_TYPE_MAX }; #define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1) /* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */ enum { IFLA_OFFLOAD_XSTATS_UNSPEC, IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */ __IFLA_OFFLOAD_XSTATS_MAX }; #define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1) /* XDP section */ enum { IFLA_XDP_UNSPEC, IFLA_XDP_FD, IFLA_XDP_ATTACHED, __IFLA_XDP_MAX, }; #define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1) #endif /* _LINUX_IF_LINK_H */ libnl-3.2.29/include/linux-private/linux/if_tunnel.h0000644000175000017500000000464313023014600017351 00000000000000#ifndef _UAPI_IF_TUNNEL_H_ #define _UAPI_IF_TUNNEL_H_ #include #include #define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0) #define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1) #define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2) #define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3) #define SIOCGETPRL (SIOCDEVPRIVATE + 4) #define SIOCADDPRL (SIOCDEVPRIVATE + 5) #define SIOCDELPRL (SIOCDEVPRIVATE + 6) #define SIOCCHGPRL (SIOCDEVPRIVATE + 7) #define SIOCGET6RD (SIOCDEVPRIVATE + 8) #define SIOCADD6RD (SIOCDEVPRIVATE + 9) #define SIOCDEL6RD (SIOCDEVPRIVATE + 10) #define SIOCCHG6RD (SIOCDEVPRIVATE + 11) #define GRE_CSUM __cpu_to_be16(0x8000) #define GRE_ROUTING __cpu_to_be16(0x4000) #define GRE_KEY __cpu_to_be16(0x2000) #define GRE_SEQ __cpu_to_be16(0x1000) #define GRE_STRICT __cpu_to_be16(0x0800) #define GRE_REC __cpu_to_be16(0x0700) #define GRE_FLAGS __cpu_to_be16(0x00F8) #define GRE_VERSION __cpu_to_be16(0x0007) struct ip_tunnel_parm { char name[IFNAMSIZ]; int link; __be16 i_flags; __be16 o_flags; __be32 i_key; __be32 o_key; struct iphdr iph; }; enum { IFLA_IPTUN_UNSPEC, IFLA_IPTUN_LINK, IFLA_IPTUN_LOCAL, IFLA_IPTUN_REMOTE, IFLA_IPTUN_TTL, IFLA_IPTUN_TOS, IFLA_IPTUN_ENCAP_LIMIT, IFLA_IPTUN_FLOWINFO, IFLA_IPTUN_FLAGS, IFLA_IPTUN_PROTO, IFLA_IPTUN_PMTUDISC, IFLA_IPTUN_6RD_PREFIX, IFLA_IPTUN_6RD_RELAY_PREFIX, IFLA_IPTUN_6RD_PREFIXLEN, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, __IFLA_IPTUN_MAX, }; #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) /* SIT-mode i_flags */ #define SIT_ISATAP 0x0001 struct ip_tunnel_prl { __be32 addr; __u16 flags; __u16 __reserved; __u32 datalen; __u32 __reserved2; /* data follows */ }; /* PRL flags */ #define PRL_DEFAULT 0x0001 struct ip_tunnel_6rd { struct in6_addr prefix; __be32 relay_prefix; __u16 prefixlen; __u16 relay_prefixlen; }; enum { IFLA_GRE_UNSPEC, IFLA_GRE_LINK, IFLA_GRE_IFLAGS, IFLA_GRE_OFLAGS, IFLA_GRE_IKEY, IFLA_GRE_OKEY, IFLA_GRE_LOCAL, IFLA_GRE_REMOTE, IFLA_GRE_TTL, IFLA_GRE_TOS, IFLA_GRE_PMTUDISC, IFLA_GRE_ENCAP_LIMIT, IFLA_GRE_FLOWINFO, IFLA_GRE_FLAGS, __IFLA_GRE_MAX, }; #define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1) /* VTI-mode i_flags */ #define VTI_ISVTI 0x0001 enum { IFLA_VTI_UNSPEC, IFLA_VTI_LINK, IFLA_VTI_IKEY, IFLA_VTI_OKEY, IFLA_VTI_LOCAL, IFLA_VTI_REMOTE, __IFLA_VTI_MAX, }; #define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1) #endif /* _UAPI_IF_TUNNEL_H_ */ libnl-3.2.29/include/linux-private/linux/if_arp.h0000644000175000017500000001436713023014600016632 00000000000000/* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * Global definitions for the ARP (RFC 826) protocol. * * Version: @(#)if_arp.h 1.0.1 04/16/93 * * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988 * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source. * Ross Biro * Fred N. van Kempen, * Florian La Roche, * Jonathan Layes * Arnaldo Carvalho de Melo ARPHRD_HWX25 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #ifndef _LINUX_IF_ARP_H #define _LINUX_IF_ARP_H #include /* ARP protocol HARDWARE identifiers. */ #define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */ #define ARPHRD_ETHER 1 /* Ethernet 10Mbps */ #define ARPHRD_EETHER 2 /* Experimental Ethernet */ #define ARPHRD_AX25 3 /* AX.25 Level 2 */ #define ARPHRD_PRONET 4 /* PROnet token ring */ #define ARPHRD_CHAOS 5 /* Chaosnet */ #define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */ #define ARPHRD_ARCNET 7 /* ARCnet */ #define ARPHRD_APPLETLK 8 /* APPLEtalk */ #define ARPHRD_DLCI 15 /* Frame Relay DLCI */ #define ARPHRD_ATM 19 /* ATM */ #define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */ #define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */ #define ARPHRD_EUI64 27 /* EUI-64 */ #define ARPHRD_INFINIBAND 32 /* InfiniBand */ /* Dummy types for non ARP hardware */ #define ARPHRD_SLIP 256 #define ARPHRD_CSLIP 257 #define ARPHRD_SLIP6 258 #define ARPHRD_CSLIP6 259 #define ARPHRD_RSRVD 260 /* Notional KISS type */ #define ARPHRD_ADAPT 264 #define ARPHRD_ROSE 270 #define ARPHRD_X25 271 /* CCITT X.25 */ #define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */ #define ARPHRD_CAN 280 /* Controller Area Network */ #define ARPHRD_PPP 512 #define ARPHRD_CISCO 513 /* Cisco HDLC */ #define ARPHRD_HDLC ARPHRD_CISCO #define ARPHRD_LAPB 516 /* LAPB */ #define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */ #define ARPHRD_RAWHDLC 518 /* Raw HDLC */ #define ARPHRD_TUNNEL 768 /* IPIP tunnel */ #define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */ #define ARPHRD_FRAD 770 /* Frame Relay Access Device */ #define ARPHRD_SKIP 771 /* SKIP vif */ #define ARPHRD_LOOPBACK 772 /* Loopback device */ #define ARPHRD_LOCALTLK 773 /* Localtalk device */ #define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface */ #define ARPHRD_BIF 775 /* AP1000 BIF */ #define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4 */ #define ARPHRD_IPDDP 777 /* IP over DDP tunneller */ #define ARPHRD_IPGRE 778 /* GRE over IP */ #define ARPHRD_PIMREG 779 /* PIMSM register interface */ #define ARPHRD_HIPPI 780 /* High Performance Parallel Interface */ #define ARPHRD_ASH 781 /* Nexus 64Mbps Ash */ #define ARPHRD_ECONET 782 /* Acorn Econet */ #define ARPHRD_IRDA 783 /* Linux-IrDA */ /* ARP works differently on different FC media .. so */ #define ARPHRD_FCPP 784 /* Point to point fibrechannel */ #define ARPHRD_FCAL 785 /* Fibrechannel arbitrated loop */ #define ARPHRD_FCPL 786 /* Fibrechannel public loop */ #define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */ /* 787->799 reserved for fibrechannel media types */ #define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */ #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ #define ARPHRD_IEEE802154 804 #define ARPHRD_IEEE802154_MONITOR 805 /* IEEE 802.15.4 network monitor */ #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ #define ARPHRD_CAIF 822 /* CAIF media type */ #define ARPHRD_IP6GRE 823 /* GRE over IPv6 */ #define ARPHRD_NETLINK 824 /* Netlink header */ #define ARPHRD_6LOWPAN 825 /* IPv6 over LoWPAN */ #define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */ #define ARPHRD_NONE 0xFFFE /* zero header length */ /* ARP protocol opcodes. */ #define ARPOP_REQUEST 1 /* ARP request */ #define ARPOP_REPLY 2 /* ARP reply */ #define ARPOP_RREQUEST 3 /* RARP request */ #define ARPOP_RREPLY 4 /* RARP reply */ #define ARPOP_InREQUEST 8 /* InARP request */ #define ARPOP_InREPLY 9 /* InARP reply */ #define ARPOP_NAK 10 /* (ATM)ARP NAK */ /* ARP ioctl request. */ struct arpreq { struct sockaddr arp_pa; /* protocol address */ struct sockaddr arp_ha; /* hardware address */ int arp_flags; /* flags */ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ char arp_dev[16]; }; struct arpreq_old { struct sockaddr arp_pa; /* protocol address */ struct sockaddr arp_ha; /* hardware address */ int arp_flags; /* flags */ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ }; /* ARP Flag values. */ #define ATF_COM 0x02 /* completed entry (ha valid) */ #define ATF_PERM 0x04 /* permanent entry */ #define ATF_PUBL 0x08 /* publish entry */ #define ATF_USETRAILERS 0x10 /* has requested trailers */ #define ATF_NETMASK 0x20 /* want to use a netmask (only for proxy entries) */ #define ATF_DONTPUB 0x40 /* don't answer this addresses */ /* * This structure defines an ethernet arp header. */ struct arphdr { __be16 ar_hrd; /* format of hardware address */ __be16 ar_pro; /* format of protocol address */ unsigned char ar_hln; /* length of hardware address */ unsigned char ar_pln; /* length of protocol address */ __be16 ar_op; /* ARP opcode (command) */ #if 0 /* * Ethernet looks like this : This bit is variable sized however... */ unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ unsigned char ar_sip[4]; /* sender IP address */ unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ unsigned char ar_tip[4]; /* target IP address */ #endif }; #endif /* _LINUX_IF_ARP_H */ libnl-3.2.29/include/linux-private/linux/gen_stats.h0000644000175000017500000000243013023014600017345 00000000000000#ifndef __LINUX_GEN_STATS_H #define __LINUX_GEN_STATS_H #include enum { TCA_STATS_UNSPEC, TCA_STATS_BASIC, TCA_STATS_RATE_EST, TCA_STATS_QUEUE, TCA_STATS_APP, __TCA_STATS_MAX, }; #define TCA_STATS_MAX (__TCA_STATS_MAX - 1) /** * struct gnet_stats_basic - byte/packet throughput statistics * @bytes: number of seen bytes * @packets: number of seen packets */ struct gnet_stats_basic { __u64 bytes; __u32 packets; }; struct gnet_stats_basic_packed { __u64 bytes; __u32 packets; } __attribute__ ((packed)); /** * struct gnet_stats_rate_est - rate estimator * @bps: current byte rate * @pps: current packet rate */ struct gnet_stats_rate_est { __u32 bps; __u32 pps; }; /** * struct gnet_stats_queue - queuing statistics * @qlen: queue length * @backlog: backlog size of queue * @drops: number of dropped packets * @requeues: number of requeues * @overlimits: number of enqueues over the limit */ struct gnet_stats_queue { __u32 qlen; __u32 backlog; __u32 drops; __u32 requeues; __u32 overlimits; }; /** * struct gnet_estimator - rate estimator configuration * @interval: sampling period * @ewma_log: the log of measurement window weight */ struct gnet_estimator { signed char interval; unsigned char ewma_log; }; #endif /* __LINUX_GEN_STATS_H */ libnl-3.2.29/include/linux-private/linux/fib_rules.h0000644000175000017500000000300713023014600017331 00000000000000#ifndef __LINUX_FIB_RULES_H #define __LINUX_FIB_RULES_H /* rule is permanent, and cannot be deleted */ #define FIB_RULE_PERMANENT 0x00000001 #define FIB_RULE_INVERT 0x00000002 #define FIB_RULE_UNRESOLVED 0x00000004 #define FIB_RULE_IIF_DETACHED 0x00000008 #define FIB_RULE_DEV_DETACHED FIB_RULE_IIF_DETACHED #define FIB_RULE_OIF_DETACHED 0x00000010 /* try to find source address in routing lookups */ #define FIB_RULE_FIND_SADDR 0x00010000 struct fib_rule_hdr { __u8 family; __u8 dst_len; __u8 src_len; __u8 tos; __u8 table; __u8 res1; /* reserved */ __u8 res2; /* reserved */ __u8 action; __u32 flags; }; enum { FRA_UNSPEC, FRA_DST, /* destination address */ FRA_SRC, /* source address */ FRA_IIFNAME, /* interface name */ #define FRA_IFNAME FRA_IIFNAME FRA_GOTO, /* target to jump to (FR_ACT_GOTO) */ FRA_UNUSED2, FRA_PRIORITY, /* priority/preference */ FRA_UNUSED3, FRA_UNUSED4, FRA_UNUSED5, FRA_FWMARK, /* mark */ FRA_FLOW, /* flow/class id */ FRA_UNUSED6, FRA_UNUSED7, FRA_UNUSED8, FRA_TABLE, /* Extended table id */ FRA_FWMASK, /* mask for netfilter mark */ FRA_OIFNAME, __FRA_MAX }; #define FRA_MAX (__FRA_MAX - 1) enum { FR_ACT_UNSPEC, FR_ACT_TO_TBL, /* Pass to fixed table */ FR_ACT_GOTO, /* Jump to another rule */ FR_ACT_NOP, /* No operation */ FR_ACT_RES3, FR_ACT_RES4, FR_ACT_BLACKHOLE, /* Drop without notification */ FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ FR_ACT_PROHIBIT, /* Drop with EACCES */ __FR_ACT_MAX, }; #define FR_ACT_MAX (__FR_ACT_MAX - 1) #endif libnl-3.2.29/include/linux-private/linux/if_vlan.h0000644000175000017500000000330313023014600016774 00000000000000/* * VLAN An implementation of 802.1Q VLAN tagging. * * Authors: Ben Greear * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * */ #ifndef _LINUX_IF_VLAN_H_ #define _LINUX_IF_VLAN_H_ /* VLAN IOCTLs are found in sockios.h */ /* Passed in vlan_ioctl_args structure to determine behaviour. */ enum vlan_ioctl_cmds { ADD_VLAN_CMD, DEL_VLAN_CMD, SET_VLAN_INGRESS_PRIORITY_CMD, SET_VLAN_EGRESS_PRIORITY_CMD, GET_VLAN_INGRESS_PRIORITY_CMD, GET_VLAN_EGRESS_PRIORITY_CMD, SET_VLAN_NAME_TYPE_CMD, SET_VLAN_FLAG_CMD, GET_VLAN_REALDEV_NAME_CMD, /* If this works, you know it's a VLAN device, btw */ GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */ }; enum vlan_flags { VLAN_FLAG_REORDER_HDR = 0x1, VLAN_FLAG_GVRP = 0x2, VLAN_FLAG_LOOSE_BINDING = 0x4, VLAN_FLAG_MVRP = 0x8, }; enum vlan_name_types { VLAN_NAME_TYPE_PLUS_VID, /* Name will look like: vlan0005 */ VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like: eth1.0005 */ VLAN_NAME_TYPE_PLUS_VID_NO_PAD, /* Name will look like: vlan5 */ VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, /* Name will look like: eth0.5 */ VLAN_NAME_TYPE_HIGHEST }; struct vlan_ioctl_args { int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */ char device1[24]; union { char device2[24]; int VID; unsigned int skb_priority; unsigned int name_type; unsigned int bind_type; unsigned int flag; /* Matches vlan_dev_info flags */ } u; short vlan_qos; }; #endif /* !(_LINUX_IF_VLAN_H_) */ libnl-3.2.29/include/linux-private/linux/socket.h0000644000175000017500000000134213023014600016647 00000000000000#ifndef _LINUX_SOCKET_H #define _LINUX_SOCKET_H /* * Desired design of maximum size and alignment (see RFC2553) */ #define _K_SS_MAXSIZE 128 /* Implementation specific max size */ #define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *)) /* Implementation specific desired alignment */ typedef unsigned short __kernel_sa_family_t; struct __kernel_sockaddr_storage { __kernel_sa_family_t ss_family; /* address family */ /* Following field(s) are implementation specific */ char __data[_K_SS_MAXSIZE - sizeof(unsigned short)]; /* space to achieve desired size, */ /* _SS_MAXSIZE value minus size of ss_family */ } __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */ #endif /* _LINUX_SOCKET_H */ libnl-3.2.29/include/linux-private/linux/netlink.h0000644000175000017500000001165513023014600017033 00000000000000#ifndef __LINUX_NETLINK_H #define __LINUX_NETLINK_H #include /* for sa_family_t */ #include #define NETLINK_ROUTE 0 /* Routing/device hook */ #define NETLINK_UNUSED 1 /* Unused number */ #define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ #define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */ #define NETLINK_SOCK_DIAG 4 /* socket monitoring */ #define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */ #define NETLINK_XFRM 6 /* ipsec */ #define NETLINK_SELINUX 7 /* SELinux event notifications */ #define NETLINK_ISCSI 8 /* Open-iSCSI */ #define NETLINK_AUDIT 9 /* auditing */ #define NETLINK_FIB_LOOKUP 10 #define NETLINK_CONNECTOR 11 #define NETLINK_NETFILTER 12 /* netfilter subsystem */ #define NETLINK_IP6_FW 13 #define NETLINK_DNRTMSG 14 /* DECnet routing messages */ #define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */ #define NETLINK_GENERIC 16 /* leave room for NETLINK_DM (DM Events) */ #define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */ #define NETLINK_ECRYPTFS 19 #define NETLINK_RDMA 20 #define NETLINK_CRYPTO 21 /* Crypto layer */ #define NETLINK_INET_DIAG NETLINK_SOCK_DIAG #define MAX_LINKS 32 struct sockaddr_nl { sa_family_t nl_family; /* AF_NETLINK */ unsigned short nl_pad; /* zero */ __u32 nl_pid; /* port ID */ __u32 nl_groups; /* multicast groups mask */ }; struct nlmsghdr { __u32 nlmsg_len; /* Length of message including header */ __u16 nlmsg_type; /* Message content */ __u16 nlmsg_flags; /* Additional flags */ __u32 nlmsg_seq; /* Sequence number */ __u32 nlmsg_pid; /* Sending process port ID */ }; /* Flags values */ #define NLM_F_REQUEST 1 /* It is request message. */ #define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */ #define NLM_F_ACK 4 /* Reply with ack, with zero or error code */ #define NLM_F_ECHO 8 /* Echo this request */ #define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */ /* Modifiers to GET request */ #define NLM_F_ROOT 0x100 /* specify tree root */ #define NLM_F_MATCH 0x200 /* return all matching */ #define NLM_F_ATOMIC 0x400 /* atomic GET */ #define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) /* Modifiers to NEW request */ #define NLM_F_REPLACE 0x100 /* Override existing */ #define NLM_F_EXCL 0x200 /* Do not touch, if it exists */ #define NLM_F_CREATE 0x400 /* Create, if it does not exist */ #define NLM_F_APPEND 0x800 /* Add to end of list */ /* 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL 4.4BSD CHANGE NLM_F_REPLACE True CHANGE NLM_F_CREATE|NLM_F_REPLACE Append NLM_F_CREATE Check NLM_F_EXCL */ #define NLMSG_ALIGNTO 4U #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN) #define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) #define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0))) #define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len))) #define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \ (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \ (nlh)->nlmsg_len <= (len)) #define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len))) #define NLMSG_NOOP 0x1 /* Nothing. */ #define NLMSG_ERROR 0x2 /* Error */ #define NLMSG_DONE 0x3 /* End of a dump */ #define NLMSG_OVERRUN 0x4 /* Data lost */ #define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */ struct nlmsgerr { int error; struct nlmsghdr msg; }; #define NETLINK_ADD_MEMBERSHIP 1 #define NETLINK_DROP_MEMBERSHIP 2 #define NETLINK_PKTINFO 3 #define NETLINK_BROADCAST_ERROR 4 #define NETLINK_NO_ENOBUFS 5 struct nl_pktinfo { __u32 group; }; #define NET_MAJOR 36 /* Major 36 is reserved for networking */ enum { NETLINK_UNCONNECTED = 0, NETLINK_CONNECTED, }; /* * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)--> * +---------------------+- - -+- - - - - - - - - -+- - -+ * | Header | Pad | Payload | Pad | * | (struct nlattr) | ing | | ing | * +---------------------+- - -+- - - - - - - - - -+- - -+ * <-------------- nlattr->nla_len --------------> */ struct nlattr { __u16 nla_len; __u16 nla_type; }; /* * nla_type (16 bits) * +---+---+-------------------------------+ * | N | O | Attribute Type | * +---+---+-------------------------------+ * N := Carries nested attributes * O := Payload stored in network byte order * * Note: The N and O flag are mutually exclusive. */ #define NLA_F_NESTED (1 << 15) #define NLA_F_NET_BYTEORDER (1 << 14) #define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) #define NLA_ALIGNTO 4 #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) #endif /* __LINUX_NETLINK_H */ libnl-3.2.29/include/linux-private/linux/if_addr.h0000644000175000017500000000267613023014600016762 00000000000000#ifndef __LINUX_IF_ADDR_H #define __LINUX_IF_ADDR_H #include #include struct ifaddrmsg { __u8 ifa_family; __u8 ifa_prefixlen; /* The prefix length */ __u8 ifa_flags; /* Flags */ __u8 ifa_scope; /* Address scope */ __u32 ifa_index; /* Link index */ }; /* * Important comment: * IFA_ADDRESS is prefix address, rather than local interface address. * It makes no difference for normally configured broadcast interfaces, * but for point-to-point IFA_ADDRESS is DESTINATION address, * local address is supplied in IFA_LOCAL attribute. * * IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags. * If present, the value from struct ifaddrmsg will be ignored. */ enum { IFA_UNSPEC, IFA_ADDRESS, IFA_LOCAL, IFA_LABEL, IFA_BROADCAST, IFA_ANYCAST, IFA_CACHEINFO, IFA_MULTICAST, IFA_FLAGS, __IFA_MAX, }; #define IFA_MAX (__IFA_MAX - 1) /* ifa_flags */ #define IFA_F_SECONDARY 0x01 #define IFA_F_TEMPORARY IFA_F_SECONDARY #define IFA_F_NODAD 0x02 #define IFA_F_OPTIMISTIC 0x04 #define IFA_F_DADFAILED 0x08 #define IFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE 0x40 #define IFA_F_PERMANENT 0x80 #define IFA_F_MANAGETEMPADDR 0x100 #define IFA_F_NOPREFIXROUTE 0x200 struct ifa_cacheinfo { __u32 ifa_prefered; __u32 ifa_valid; __u32 cstamp; /* created timestamp, hundredths of seconds */ __u32 tstamp; /* updated timestamp, hundredths of seconds */ }; #endif libnl-3.2.29/include/linux-private/linux/ipv6.h0000644000175000017500000000523113023014600016244 00000000000000#ifndef _IPV6_H #define _IPV6_H #include #include /* The latest drafts declared increase in minimal mtu up to 1280. */ #define IPV6_MIN_MTU 1280 /* * Advanced API * source interface/address selection, source routing, etc... * *under construction* */ #define IPV6_SRCRT_STRICT 0x01 /* Deprecated; will be removed */ #define IPV6_SRCRT_TYPE_0 0 /* Deprecated; will be removed */ #define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */ /* * routing header */ struct ipv6_rt_hdr { __u8 nexthdr; __u8 hdrlen; __u8 type; __u8 segments_left; /* * type specific data * variable length field */ }; struct ipv6_opt_hdr { __u8 nexthdr; __u8 hdrlen; /* * TLV encoded option data follows. */ } __attribute__((packed)); /* required for some archs */ #define ipv6_destopt_hdr ipv6_opt_hdr #define ipv6_hopopt_hdr ipv6_opt_hdr /* * routing header type 0 (used in cmsghdr struct) */ struct rt0_hdr { struct ipv6_rt_hdr rt_hdr; __u32 reserved; struct in6_addr addr[0]; #define rt0_type rt_hdr.type }; /* * routing header type 2 */ struct rt2_hdr { struct ipv6_rt_hdr rt_hdr; __u32 reserved; struct in6_addr addr; #define rt2_type rt_hdr.type }; /* * home address option in destination options header */ struct ipv6_destopt_hao { __u8 type; __u8 length; struct in6_addr addr; } __attribute__((packed)); /* * IPv6 fixed header * * BEWARE, it is incorrect. The first 4 bits of flow_lbl * are glued to priority now, forming "class". */ struct ipv6hdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 priority:4, version:4; #elif defined(__BIG_ENDIAN_BITFIELD) __u8 version:4, priority:4; #else #error "Please fix " #endif __u8 flow_lbl[3]; __be16 payload_len; __u8 nexthdr; __u8 hop_limit; struct in6_addr saddr; struct in6_addr daddr; }; /* index values for the variables in ipv6_devconf */ enum { DEVCONF_FORWARDING = 0, DEVCONF_HOPLIMIT, DEVCONF_MTU6, DEVCONF_ACCEPT_RA, DEVCONF_ACCEPT_REDIRECTS, DEVCONF_AUTOCONF, DEVCONF_DAD_TRANSMITS, DEVCONF_RTR_SOLICITS, DEVCONF_RTR_SOLICIT_INTERVAL, DEVCONF_RTR_SOLICIT_DELAY, DEVCONF_USE_TEMPADDR, DEVCONF_TEMP_VALID_LFT, DEVCONF_TEMP_PREFERED_LFT, DEVCONF_REGEN_MAX_RETRY, DEVCONF_MAX_DESYNC_FACTOR, DEVCONF_MAX_ADDRESSES, DEVCONF_FORCE_MLD_VERSION, DEVCONF_ACCEPT_RA_DEFRTR, DEVCONF_ACCEPT_RA_PINFO, DEVCONF_ACCEPT_RA_RTR_PREF, DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, DEVCONF_OPTIMISTIC_DAD, DEVCONF_ACCEPT_SOURCE_ROUTE, DEVCONF_MC_FORWARDING, DEVCONF_DISABLE_IPV6, DEVCONF_ACCEPT_DAD, DEVCONF_FORCE_TLLAO, DEVCONF_MAX }; #endif /* _IPV6_H */ libnl-3.2.29/include/linux-private/linux/rtnetlink.h0000644000175000017500000004016113023014600017373 00000000000000#ifndef __LINUX_RTNETLINK_H #define __LINUX_RTNETLINK_H #include #include #include #include #include /* rtnetlink families. Values up to 127 are reserved for real address * families, values above 128 may be used arbitrarily. */ #define RTNL_FAMILY_IPMR 128 #define RTNL_FAMILY_IP6MR 129 #define RTNL_FAMILY_MAX 129 /**** * Routing/neighbour discovery messages. ****/ /* Types of messages */ enum { RTM_BASE = 16, #define RTM_BASE RTM_BASE RTM_NEWLINK = 16, #define RTM_NEWLINK RTM_NEWLINK RTM_DELLINK, #define RTM_DELLINK RTM_DELLINK RTM_GETLINK, #define RTM_GETLINK RTM_GETLINK RTM_SETLINK, #define RTM_SETLINK RTM_SETLINK RTM_NEWADDR = 20, #define RTM_NEWADDR RTM_NEWADDR RTM_DELADDR, #define RTM_DELADDR RTM_DELADDR RTM_GETADDR, #define RTM_GETADDR RTM_GETADDR RTM_NEWROUTE = 24, #define RTM_NEWROUTE RTM_NEWROUTE RTM_DELROUTE, #define RTM_DELROUTE RTM_DELROUTE RTM_GETROUTE, #define RTM_GETROUTE RTM_GETROUTE RTM_NEWNEIGH = 28, #define RTM_NEWNEIGH RTM_NEWNEIGH RTM_DELNEIGH, #define RTM_DELNEIGH RTM_DELNEIGH RTM_GETNEIGH, #define RTM_GETNEIGH RTM_GETNEIGH RTM_NEWRULE = 32, #define RTM_NEWRULE RTM_NEWRULE RTM_DELRULE, #define RTM_DELRULE RTM_DELRULE RTM_GETRULE, #define RTM_GETRULE RTM_GETRULE RTM_NEWQDISC = 36, #define RTM_NEWQDISC RTM_NEWQDISC RTM_DELQDISC, #define RTM_DELQDISC RTM_DELQDISC RTM_GETQDISC, #define RTM_GETQDISC RTM_GETQDISC RTM_NEWTCLASS = 40, #define RTM_NEWTCLASS RTM_NEWTCLASS RTM_DELTCLASS, #define RTM_DELTCLASS RTM_DELTCLASS RTM_GETTCLASS, #define RTM_GETTCLASS RTM_GETTCLASS RTM_NEWTFILTER = 44, #define RTM_NEWTFILTER RTM_NEWTFILTER RTM_DELTFILTER, #define RTM_DELTFILTER RTM_DELTFILTER RTM_GETTFILTER, #define RTM_GETTFILTER RTM_GETTFILTER RTM_NEWACTION = 48, #define RTM_NEWACTION RTM_NEWACTION RTM_DELACTION, #define RTM_DELACTION RTM_DELACTION RTM_GETACTION, #define RTM_GETACTION RTM_GETACTION RTM_NEWPREFIX = 52, #define RTM_NEWPREFIX RTM_NEWPREFIX RTM_GETMULTICAST = 58, #define RTM_GETMULTICAST RTM_GETMULTICAST RTM_GETANYCAST = 62, #define RTM_GETANYCAST RTM_GETANYCAST RTM_NEWNEIGHTBL = 64, #define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL RTM_GETNEIGHTBL = 66, #define RTM_GETNEIGHTBL RTM_GETNEIGHTBL RTM_SETNEIGHTBL, #define RTM_SETNEIGHTBL RTM_SETNEIGHTBL RTM_NEWNDUSEROPT = 68, #define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT RTM_NEWADDRLABEL = 72, #define RTM_NEWADDRLABEL RTM_NEWADDRLABEL RTM_DELADDRLABEL, #define RTM_DELADDRLABEL RTM_DELADDRLABEL RTM_GETADDRLABEL, #define RTM_GETADDRLABEL RTM_GETADDRLABEL RTM_GETDCB = 78, #define RTM_GETDCB RTM_GETDCB RTM_SETDCB, #define RTM_SETDCB RTM_SETDCB RTM_NEWNETCONF = 80, #define RTM_NEWNETCONF RTM_NEWNETCONF RTM_GETNETCONF = 82, #define RTM_GETNETCONF RTM_GETNETCONF RTM_NEWMDB = 84, #define RTM_NEWMDB RTM_NEWMDB RTM_DELMDB = 85, #define RTM_DELMDB RTM_DELMDB RTM_GETMDB = 86, #define RTM_GETMDB RTM_GETMDB RTM_NEWNSID = 88, #define RTM_NEWNSID RTM_NEWNSID RTM_DELNSID = 89, #define RTM_DELNSID RTM_DELNSID RTM_GETNSID = 90, #define RTM_GETNSID RTM_GETNSID __RTM_MAX, #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; #define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE) #define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2) #define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2) /* Generic structure for encapsulation of optional route information. It is reminiscent of sockaddr, but with sa_family replaced with attribute type. */ struct rtattr { unsigned short rta_len; unsigned short rta_type; }; /* Macros to handle rtattributes */ #define RTA_ALIGNTO 4U #define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) ) #define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \ (rta)->rta_len >= sizeof(struct rtattr) && \ (rta)->rta_len <= (len)) #define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \ (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len))) #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) #define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len)) #define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0))) #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) /****************************************************************************** * Definitions used in routing table administration. ****/ struct rtmsg { unsigned char rtm_family; unsigned char rtm_dst_len; unsigned char rtm_src_len; unsigned char rtm_tos; unsigned char rtm_table; /* Routing table id */ unsigned char rtm_protocol; /* Routing protocol; see below */ unsigned char rtm_scope; /* See below */ unsigned char rtm_type; /* See below */ unsigned rtm_flags; }; /* rtm_type */ enum { RTN_UNSPEC, RTN_UNICAST, /* Gateway or direct route */ RTN_LOCAL, /* Accept locally */ RTN_BROADCAST, /* Accept locally as broadcast, send as broadcast */ RTN_ANYCAST, /* Accept locally as broadcast, but send as unicast */ RTN_MULTICAST, /* Multicast route */ RTN_BLACKHOLE, /* Drop */ RTN_UNREACHABLE, /* Destination is unreachable */ RTN_PROHIBIT, /* Administratively prohibited */ RTN_THROW, /* Not in this table */ RTN_NAT, /* Translate this address */ RTN_XRESOLVE, /* Use external resolver */ __RTN_MAX }; #define RTN_MAX (__RTN_MAX - 1) /* rtm_protocol */ #define RTPROT_UNSPEC 0 #define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects; not used by current IPv4 */ #define RTPROT_KERNEL 2 /* Route installed by kernel */ #define RTPROT_BOOT 3 /* Route installed during boot */ #define RTPROT_STATIC 4 /* Route installed by administrator */ /* Values of protocol >= RTPROT_STATIC are not interpreted by kernel; they are just passed from user and back as is. It will be used by hypothetical multiple routing daemons. Note that protocol values should be standardized in order to avoid conflicts. */ #define RTPROT_GATED 8 /* Apparently, GateD */ #define RTPROT_RA 9 /* RDISC/ND router advertisements */ #define RTPROT_MRT 10 /* Merit MRT */ #define RTPROT_ZEBRA 11 /* Zebra */ #define RTPROT_BIRD 12 /* BIRD */ #define RTPROT_DNROUTED 13 /* DECnet routing daemon */ #define RTPROT_XORP 14 /* XORP */ #define RTPROT_NTK 15 /* Netsukuku */ #define RTPROT_DHCP 16 /* DHCP client */ #define RTPROT_MROUTED 17 /* Multicast daemon */ #define RTPROT_BABEL 42 /* Babel daemon */ /* rtm_scope Really it is not scope, but sort of distance to the destination. NOWHERE are reserved for not existing destinations, HOST is our local addresses, LINK are destinations, located on directly attached link and UNIVERSE is everywhere in the Universe. Intermediate values are also possible f.e. interior routes could be assigned a value between UNIVERSE and LINK. */ enum rt_scope_t { RT_SCOPE_UNIVERSE=0, /* User defined values */ RT_SCOPE_SITE=200, RT_SCOPE_LINK=253, RT_SCOPE_HOST=254, RT_SCOPE_NOWHERE=255 }; /* rtm_flags */ #define RTM_F_NOTIFY 0x100 /* Notify user of route change */ #define RTM_F_CLONED 0x200 /* This route is cloned */ #define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */ #define RTM_F_PREFIX 0x800 /* Prefix addresses */ /* Reserved table identifiers */ enum rt_class_t { RT_TABLE_UNSPEC=0, /* User defined values */ RT_TABLE_COMPAT=252, RT_TABLE_DEFAULT=253, RT_TABLE_MAIN=254, RT_TABLE_LOCAL=255, RT_TABLE_MAX=0xFFFFFFFF }; /* Routing message attributes */ enum rtattr_type_t { RTA_UNSPEC, RTA_DST, RTA_SRC, RTA_IIF, RTA_OIF, RTA_GATEWAY, RTA_PRIORITY, RTA_PREFSRC, RTA_METRICS, RTA_MULTIPATH, RTA_PROTOINFO, /* no longer used */ RTA_FLOW, RTA_CACHEINFO, RTA_SESSION, /* no longer used */ RTA_MP_ALGO, /* no longer used */ RTA_TABLE, RTA_MARK, RTA_MFC_STATS, RTA_VIA, RTA_NEWDST, RTA_PREF, RTA_ENCAP_TYPE, RTA_ENCAP, __RTA_MAX }; #define RTA_MAX (__RTA_MAX - 1) #define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg)))) #define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg)) /* RTM_MULTIPATH --- array of struct rtnexthop. * * "struct rtnexthop" describes all necessary nexthop information, * i.e. parameters of path to a destination via this nexthop. * * At the moment it is impossible to set different prefsrc, mtu, window * and rtt for different paths from multipath. */ struct rtnexthop { unsigned short rtnh_len; unsigned char rtnh_flags; unsigned char rtnh_hops; int rtnh_ifindex; }; /* rtnh_flags */ #define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */ #define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */ #define RTNH_F_ONLINK 4 /* Gateway is forced on link */ #define RTNH_F_OFFLOAD 8 /* offloaded route */ #define RTNH_F_LINKDOWN 16 /* carrier-down on nexthop */ #define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN) /* Macros to handle hexthops */ #define RTNH_ALIGNTO 4 #define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) ) #define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \ ((int)(rtnh)->rtnh_len) <= (len)) #define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len))) #define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len)) #define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len)) #define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0))) /* RTA_VIA */ struct rtvia { __kernel_sa_family_t rtvia_family; __u8 rtvia_addr[0]; }; /* RTM_CACHEINFO */ struct rta_cacheinfo { __u32 rta_clntref; __u32 rta_lastuse; __s32 rta_expires; __u32 rta_error; __u32 rta_used; #define RTNETLINK_HAVE_PEERINFO 1 __u32 rta_id; __u32 rta_ts; __u32 rta_tsage; }; /* RTM_METRICS --- array of struct rtattr with types of RTAX_* */ enum { RTAX_UNSPEC, #define RTAX_UNSPEC RTAX_UNSPEC RTAX_LOCK, #define RTAX_LOCK RTAX_LOCK RTAX_MTU, #define RTAX_MTU RTAX_MTU RTAX_WINDOW, #define RTAX_WINDOW RTAX_WINDOW RTAX_RTT, #define RTAX_RTT RTAX_RTT RTAX_RTTVAR, #define RTAX_RTTVAR RTAX_RTTVAR RTAX_SSTHRESH, #define RTAX_SSTHRESH RTAX_SSTHRESH RTAX_CWND, #define RTAX_CWND RTAX_CWND RTAX_ADVMSS, #define RTAX_ADVMSS RTAX_ADVMSS RTAX_REORDERING, #define RTAX_REORDERING RTAX_REORDERING RTAX_HOPLIMIT, #define RTAX_HOPLIMIT RTAX_HOPLIMIT RTAX_INITCWND, #define RTAX_INITCWND RTAX_INITCWND RTAX_FEATURES, #define RTAX_FEATURES RTAX_FEATURES RTAX_RTO_MIN, #define RTAX_RTO_MIN RTAX_RTO_MIN RTAX_INITRWND, #define RTAX_INITRWND RTAX_INITRWND RTAX_QUICKACK, #define RTAX_QUICKACK RTAX_QUICKACK RTAX_CC_ALGO, #define RTAX_CC_ALGO RTAX_CC_ALGO __RTAX_MAX }; #define RTAX_MAX (__RTAX_MAX - 1) #define RTAX_FEATURE_ECN (1 << 0) #define RTAX_FEATURE_SACK (1 << 1) #define RTAX_FEATURE_TIMESTAMP (1 << 2) #define RTAX_FEATURE_ALLFRAG (1 << 3) #define RTAX_FEATURE_MASK (RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | \ RTAX_FEATURE_TIMESTAMP | RTAX_FEATURE_ALLFRAG) struct rta_session { __u8 proto; __u8 pad1; __u16 pad2; union { struct { __u16 sport; __u16 dport; } ports; struct { __u8 type; __u8 code; __u16 ident; } icmpt; __u32 spi; } u; }; struct rta_mfc_stats { __u64 mfcs_packets; __u64 mfcs_bytes; __u64 mfcs_wrong_if; }; /**** * General form of address family dependent message. ****/ struct rtgenmsg { unsigned char rtgen_family; }; /***************************************************************** * Link layer specific messages. ****/ /* struct ifinfomsg * passes link level specific information, not dependent * on network protocol. */ struct ifinfomsg { unsigned char ifi_family; unsigned char __ifi_pad; unsigned short ifi_type; /* ARPHRD_* */ int ifi_index; /* Link index */ unsigned ifi_flags; /* IFF_* flags */ unsigned ifi_change; /* IFF_* change mask */ }; /******************************************************************** * prefix information ****/ struct prefixmsg { unsigned char prefix_family; unsigned char prefix_pad1; unsigned short prefix_pad2; int prefix_ifindex; unsigned char prefix_type; unsigned char prefix_len; unsigned char prefix_flags; unsigned char prefix_pad3; }; enum { PREFIX_UNSPEC, PREFIX_ADDRESS, PREFIX_CACHEINFO, __PREFIX_MAX }; #define PREFIX_MAX (__PREFIX_MAX - 1) struct prefix_cacheinfo { __u32 preferred_time; __u32 valid_time; }; /***************************************************************** * Traffic control messages. ****/ struct tcmsg { unsigned char tcm_family; unsigned char tcm__pad1; unsigned short tcm__pad2; int tcm_ifindex; __u32 tcm_handle; __u32 tcm_parent; __u32 tcm_info; }; enum { TCA_UNSPEC, TCA_KIND, TCA_OPTIONS, TCA_STATS, TCA_XSTATS, TCA_RATE, TCA_FCNT, TCA_STATS2, TCA_STAB, __TCA_MAX }; #define TCA_MAX (__TCA_MAX - 1) #define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg)))) #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg)) /******************************************************************** * Neighbor Discovery userland options ****/ struct nduseroptmsg { unsigned char nduseropt_family; unsigned char nduseropt_pad1; unsigned short nduseropt_opts_len; /* Total length of options */ int nduseropt_ifindex; __u8 nduseropt_icmp_type; __u8 nduseropt_icmp_code; unsigned short nduseropt_pad2; unsigned int nduseropt_pad3; /* Followed by one or more ND options */ }; enum { NDUSEROPT_UNSPEC, NDUSEROPT_SRCADDR, __NDUSEROPT_MAX }; #define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1) /* RTnetlink multicast groups - backwards compatibility for userspace */ #define RTMGRP_LINK 1 #define RTMGRP_NOTIFY 2 #define RTMGRP_NEIGH 4 #define RTMGRP_TC 8 #define RTMGRP_IPV4_IFADDR 0x10 #define RTMGRP_IPV4_MROUTE 0x20 #define RTMGRP_IPV4_ROUTE 0x40 #define RTMGRP_IPV4_RULE 0x80 #define RTMGRP_IPV6_IFADDR 0x100 #define RTMGRP_IPV6_MROUTE 0x200 #define RTMGRP_IPV6_ROUTE 0x400 #define RTMGRP_IPV6_IFINFO 0x800 #define RTMGRP_DECnet_IFADDR 0x1000 #define RTMGRP_DECnet_ROUTE 0x4000 #define RTMGRP_IPV6_PREFIX 0x20000 /* RTnetlink multicast groups */ enum rtnetlink_groups { RTNLGRP_NONE, #define RTNLGRP_NONE RTNLGRP_NONE RTNLGRP_LINK, #define RTNLGRP_LINK RTNLGRP_LINK RTNLGRP_NOTIFY, #define RTNLGRP_NOTIFY RTNLGRP_NOTIFY RTNLGRP_NEIGH, #define RTNLGRP_NEIGH RTNLGRP_NEIGH RTNLGRP_TC, #define RTNLGRP_TC RTNLGRP_TC RTNLGRP_IPV4_IFADDR, #define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_MROUTE, #define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_ROUTE, #define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_RULE, #define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE RTNLGRP_IPV6_IFADDR, #define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_MROUTE, #define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_ROUTE, #define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_IFINFO, #define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO RTNLGRP_DECnet_IFADDR, #define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR RTNLGRP_NOP2, RTNLGRP_DECnet_ROUTE, #define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_RULE, #define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE RTNLGRP_NOP4, RTNLGRP_IPV6_PREFIX, #define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_RULE, #define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE RTNLGRP_ND_USEROPT, #define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT RTNLGRP_PHONET_IFADDR, #define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_ROUTE, #define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE RTNLGRP_DCB, #define RTNLGRP_DCB RTNLGRP_DCB RTNLGRP_IPV4_NETCONF, #define RTNLGRP_IPV4_NETCONF RTNLGRP_IPV4_NETCONF RTNLGRP_IPV6_NETCONF, #define RTNLGRP_IPV6_NETCONF RTNLGRP_IPV6_NETCONF RTNLGRP_MDB, #define RTNLGRP_MDB RTNLGRP_MDB RTNLGRP_MPLS_ROUTE, #define RTNLGRP_MPLS_ROUTE RTNLGRP_MPLS_ROUTE RTNLGRP_NSID, #define RTNLGRP_NSID RTNLGRP_NSID __RTNLGRP_MAX }; #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) /* TC action piece */ struct tcamsg { unsigned char tca_family; unsigned char tca__pad1; unsigned short tca__pad2; }; #define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg)))) #define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg)) #define TCA_ACT_TAB 1 /* attr type must be >=1 */ #define TCAA_MAX 1 /* New extended info filters for IFLA_EXT_MASK */ #define RTEXT_FILTER_VF (1 << 0) #define RTEXT_FILTER_BRVLAN (1 << 1) #define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2) /* End of information exported to user level */ #endif /* __LINUX_RTNETLINK_H */ libnl-3.2.29/include/linux-private/linux/veth.h0000644000175000017500000000024113023014600016322 00000000000000#ifndef __NET_VETH_H_ #define __NET_VETH_H_ enum { VETH_INFO_UNSPEC, VETH_INFO_PEER, __VETH_INFO_MAX #define VETH_INFO_MAX (__VETH_INFO_MAX - 1) }; #endif libnl-3.2.29/include/Makefile.in0000644000175000017500000006122113031473644013327 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_CLI_TRUE@am__append_1 = \ @ENABLE_CLI_TRUE@ netlink/cli/addr.h \ @ENABLE_CLI_TRUE@ netlink/cli/class.h \ @ENABLE_CLI_TRUE@ netlink/cli/cls.h \ @ENABLE_CLI_TRUE@ netlink/cli/ct.h \ @ENABLE_CLI_TRUE@ netlink/cli/exp.h \ @ENABLE_CLI_TRUE@ netlink/cli/link.h \ @ENABLE_CLI_TRUE@ netlink/cli/neigh.h \ @ENABLE_CLI_TRUE@ netlink/cli/qdisc.h \ @ENABLE_CLI_TRUE@ netlink/cli/route.h \ @ENABLE_CLI_TRUE@ netlink/cli/rule.h \ @ENABLE_CLI_TRUE@ netlink/cli/tc.h \ @ENABLE_CLI_TRUE@ netlink/cli/utils.h subdir = include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am \ $(am__nobase_libnlinclude_HEADERS_DIST) $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__nobase_libnlinclude_HEADERS_DIST = netlink/fib_lookup/lookup.h \ netlink/fib_lookup/request.h netlink/genl/ctrl.h \ netlink/genl/family.h netlink/genl/genl.h netlink/genl/mngt.h \ netlink/netfilter/ct.h netlink/netfilter/exp.h \ netlink/netfilter/log.h netlink/netfilter/log_msg.h \ netlink/netfilter/netfilter.h netlink/netfilter/nfnl.h \ netlink/netfilter/queue.h netlink/netfilter/queue_msg.h \ netlink/addr.h netlink/attr.h netlink/cache.h netlink/data.h \ netlink/errno.h netlink/handlers.h netlink/hash.h \ netlink/hashtable.h netlink/list.h netlink/msg.h \ netlink/netlink-compat.h netlink/netlink-kernel.h \ netlink/netlink.h netlink/object.h netlink/route/action.h \ netlink/route/act/mirred.h netlink/route/act/skbedit.h \ netlink/route/act/gact.h netlink/route/cls/ematch/cmp.h \ netlink/route/cls/ematch/meta.h \ netlink/route/cls/ematch/nbyte.h \ netlink/route/cls/ematch/text.h netlink/route/cls/basic.h \ netlink/route/cls/cgroup.h netlink/route/cls/ematch.h \ netlink/route/cls/fw.h netlink/route/cls/police.h \ netlink/route/cls/u32.h netlink/route/link/api.h \ netlink/route/link/bonding.h netlink/route/link/bridge.h \ netlink/route/link/can.h netlink/route/link/inet.h \ netlink/route/link/inet6.h netlink/route/link/info-api.h \ netlink/route/link/macsec.h netlink/route/link/macvlan.h \ netlink/route/link/macvtap.h netlink/route/link/vlan.h \ netlink/route/link/vxlan.h netlink/route/link/veth.h \ netlink/route/link/ip6tnl.h netlink/route/link/ipgre.h \ netlink/route/link/ipip.h netlink/route/link/ipvti.h \ netlink/route/link/sit.h netlink/route/link/ipvlan.h \ netlink/route/link/vrf.h netlink/route/link/sriov.h \ netlink/route/link/ppp.h netlink/route/qdisc/cbq.h \ netlink/route/qdisc/dsmark.h netlink/route/qdisc/fifo.h \ netlink/route/qdisc/htb.h netlink/route/qdisc/netem.h \ netlink/route/qdisc/prio.h netlink/route/qdisc/red.h \ netlink/route/qdisc/sfq.h netlink/route/qdisc/tbf.h \ netlink/route/qdisc/plug.h netlink/route/qdisc/fq_codel.h \ netlink/route/qdisc/hfsc.h netlink/route/addr.h \ netlink/route/class.h netlink/route/classifier.h \ netlink/route/link.h netlink/route/neighbour.h \ netlink/route/neightbl.h netlink/route/nexthop.h \ netlink/route/pktloc.h netlink/route/qdisc.h \ netlink/route/route.h netlink/route/rtnl.h \ netlink/route/rule.h netlink/route/tc.h netlink/socket.h \ netlink/types.h netlink/utils.h netlink/version.h \ netlink/cache-api.h netlink/object-api.h \ netlink/route/tc-api.h netlink/idiag/idiagnl.h \ netlink/idiag/meminfo.h netlink/idiag/msg.h \ netlink/idiag/req.h netlink/idiag/vegasinfo.h \ netlink/xfrm/ae.h netlink/xfrm/lifetime.h netlink/xfrm/sa.h \ netlink/xfrm/selector.h netlink/xfrm/sp.h \ netlink/xfrm/template.h netlink/cli/addr.h netlink/cli/class.h \ netlink/cli/cls.h netlink/cli/ct.h netlink/cli/exp.h \ netlink/cli/link.h netlink/cli/neigh.h netlink/cli/qdisc.h \ netlink/cli/route.h netlink/cli/rule.h netlink/cli/tc.h \ netlink/cli/utils.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libnlincludedir)" HEADERS = $(nobase_libnlinclude_HEADERS) $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ libnlincludedir = $(includedir)/libnl@MAJ_VERSION@ nobase_libnlinclude_HEADERS = netlink/fib_lookup/lookup.h \ netlink/fib_lookup/request.h netlink/genl/ctrl.h \ netlink/genl/family.h netlink/genl/genl.h netlink/genl/mngt.h \ netlink/netfilter/ct.h netlink/netfilter/exp.h \ netlink/netfilter/log.h netlink/netfilter/log_msg.h \ netlink/netfilter/netfilter.h netlink/netfilter/nfnl.h \ netlink/netfilter/queue.h netlink/netfilter/queue_msg.h \ netlink/addr.h netlink/attr.h netlink/cache.h netlink/data.h \ netlink/errno.h netlink/handlers.h netlink/hash.h \ netlink/hashtable.h netlink/list.h netlink/msg.h \ netlink/netlink-compat.h netlink/netlink-kernel.h \ netlink/netlink.h netlink/object.h netlink/route/action.h \ netlink/route/act/mirred.h netlink/route/act/skbedit.h \ netlink/route/act/gact.h netlink/route/cls/ematch/cmp.h \ netlink/route/cls/ematch/meta.h \ netlink/route/cls/ematch/nbyte.h \ netlink/route/cls/ematch/text.h netlink/route/cls/basic.h \ netlink/route/cls/cgroup.h netlink/route/cls/ematch.h \ netlink/route/cls/fw.h netlink/route/cls/police.h \ netlink/route/cls/u32.h netlink/route/link/api.h \ netlink/route/link/bonding.h netlink/route/link/bridge.h \ netlink/route/link/can.h netlink/route/link/inet.h \ netlink/route/link/inet6.h netlink/route/link/info-api.h \ netlink/route/link/macsec.h netlink/route/link/macvlan.h \ netlink/route/link/macvtap.h netlink/route/link/vlan.h \ netlink/route/link/vxlan.h netlink/route/link/veth.h \ netlink/route/link/ip6tnl.h netlink/route/link/ipgre.h \ netlink/route/link/ipip.h netlink/route/link/ipvti.h \ netlink/route/link/sit.h netlink/route/link/ipvlan.h \ netlink/route/link/vrf.h netlink/route/link/sriov.h \ netlink/route/link/ppp.h netlink/route/qdisc/cbq.h \ netlink/route/qdisc/dsmark.h netlink/route/qdisc/fifo.h \ netlink/route/qdisc/htb.h netlink/route/qdisc/netem.h \ netlink/route/qdisc/prio.h netlink/route/qdisc/red.h \ netlink/route/qdisc/sfq.h netlink/route/qdisc/tbf.h \ netlink/route/qdisc/plug.h netlink/route/qdisc/fq_codel.h \ netlink/route/qdisc/hfsc.h netlink/route/addr.h \ netlink/route/class.h netlink/route/classifier.h \ netlink/route/link.h netlink/route/neighbour.h \ netlink/route/neightbl.h netlink/route/nexthop.h \ netlink/route/pktloc.h netlink/route/qdisc.h \ netlink/route/route.h netlink/route/rtnl.h \ netlink/route/rule.h netlink/route/tc.h netlink/socket.h \ netlink/types.h netlink/utils.h netlink/version.h \ netlink/cache-api.h netlink/object-api.h \ netlink/route/tc-api.h netlink/idiag/idiagnl.h \ netlink/idiag/meminfo.h netlink/idiag/msg.h \ netlink/idiag/req.h netlink/idiag/vegasinfo.h \ netlink/xfrm/ae.h netlink/xfrm/lifetime.h netlink/xfrm/sa.h \ netlink/xfrm/selector.h netlink/xfrm/sp.h \ netlink/xfrm/template.h $(am__append_1) noinst_HEADERS = \ linux-private/linux/fib_rules.h \ linux-private/linux/genetlink.h \ linux-private/linux/gen_stats.h \ linux-private/linux/if_addr.h \ linux-private/linux/if_arp.h \ linux-private/linux/if_ether.h \ linux-private/linux/if.h \ linux-private/linux/if_bridge.h \ linux-private/linux/if_link.h \ linux-private/linux/if_macsec.h \ linux-private/linux/if_tunnel.h \ linux-private/linux/if_vlan.h \ linux-private/linux/inet_diag.h \ linux-private/linux/ip.h \ linux-private/linux/ip_mp_alg.h \ linux-private/linux/ipv6.h \ linux-private/linux/can/netlink.h \ linux-private/linux/neighbour.h \ linux-private/linux/netfilter.h \ linux-private/linux/netfilter/nf_conntrack_common.h \ linux-private/linux/netfilter/nfnetlink_compat.h \ linux-private/linux/netfilter/nfnetlink_conntrack.h \ linux-private/linux/netfilter/nfnetlink.h \ linux-private/linux/netfilter/nfnetlink_log.h \ linux-private/linux/netfilter/nfnetlink_queue.h \ linux-private/linux/netlink.h \ linux-private/linux/pkt_cls.h \ linux-private/linux/sock_diag.h \ linux-private/linux/socket.h \ linux-private/linux/tc_act/tc_mirred.h \ linux-private/linux/tc_act/tc_skbedit.h \ linux-private/linux/tc_act/tc_gact.h \ linux-private/linux/pkt_sched.h \ linux-private/linux/rtnetlink.h \ linux-private/linux/snmp.h \ linux-private/linux/veth.h \ linux-private/linux/xfrm.h \ linux-private/linux/tc_ematch/tc_em_meta.h \ netlink-private/genl.h \ netlink-private/netlink.h \ netlink-private/socket.h \ netlink-private/tc.h \ netlink-private/types.h \ netlink-private/utils.h \ netlink-private/cache-api.h \ netlink-private/object-api.h \ netlink-private/route/link/api.h \ netlink-private/route/link/sriov.h \ netlink-private/route/tc-api.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-nobase_libnlincludeHEADERS: $(nobase_libnlinclude_HEADERS) @$(NORMAL_INSTALL) @list='$(nobase_libnlinclude_HEADERS)'; test -n "$(libnlincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(libnlincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libnlincludedir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libnlincludedir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(libnlincludedir)/$$dir"; }; \ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(libnlincludedir)/$$dir'"; \ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(libnlincludedir)/$$dir" || exit $$?; }; \ done uninstall-nobase_libnlincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(nobase_libnlinclude_HEADERS)'; test -n "$(libnlincludedir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(libnlincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libnlincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-nobase_libnlincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-nobase_libnlincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man \ install-nobase_libnlincludeHEADERS install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-nobase_libnlincludeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/src/0000755000175000017500000000000013031473756010510 500000000000000libnl-3.2.29/src/nf-exp-add.c0000644000175000017500000001557013023014600012503 00000000000000/* * src/nf-exp-add.c Create an expectation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2012 Rich Fought * */ #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nf-exp-list [OPTION]... [CONNTRACK ENTRY]\n" "\n" "Options\n" " --replace Replace the address if it exists.\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Expectation Selection\n" " -i, --id=NUM Identifier\n" " --expect-proto=PROTOCOL Expectation protocol\n" " --expect-src=ADDR Expectation source address\n" " --expect-sport=PORT Expectation source port\n" " --expect-dst=ADDR Expectation destination address\n" " --expect-dport=PORT Expectation destination port\n" " --master-proto=PROTOCOL Master conntrack protocol\n" " --master-src=ADDR Master conntrack source address\n" " --master-sport=PORT Master conntrack source port\n" " --master-dst=ADDR Master conntrack destination address\n" " --master-dport=PORT Master conntrack destination port\n" " --mask-proto=PROTOCOL Mask protocol\n" " --mask-src=ADDR Mask source address\n" " --mask-sport=PORT Mask source port\n" " --mask-dst=ADDR Mask destination address\n" " --mask-dport=PORT Mask destination port\n" " -F, --family=FAMILY Address family\n" " --timeout=NUM Timeout value\n" " --helper=STRING Helper Name\n" " --flags Flags (Kernel 2.6.37)\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nfnl_exp *exp; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err, nlflags = NLM_F_CREATE; exp = nl_cli_exp_alloc(); for (;;) { int c, optidx = 0; enum { ARG_MARK = 270, ARG_TCP_STATE = 271, ARG_EXPECT_PROTO, ARG_EXPECT_SRC, ARG_EXPECT_SPORT, ARG_EXPECT_DST, ARG_EXPECT_DPORT, ARG_MASTER_PROTO, ARG_MASTER_SRC, ARG_MASTER_SPORT, ARG_MASTER_DST, ARG_MASTER_DPORT, ARG_MASK_PROTO, ARG_MASK_SRC, ARG_MASK_SPORT, ARG_MASK_DST, ARG_MASK_DPORT, ARG_NAT_PROTO, ARG_NAT_SRC, ARG_NAT_SPORT, ARG_NAT_DST, ARG_NAT_DPORT, ARG_NAT_DIR, ARG_TIMEOUT, ARG_HELPER_NAME, ARG_REPLACE, ARG_FLAGS, }; static struct option long_opts[] = { { "replace", 1, 0, ARG_REPLACE }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "id", 1, 0, 'i' }, { "expect-proto", 1, 0, ARG_EXPECT_PROTO }, { "expect-src", 1, 0, ARG_EXPECT_SRC }, { "expect-sport", 1, 0, ARG_EXPECT_SPORT }, { "expect-dst", 1, 0, ARG_EXPECT_DST }, { "expect-dport", 1, 0, ARG_EXPECT_DPORT }, { "master-proto", 1, 0, ARG_MASTER_PROTO }, { "master-src", 1, 0, ARG_MASTER_SRC }, { "master-sport", 1, 0, ARG_MASTER_SPORT }, { "master-dst", 1, 0, ARG_MASTER_DST }, { "master-dport", 1, 0, ARG_MASTER_DPORT }, { "mask-proto", 1, 0, ARG_MASK_PROTO }, { "mask-src", 1, 0, ARG_MASK_SRC }, { "mask-sport", 1, 0, ARG_MASK_SPORT }, { "mask-dst", 1, 0, ARG_MASK_DST }, { "mask-dport", 1, 0, ARG_MASK_DPORT }, { "nat-proto", 1, 0, ARG_NAT_PROTO }, { "nat-src", 1, 0, ARG_NAT_SRC }, { "nat-sport", 1, 0, ARG_NAT_SPORT }, { "nat-dst", 1, 0, ARG_NAT_DST }, { "nat-dport", 1, 0, ARG_NAT_DPORT }, { "nat-dir", 1, 0, ARG_NAT_DIR }, { "family", 1, 0, 'F' }, { "timeout", 1, 0, ARG_TIMEOUT }, { "helper", 1, 0, ARG_HELPER_NAME }, { "flags", 1, 0, ARG_FLAGS}, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "46f:hvi:p:F:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case ARG_REPLACE: nlflags |= NLM_F_REPLACE; break; case 'q': quiet = 1; break; case '4': nfnl_exp_set_family(exp, AF_INET); break; case '6': nfnl_exp_set_family(exp, AF_INET6); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'i': nl_cli_exp_parse_id(exp, optarg); break; case ARG_EXPECT_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_MASTER_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASK_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_NAT_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_NAT, optarg); break; case ARG_NAT_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_NAT, optarg); break; case ARG_NAT_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_NAT, optarg); break; case ARG_NAT_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_NAT, optarg); break; case ARG_NAT_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_NAT, optarg); break; case ARG_NAT_DIR: nl_cli_exp_parse_nat_dir(exp, optarg); break; case 'F': nl_cli_exp_parse_family(exp, optarg); break; case ARG_TIMEOUT: nl_cli_exp_parse_timeout(exp, optarg); break; case ARG_HELPER_NAME: nl_cli_exp_parse_helper_name(exp, optarg); break; case ARG_FLAGS: nl_cli_exp_parse_flags(exp, optarg); break; } } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_NETFILTER); if ((err = nfnl_exp_add(sock, exp, nlflags)) < 0) nl_cli_fatal(err, "Unable to add expectation: %s", nl_geterror(err)); if (!quiet) { printf("Added "); nl_object_dump(OBJ_CAST(exp), ¶ms); } return 0; } libnl-3.2.29/src/nl-util-addr.c0000644000175000017500000000137713023014600013054 00000000000000/* * src/nl-util-addr.c Address Helper * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include int main(int argc, char *argv[]) { int err; char host[256]; struct nl_addr *a; if (argc < 2) { fprintf(stderr, "Usage: nl-util-addr
\n"); return -1; } a = nl_cli_addr_parse(argv[1], AF_UNSPEC); err = nl_addr_resolve(a, host, sizeof(host)); if (err != 0) nl_cli_fatal(err, "Unable to resolve address \"%s\": %s", argv[1], nl_geterror(err)); printf("%s\n", host); return 0; } libnl-3.2.29/src/Makefile.am0000644000175000017500000000622013023014600012440 00000000000000# -*- Makefile -*- SUBDIRS = lib AM_CPPFLAGS = \ -I${top_srcdir}/include/linux-private \ -I${top_srcdir}/include \ -I${top_builddir}/include \ -D_GNU_SOURCE \ -DSYSCONFDIR=\"$(sysconfdir)/libnl\" AM_CFLAGS = -Wall LDADD = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la cli_programs = \ genl-ctrl-list \ idiag-socket-details \ nf-ct-add \ nf-ct-list \ nf-exp-add \ nf-exp-delete \ nf-exp-list \ nf-log \ nf-monitor \ nf-queue \ nl-addr-add \ nl-addr-delete \ nl-addr-list \ nl-class-add \ nl-class-delete \ nl-classid-lookup \ nl-class-list \ nl-cls-add \ nl-cls-delete \ nl-cls-list \ nl-fib-lookup \ nl-link-enslave \ nl-link-ifindex2name \ nl-link-list \ nl-link-name2ifindex \ nl-link-release \ nl-link-set \ nl-link-stats \ nl-list-caches \ nl-list-sockets \ nl-monitor \ nl-neigh-add \ nl-neigh-delete \ nl-neigh-list \ nl-neightbl-list \ nl-pktloc-lookup \ nl-qdisc-add \ nl-qdisc-delete \ nl-qdisc-list \ nl-route-add \ nl-route-delete \ nl-route-get \ nl-route-list \ nl-rule-list \ nl-tctree-list \ nl-util-addr if ENABLE_CLI_INSTALL_BIN bin_PROGRAMS = $(cli_programs) else if ENABLE_CLI_INSTALL_SBIN sbin_PROGRAMS = $(cli_programs) else noinst_PROGRAMS = $(cli_programs) endif endif genl_ctrl_list_SOURCES = genl-ctrl-list.c nf_ct_list_SOURCES = nf-ct-list.c nf_ct_add_SOURCES = nf-ct-add.c nf_log_SOURCES = nf-log.c nf_queue_SOURCES = nf-queue.c nf_monitor_SOURCES = nf-monitor.c nf_exp_list_SOURCES = nf-exp-list.c nf_exp_add_SOURCES = nf-exp-add.c nf_exp_delete_SOURCES = nf-exp-delete.c nl_addr_add_SOURCES = nl-addr-add.c nl_addr_delete_SOURCES = nl-addr-delete.c nl_addr_list_SOURCES = nl-addr-list.c nl_link_list_SOURCES = nl-link-list.c nl_link_set_SOURCES = nl-link-set.c nl_link_stats_SOURCES = nl-link-stats.c nl_link_ifindex2name_SOURCES = nl-link-ifindex2name.c nl_link_name2ifindex_SOURCES = nl-link-name2ifindex.c nl_monitor_SOURCES = nl-monitor.c nl_neigh_add_SOURCES = nl-neigh-add.c nl_neigh_delete_SOURCES = nl-neigh-delete.c nl_neigh_list_SOURCES = nl-neigh-list.c nl_neightbl_list_SOURCES = nl-neightbl-list.c nl_qdisc_add_SOURCES = nl-qdisc-add.c nl_qdisc_delete_SOURCES = nl-qdisc-delete.c nl_qdisc_list_SOURCES = nl-qdisc-list.c nl_class_add_SOURCES = nl-class-add.c nl_class_delete_SOURCES = nl-class-delete.c nl_class_list_SOURCES = nl-class-list.c nl_cls_add_SOURCES = nl-cls-add.c nl_cls_list_SOURCES = nl-cls-list.c nl_cls_delete_SOURCES = nl-cls-delete.c nl_route_add_SOURCES = nl-route-add.c nl_route_delete_SOURCES = nl-route-delete.c nl_route_get_SOURCES = nl-route-get.c nl_route_list_SOURCES = nl-route-list.c nl_rule_list_SOURCES = nl-rule-list.c nl_tctree_list_SOURCES = nl-tctree-list.c nl_fib_lookup_SOURCES = nl-fib-lookup.c nl_list_caches_SOURCES = nl-list-caches.c nl_list_sockets_SOURCES = nl-list-sockets.c nl_util_addr_SOURCES = nl-util-addr.c nl_pktloc_lookup_SOURCES = nl-pktloc-lookup.c nl_classid_lookup_SOURCES = nl-classid-lookup.c idiag_socket_details_SOURCES = idiag-socket-details.c libnl-3.2.29/src/nl-cls-delete.c0000644000175000017500000001006513023014600013202 00000000000000/* * src/nl-cls-delete.c Delete Classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2010 Thomas Graf */ #include #include #include static int quiet = 0, default_yes = 0, deleted = 0, interactive = 0; static struct nl_sock *sock; static void print_usage(void) { printf( "Usage: nl-cls-delete [OPTION]... [class]\n" "\n" "OPTIONS\n" " --interactive Run interactively.\n" " --yes Set default answer to yes.\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help text and exit.\n" " -v, --version Show versioning information and exit.\n" "\n" " -d, --dev=DEV Device the classifer is attached to.\n" " -p, --parent=ID Identifier of parent qdisc/class.\n" " -i, --id=ID Identifier\n" " -k, --kind=NAME Kind of classifier (e.g. basic, u32, fw)\n" " --proto=PROTO Protocol to match (default: all)\n" " --prio=PRIO Priority (default: 0)\n" "\n" "EXAMPLE\n" " # Delete all classifiers on eth0 attached to parent q_root:\n" " $ nl-cls-delete --dev eth0 --parent q_root:\n" "\n" ); exit(0); } static void delete_cb(struct nl_object *obj, void *arg) { struct rtnl_cls *cls = nl_object_priv(obj); struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; if (interactive && !nl_cli_confirm(obj, ¶ms, default_yes)) return; if ((err = rtnl_cls_delete(sock, cls, 0)) < 0) nl_cli_fatal(err, "Unable to delete classifier: %s\n", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(obj, ¶ms); } deleted++; } static void __delete_link(int ifindex, struct rtnl_cls *filter) { struct nl_cache *cache; uint32_t parent = rtnl_tc_get_parent((struct rtnl_tc *) filter); cache = nl_cli_cls_alloc_cache(sock, ifindex, parent); nl_cache_foreach_filter(cache, OBJ_CAST(filter), delete_cb, NULL); nl_cache_free(cache); } static void delete_link(struct nl_object *obj, void *arg) { struct rtnl_link *link = nl_object_priv(obj); __delete_link(rtnl_link_get_ifindex(link), arg); } int main(int argc, char *argv[]) { struct rtnl_cls *cls; struct rtnl_tc *tc; struct nl_cache *link_cache; int ifindex; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); cls = nl_cli_cls_alloc(); tc = (struct rtnl_tc *) cls; for (;;) { int c, optidx = 0; enum { ARG_YES = 257, ARG_INTERACTIVE = 258, ARG_PROTO, ARG_PRIO, }; static struct option long_opts[] = { { "interactive", 0, 0, ARG_INTERACTIVE }, { "yes", 0, 0, ARG_YES }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "kind", 1, 0, 'k' }, { "proto", 1, 0, ARG_PROTO }, { "prio", 1, 0, ARG_PRIO }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhvd:p:i:k:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': nl_cli_fatal(EINVAL, "Invalid options"); case ARG_INTERACTIVE: interactive = 1; break; case ARG_YES: default_yes = 1; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': nl_cli_tc_parse_handle(tc, optarg, 0); break; case 'k': nl_cli_tc_parse_kind(tc, optarg); break; case ARG_PROTO: nl_cli_cls_parse_proto(cls, optarg); break; case ARG_PRIO: rtnl_cls_set_prio(cls, nl_cli_parse_u32(optarg)); break; } } if ((ifindex = rtnl_tc_get_ifindex(tc))) __delete_link(ifindex, cls); else nl_cache_foreach(link_cache, delete_link, cls); if (!quiet) printf("Deleted %d classs\n", deleted); return 0; } libnl-3.2.29/src/nf-log.c0000644000175000017500000000663613023014600011745 00000000000000/* * src/nf-log.c Monitor netfilter log events * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #include #include #include #include #include static struct nfnl_log *alloc_log(void) { struct nfnl_log *log; log = nfnl_log_alloc(); if (!log) nl_cli_fatal(ENOMEM, "Unable to allocate log object"); return log; } static void obj_input(struct nl_object *obj, void *arg) { struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; nl_object_dump(obj, &dp); } static int event_input(struct nl_msg *msg, void *arg) { if (nl_msg_parse(msg, &obj_input, NULL) < 0) fprintf(stderr, "<> Unknown message type\n"); /* Exit nl_recvmsgs_def() and return to the main select() */ return NL_STOP; } int main(int argc, char *argv[]) { struct nl_sock *nf_sock; struct nl_sock *rt_sock; struct nfnl_log *log; int copy_mode; uint32_t copy_range; int err; int family; nf_sock = nl_cli_alloc_socket(); nl_socket_disable_seq_check(nf_sock); nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) { printf("Usage: nf-log family group [ copy_mode ] " "[copy_range] \n"); return 2; } nl_cli_connect(nf_sock, NETLINK_NETFILTER); family = nl_str2af(argv[1]); if (family == AF_UNSPEC) nl_cli_fatal(NLE_INVAL, "Unknown family \"%s\": %s", argv[1], nl_geterror(family)); nfnl_log_pf_unbind(nf_sock, family); if ((err = nfnl_log_pf_bind(nf_sock, family)) < 0) nl_cli_fatal(err, "Unable to bind logger: %s", nl_geterror(err)); log = alloc_log(); nfnl_log_set_group(log, atoi(argv[2])); copy_mode = NFNL_LOG_COPY_META; if (argc > 3) { copy_mode = nfnl_log_str2copy_mode(argv[3]); if (copy_mode < 0) nl_cli_fatal(copy_mode, "Unable to parse copy mode \"%s\": %s", argv[3], nl_geterror(copy_mode)); } nfnl_log_set_copy_mode(log, copy_mode); copy_range = 0xFFFF; if (argc > 4) copy_range = atoi(argv[4]); nfnl_log_set_copy_range(log, copy_range); if ((err = nfnl_log_create(nf_sock, log)) < 0) nl_cli_fatal(err, "Unable to bind instance: %s", nl_geterror(err)); { struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; printf("log params: "); nl_object_dump((struct nl_object *) log, &dp); } rt_sock = nl_cli_alloc_socket(); nl_cli_connect(rt_sock, NETLINK_ROUTE); nl_cli_link_alloc_cache(rt_sock); while (1) { fd_set rfds; int nffd, rtfd, maxfd, retval; FD_ZERO(&rfds); maxfd = nffd = nl_socket_get_fd(nf_sock); FD_SET(nffd, &rfds); rtfd = nl_socket_get_fd(rt_sock); FD_SET(rtfd, &rfds); if (maxfd < rtfd) maxfd = rtfd; /* wait for an incoming message on the netlink nf_socket */ retval = select(maxfd+1, &rfds, NULL, NULL, NULL); if (retval) { if (FD_ISSET(nffd, &rfds)) nl_recvmsgs_default(nf_sock); if (FD_ISSET(rtfd, &rfds)) nl_recvmsgs_default(rt_sock); } } return 0; } libnl-3.2.29/src/nl-neigh-list.c0000644000175000017500000000473213023014600013230 00000000000000/* * src/nl-neigh-list.c List Neighbours * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static void print_usage(void) { printf( "Usage: nl-neigh-list [OPTION]... [NEIGHBOUR]\n" "\n" "Options\n" " -f, --format=TYPE Output format { brief | details | stats }\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Neighbour Options\n" " -a, --addr=ADDR Destination address of neighbour\n" " -l, --lladdr=ADDR Link layer address of neighbour\n" " -d, --dev=DEV Device the neighbour is connected to\n" " --family=FAMILY Destination address family\n" " --state=STATE Neighbour state, (default = permanent)\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_neigh *neigh; struct nl_cache *link_cache, *neigh_cache; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache_flags(sock, NL_CACHE_AF_ITER); neigh_cache = nl_cli_neigh_alloc_cache(sock); neigh = nl_cli_neigh_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_STATE = 258, }; static struct option long_opts[] = { { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "addr", 1, 0, 'a' }, { "lladdr", 1, 0, 'l' }, { "dev", 1, 0, 'd' }, { "family", 1, 0, ARG_FAMILY }, { "state", 1, 0, ARG_STATE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "f:hva:l:d:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'a': nl_cli_neigh_parse_dst(neigh, optarg); break; case 'l': nl_cli_neigh_parse_lladdr(neigh, optarg); break; case 'd': nl_cli_neigh_parse_dev(neigh, link_cache, optarg); break; case ARG_FAMILY: nl_cli_neigh_parse_family(neigh, optarg); break; case ARG_STATE: nl_cli_neigh_parse_state(neigh, optarg); break; } } nl_cache_dump_filter(neigh_cache, ¶ms, OBJ_CAST(neigh)); return 0; } libnl-3.2.29/src/nl-monitor.c0000644000175000017500000000537713023014600012662 00000000000000/* * src/nl-monitor.c Monitor events * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include static void obj_input(struct nl_object *obj, void *arg) { struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; nl_object_dump(obj, &dp); } static int event_input(struct nl_msg *msg, void *arg) { if (nl_msg_parse(msg, &obj_input, NULL) < 0) fprintf(stderr, "<> Unknown message type\n"); /* Exit nl_recvmsgs_def() and return to the main select() */ return NL_STOP; } int main(int argc, char *argv[]) { struct nl_sock *sock; int err = 1; int i, idx; static const struct { enum rtnetlink_groups gr_id; const char* gr_name; } known_groups[] = { { RTNLGRP_LINK, "link" }, { RTNLGRP_NOTIFY, "notify" }, { RTNLGRP_NEIGH, "neigh" }, { RTNLGRP_TC, "tc" }, { RTNLGRP_IPV4_IFADDR, "ipv4-ifaddr" }, { RTNLGRP_IPV4_MROUTE, "ipv4-mroute" }, { RTNLGRP_IPV4_ROUTE, "ipv4-route" }, { RTNLGRP_IPV6_IFADDR, "ipv6-ifaddr" }, { RTNLGRP_IPV6_MROUTE, "ipv6-mroute" }, { RTNLGRP_IPV6_ROUTE, "ipv6-route" }, { RTNLGRP_IPV6_IFINFO, "ipv6-ifinfo" }, { RTNLGRP_DECnet_IFADDR, "decnet-ifaddr" }, { RTNLGRP_DECnet_ROUTE, "decnet-route" }, { RTNLGRP_IPV6_PREFIX, "ipv6-prefix" }, { RTNLGRP_NONE, NULL } }; sock = nl_cli_alloc_socket(); nl_socket_disable_seq_check(sock); nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); if (argc > 1 && !strcasecmp(argv[1], "-h")) { printf("Usage: nl-monitor []\n"); printf("Known groups:"); for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) printf(" %s", known_groups[i].gr_name); printf("\n"); return 2; } nl_cli_connect(sock, NETLINK_ROUTE); for (idx = 1; argc > idx; idx++) { for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) { if (!strcmp(argv[idx], known_groups[i].gr_name)) { if ((err = nl_socket_add_membership(sock, known_groups[i].gr_id)) < 0) { nl_cli_fatal(err, "%s: %s\n", argv[idx], nl_geterror(err)); } break; } } if (known_groups[i].gr_id == RTNLGRP_NONE) fprintf(stderr, "Warning: Unknown group: %s\n", argv[idx]); } nl_cli_link_alloc_cache(sock); while (1) { fd_set rfds; int fd, retval; fd = nl_socket_get_fd(sock); FD_ZERO(&rfds); FD_SET(fd, &rfds); /* wait for an incoming message on the netlink socket */ retval = select(fd+1, &rfds, NULL, NULL, NULL); if (retval) { /* FD_ISSET(fd, &rfds) will be true */ nl_recvmsgs_default(sock); } } return 0; } libnl-3.2.29/src/nl-link-list.c0000644000175000017500000000520513023014600013067 00000000000000/* * src/nl-link-dump.c Dump link attributes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2010 Thomas Graf */ #include #include static void print_usage(void) { printf( "Usage: nl-link-list [OPTIONS]... \n" "\n" "OPTIONS\n" " --details Show detailed information of each link\n" " --stats Show statistics, implies --details\n" " -h, --help Show this help text.\n" " -v, --version Show versioning information.\n" "\n" " -n, --name=NAME Name of link\n" " -i, --index Interface index (unique identifier)\n" " --family=NAME Link address family\n" " --mtu=NUM MTU value\n" " --txqlen=NUM TX queue length\n" " --weight=NUM Weight\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *link_cache; struct rtnl_link *link; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link = nl_cli_link_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_MTU = 258, ARG_TXQLEN, ARG_WEIGHT, ARG_DETAILS, ARG_STATS, }; static struct option long_opts[] = { { "details", 0, 0, ARG_DETAILS }, { "stats", 0, 0, ARG_STATS }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "name", 1, 0, 'n' }, { "index", 1, 0, 'i' }, { "family", 1, 0, ARG_FAMILY }, { "mtu", 1, 0, ARG_MTU }, { "txqlen", 1, 0, ARG_TXQLEN }, { "weight", 1, 0, ARG_WEIGHT }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hvn:i:", long_opts, &optidx); if (c == -1) break; switch (c) { case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break; case ARG_STATS: params.dp_type = NL_DUMP_STATS; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'n': nl_cli_link_parse_name(link, optarg); break; case 'i': nl_cli_link_parse_ifindex(link, optarg); break; case ARG_FAMILY: nl_cli_link_parse_family(link, optarg); break; case ARG_MTU: nl_cli_link_parse_mtu(link, optarg); break; case ARG_TXQLEN: nl_cli_link_parse_txqlen(link, optarg); break; case ARG_WEIGHT: nl_cli_link_parse_weight(link, optarg); break; } } link_cache = nl_cli_link_alloc_cache_family(sock, rtnl_link_get_family(link)); nl_cache_dump_filter(link_cache, ¶ms, OBJ_CAST(link)); return 0; } libnl-3.2.29/src/genl-ctrl-list.c0000644000175000017500000000321213023014600013406 00000000000000/* * src/genl-ctrl-list.c List Generic Netlink Families * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ #include static struct nl_cache *alloc_genl_family_cache(struct nl_sock *sk) { return nl_cli_alloc_cache(sk, "generic netlink family", genl_ctrl_alloc_cache); } static void print_usage(void) { printf( "Usage: genl-ctrl-list [--details]\n" "\n" "Options\n" " -d, --details Include detailed information in the list\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *family_cache; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_GENERIC); family_cache = alloc_genl_family_cache(sock); for (;;) { int c, optidx = 0; static struct option long_opts[] = { { "details", 0, 0, 'd' }, { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "df:hv", long_opts, &optidx); if (c == -1) break; switch (c) { case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'd': params.dp_type = NL_DUMP_DETAILS; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; } } nl_cache_dump(family_cache, ¶ms); return 0; } libnl-3.2.29/src/nl-route-delete.c0000644000175000017500000001162713023014600013564 00000000000000/* * src/nl-route-delete.c Delete Routes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static int interactive = 0, default_yes = 0, quiet = 0; static int deleted = 0; static struct nl_sock *sock; static void print_version(void) { fprintf(stderr, "%s\n", LIBNL_STRING); exit(0); } static void print_usage(void) { printf( "Usage: nl-route-delete [OPTION]... [ROUTE]\n" "\n" "Options\n" " -i, --interactive Run interactively\n" " --yes Set default answer to yes\n" " -q, --quiet Do not print informal notifications\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Route Options\n" " -d, --dst=ADDR destination prefix, e.g. 10.10.0.0/16\n" " -n, --nexthop=NH nexthop configuration:\n" " dev=DEV route via device\n" " weight=WEIGHT weight of nexthop\n" " flags=FLAGS\n" " via=GATEWAY route via other node\n" " realms=REALMS\n" " e.g. dev=eth0,via=192.168.1.12\n" " -t, --table=TABLE Routing table\n" " --family=FAMILY Address family\n" " --src=ADDR Source prefix\n" " --iif=DEV Incomming interface\n" " --pref-src=ADDR Preferred source address\n" " --metrics=OPTS Metrics configurations\n" " --priority=NUM Priotity\n" " --scope=SCOPE Scope\n" " --protocol=PROTO Protocol\n" " --type=TYPE { unicast | local | broadcast | multicast }\n" ); exit(0); } static void delete_cb(struct nl_object *obj, void *arg) { struct rtnl_route *route = (struct rtnl_route *) obj; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; if (interactive && !nl_cli_confirm(obj, ¶ms, default_yes)) return; if ((err = rtnl_route_delete(sock, route, 0)) < 0) nl_cli_fatal(err, "Unable to delete route: %s", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(obj, ¶ms); } deleted++; } int main(int argc, char *argv[]) { struct nl_cache *link_cache, *route_cache; struct rtnl_route *route; int nf = 0; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); route_cache = nl_cli_route_alloc_cache(sock, 0); route = nl_cli_route_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_SRC = 258, ARG_IIF, ARG_PREF_SRC, ARG_METRICS, ARG_PRIORITY, ARG_SCOPE, ARG_PROTOCOL, ARG_TYPE, ARG_YES, }; static struct option long_opts[] = { { "interactive", 0, 0, 'i' }, { "yes", 0, 0, ARG_YES }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dst", 1, 0, 'd' }, { "nexthop", 1, 0, 'n' }, { "table", 1, 0, 't' }, { "family", 1, 0, ARG_FAMILY }, { "src", 1, 0, ARG_SRC }, { "iif", 1, 0, ARG_IIF }, { "pref-src", 1, 0, ARG_PREF_SRC }, { "metrics", 1, 0, ARG_METRICS }, { "priority", 1, 0, ARG_PRIORITY }, { "scope", 1, 0, ARG_SCOPE }, { "protocol", 1, 0, ARG_PROTOCOL }, { "type", 1, 0, ARG_TYPE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "iqhvd:n:t:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'i': interactive = 1; break; case ARG_YES: default_yes = 1; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': print_version(); break; case 'd': nf++; nl_cli_route_parse_dst(route, optarg); break; case 'n': nf++; nl_cli_route_parse_nexthop(route, optarg, link_cache); break; case 't': nf++; nl_cli_route_parse_table(route, optarg); break; case ARG_FAMILY: nf++; nl_cli_route_parse_family(route, optarg); break; case ARG_SRC: nf++; nl_cli_route_parse_src(route, optarg); break; case ARG_IIF: nf++; nl_cli_route_parse_iif(route, optarg, link_cache); break; case ARG_PREF_SRC: nf++; nl_cli_route_parse_pref_src(route, optarg); break; case ARG_METRICS: nf++; nl_cli_route_parse_metric(route, optarg); break; case ARG_PRIORITY: nf++; nl_cli_route_parse_prio(route, optarg); break; case ARG_SCOPE: nf++; nl_cli_route_parse_scope(route, optarg); break; case ARG_PROTOCOL: nf++; nl_cli_route_parse_protocol(route, optarg); break; case ARG_TYPE: nf++; nl_cli_route_parse_type(route, optarg); break; } } if (nf == 0 && !interactive && !default_yes) { fprintf(stderr, "You attempted to delete all routes in " "non-interactive mode, aborting.\n"); exit(0); } nl_cache_foreach_filter(route_cache, OBJ_CAST(route), delete_cb, NULL); if (!quiet) printf("Deleted %d routes\n", deleted); return 0; } libnl-3.2.29/src/nf-exp-list.c0000644000175000017500000001145113023014600012720 00000000000000/* * src/nf-exp-list.c List Expectation Entries * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2012 Rich Fought */ #include #include static void print_usage(void) { printf( "Usage: nf-exp-list [OPTION]... [EXPECTATION ENTRY]\n" "\n" "Options\n" " -f, --format=TYPE Output format { brief | details }\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Expectation Selection\n" " -i, --id=NUM Identifier\n" " --expect-proto=PROTOCOL Expectation protocol\n" " --expect-src=ADDR Expectation source address\n" " --expect-sport=PORT Expectation source port\n" " --expect-dst=ADDR Expectation destination address\n" " --expect-dport=PORT Expectation destination port\n" " --master-proto=PROTOCOL Master conntrack protocol\n" " --master-src=ADDR Master conntrack source address\n" " --master-sport=PORT Master conntrack source port\n" " --master-dst=ADDR Master conntrack destination address\n" " --master-dport=PORT Master conntrack destination port\n" " -F, --family=FAMILY Address family\n" " --timeout=NUM Timeout value\n" " --helper=STRING Helper Name\n" //" --flags Flags\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *exp_cache; struct nfnl_exp *exp; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; exp = nl_cli_exp_alloc(); for (;;) { int c, optidx = 0; enum { ARG_MARK = 270, ARG_TCP_STATE = 271, ARG_EXPECT_PROTO, ARG_EXPECT_SRC, ARG_EXPECT_SPORT, ARG_EXPECT_DST, ARG_EXPECT_DPORT, ARG_MASTER_PROTO, ARG_MASTER_SRC, ARG_MASTER_SPORT, ARG_MASTER_DST, ARG_MASTER_DPORT, ARG_TIMEOUT, ARG_HELPER_NAME, ARG_FLAGS, }; static struct option long_opts[] = { { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "id", 1, 0, 'i' }, { "expect-proto", 1, 0, ARG_EXPECT_PROTO }, { "expect-src", 1, 0, ARG_EXPECT_SRC }, { "expect-sport", 1, 0, ARG_EXPECT_SPORT }, { "expect-dst", 1, 0, ARG_EXPECT_DST }, { "expect-dport", 1, 0, ARG_EXPECT_DPORT }, { "master-proto", 1, 0, ARG_MASTER_PROTO }, { "master-src", 1, 0, ARG_MASTER_SRC }, { "master-sport", 1, 0, ARG_MASTER_SPORT }, { "master-dst", 1, 0, ARG_MASTER_DST }, { "master-dport", 1, 0, ARG_MASTER_DPORT }, { "family", 1, 0, 'F' }, { "timeout", 1, 0, ARG_TIMEOUT }, { "helper", 1, 0, ARG_HELPER_NAME }, { "flags", 1, 0, ARG_FLAGS}, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "46f:hvi:p:F:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case '4': nfnl_exp_set_family(exp, AF_INET); break; case '6': nfnl_exp_set_family(exp, AF_INET6); break; case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'i': nl_cli_exp_parse_id(exp, optarg); break; case ARG_EXPECT_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_MASTER_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case 'F': nl_cli_exp_parse_family(exp, optarg); break; case ARG_TIMEOUT: nl_cli_exp_parse_timeout(exp, optarg); break; case ARG_HELPER_NAME: nl_cli_exp_parse_helper_name(exp, optarg); break; case ARG_FLAGS: nl_cli_exp_parse_flags(exp, optarg); break; } } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_NETFILTER); exp_cache = nl_cli_exp_alloc_cache(sock); nl_cache_dump_filter(exp_cache, ¶ms, OBJ_CAST(exp)); return 0; } libnl-3.2.29/src/nl-classid-lookup.c0000644000175000017500000000402113023014600014105 00000000000000/* * src/nl-classid-lookup.c Lookup classid * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include static void print_usage(void) { printf( "Usage: nl-classid-lookup [OPTIONS]... NAME\n" "\n" "OPTIONS\n" " -h, --help Show this help text.\n" " -v, --version Show versioning information.\n" " -r, --reverse Do a reverse lookup, i.e. classid to name.\n" " --raw Print the raw classid, not pretty printed.\n" "\n" "EXAMPLE\n" " $ nl-classid-lookup low_latency\n" " $ nl-classid-lookup -r 1:12\n" "\n" ); exit(0); } int main(int argc, char *argv[]) { uint32_t classid; char *name; int err, reverse = 0, raw = 0; for (;;) { int c, optidx = 0; enum { ARG_RAW = 257, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "reverse", 0, 0, 'r' }, { "raw", 0, 0, ARG_RAW }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hvr", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'r': reverse = 1; break; case ARG_RAW: raw = 1; break; } } if (optind >= argc) print_usage(); name = argv[optind++]; /* * We use rtnl_tc_str2handle() even while doing a reverse lookup. This * allows for name -> name lookups. This is intentional, it does not * do any harm and avoids duplicating a lot of code. */ if ((err = rtnl_tc_str2handle(name, &classid)) < 0) nl_cli_fatal(err, "Unable to lookup classid \"%s\": %s", name, nl_geterror(err)); if (reverse) { char buf[64]; printf("%s\n", rtnl_tc_handle2str(classid, buf, sizeof(buf))); } else if (raw) printf("%#x\n", classid); else printf("%x:%x\n", TC_H_MAJ(classid) >> 16, TC_H_MIN(classid)); return 0; } libnl-3.2.29/src/nl-qdisc-add.c0000644000175000017500000000755113023014600013020 00000000000000/* * src/nl-qdisc-add.c Add Queueing Discipline * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include #include #include #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nl-qdisc-add [OPTIONS]... QDISC [CONFIGURATION]...\n" "\n" "OPTIONS\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help text.\n" " -v, --version Show versioning information.\n" " --update Update qdisc if it exists.\n" " --replace Replace or update qdisc if it exists.\n" " --update-only Only update qdisc, never create it.\n" " --replace-only Only replace or update qdisc, never create it.\n" " -d, --dev=DEV Network device the qdisc should be attached to.\n" " -i, --id=ID ID of new qdisc (default: auto-generated)r\n" " -p, --parent=ID ID of parent { root | ingress | QDISC-ID }\n" "\n" "CONFIGURATION\n" " -h, --help Show help text of qdisc specific options.\n" "\n" "EXAMPLE\n" " $ nl-qdisc-add --dev=eth1 --parent=root htb --rate=100mbit\n" "\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_qdisc *qdisc; struct rtnl_tc *tc; struct nl_cache *link_cache; struct nl_dump_params dp = { .dp_type = NL_DUMP_DETAILS, .dp_fd = stdout, }; struct nl_cli_tc_module *tm; struct rtnl_tc_ops *ops; int err, flags = NLM_F_CREATE | NLM_F_EXCL; char *kind, *id = NULL; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); qdisc = nl_cli_qdisc_alloc(); tc = (struct rtnl_tc *) qdisc; for (;;) { int c, optidx = 0; enum { ARG_REPLACE = 257, ARG_UPDATE = 258, ARG_REPLACE_ONLY, ARG_UPDATE_ONLY, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "replace", 0, 0, ARG_REPLACE }, { "update", 0, 0, ARG_UPDATE }, { "replace-only", 0, 0, ARG_REPLACE_ONLY }, { "update-only", 0, 0, ARG_UPDATE_ONLY }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "+qhvd:p:i:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': id = strdup(optarg); break; case ARG_UPDATE: flags = NLM_F_CREATE; break; case ARG_REPLACE: flags = NLM_F_CREATE | NLM_F_REPLACE; break; case ARG_UPDATE_ONLY: flags = 0; break; case ARG_REPLACE_ONLY: flags = NLM_F_REPLACE; break; } } if (optind >= argc) print_usage(); if (!rtnl_tc_get_ifindex(tc)) nl_cli_fatal(EINVAL, "You must specify a network device (--dev=XXX)"); if (!rtnl_tc_get_parent(tc)) nl_cli_fatal(EINVAL, "You must specify a parent"); if (id) { nl_cli_tc_parse_handle(tc, id, 1); free(id); } kind = argv[optind++]; rtnl_tc_set_kind(tc, kind); if (!(ops = rtnl_tc_get_ops(tc))) nl_cli_fatal(ENOENT, "Unknown qdisc \"%s\"", kind); if (!(tm = nl_cli_tc_lookup(ops))) nl_cli_fatal(ENOTSUP, "Qdisc type \"%s\" not supported.", kind); tm->tm_parse_argv(tc, argc, argv); if (!quiet) { printf("Adding "); nl_object_dump(OBJ_CAST(qdisc), &dp); } if ((err = rtnl_qdisc_add(sock, qdisc, flags)) < 0) nl_cli_fatal(EINVAL, "Unable to add qdisc: %s", nl_geterror(err)); return 0; } libnl-3.2.29/src/nl-link-release.c0000644000175000017500000000203113023014600013526 00000000000000/* * src/nl-link-release.c release a link * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2011 Thomas Graf */ #include #include #include int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *link_cache; struct rtnl_link *slave; int err; if (argc < 2) { fprintf(stderr, "Usage: nl-link-release slave\n"); return 1; } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); if (!(slave = rtnl_link_get_by_name(link_cache, argv[1]))) { fprintf(stderr, "Unknown link: %s\n", argv[1]); return 1; } if ((err = rtnl_link_bond_release(sock, slave)) < 0) { fprintf(stderr, "Unable to release slave %s: %s\n", argv[1], nl_geterror(err)); return 1; } return 0; } libnl-3.2.29/src/nl-cls-list.c0000644000175000017500000000652213023014600012716 00000000000000/* * src/nl-cls-list.c List classifiers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2010 Thomas Graf */ #include #include #include #include static struct nl_sock *sock; static struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, }; static void print_usage(void) { printf( "Usage: nl-cls-list [OPTION]...\n" "\n" "OPTIONS\n" " --details Show details\n" " --stats Show statistics\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" " -d, --dev=DEV Device the classifier is attached to. (default: all)\n" " -p, --parent=ID Identifier of parent class.\n" " -i, --id=ID Identifier.\n" " -k, --kind=NAME Kind of classifier (e.g. basic, u32, fw)\n" " --proto=PROTO Protocol to match (default: all)\n" " --prio=PRIO Priority (default: 0)\n" "\n" "EXAMPLE\n" " # Display statistics of all classes on eth0\n" " $ nl-cls-list --stats --dev=eth0\n" "\n" ); exit(0); } static void __dump_link(int ifindex, struct rtnl_cls *filter) { struct nl_cache *cache; uint32_t parent = rtnl_tc_get_parent((struct rtnl_tc *) filter); cache = nl_cli_cls_alloc_cache(sock, ifindex, parent); nl_cache_dump_filter(cache, ¶ms, OBJ_CAST(filter)); nl_cache_free(cache); } static void dump_link(struct nl_object *obj, void *arg) { struct rtnl_link *link = nl_object_priv(obj); __dump_link(rtnl_link_get_ifindex(link), arg); } int main(int argc, char *argv[]) { struct rtnl_cls *cls; struct rtnl_tc *tc; struct nl_cache *link_cache; int ifindex; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); cls = nl_cli_cls_alloc(); tc = (struct rtnl_tc *) cls; params.dp_fd = stdout; for (;;) { int c, optidx = 0; enum { ARG_DETAILS = 257, ARG_STATS = 258, ARG_PROTO, ARG_PRIO, }; static struct option long_opts[] = { { "details", 0, 0, ARG_DETAILS }, { "stats", 0, 0, ARG_STATS }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "kind", 1, 0, 'k' }, { "proto", 1, 0, ARG_PROTO }, { "prio", 1, 0, ARG_PRIO }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hvd:p:i:k:", long_opts, &optidx); if (c == -1) break; switch (c) { case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break; case ARG_STATS: params.dp_type = NL_DUMP_STATS; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': nl_cli_tc_parse_handle(tc, optarg, 0); break; case 'k': nl_cli_tc_parse_kind(tc, optarg); break; case ARG_PROTO: nl_cli_cls_parse_proto(cls, optarg); break; case ARG_PRIO: rtnl_cls_set_prio(cls, nl_cli_parse_u32(optarg)); break; } } if ((ifindex = rtnl_tc_get_ifindex(tc))) __dump_link(ifindex, cls); else nl_cache_foreach(link_cache, dump_link, cls); return 0; } libnl-3.2.29/src/nl-pktloc-lookup.c0000644000175000017500000000667013023014600013773 00000000000000/* * src/nl-pktloc-lookup.c Lookup packet location alias * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include #include static void print_usage(void) { printf( "Usage: nl-pktloc-lookup [OPTIONS] \n" "\n" "OPTIONS\n" " -h, --help Show this help text.\n" " -v, --version Show versioning information.\n" " -l, --list List all packet location definitions.\n" " --u32=VALUE Print in iproute2's u32 selector style\n" "\n" "\n" "EXAMPLE\n" " $ nl-pktloc-lookup ip.dst\n" " $ nl-pktloc-lookup --list\n" "\n" ); exit(0); } static const char *align_txt[] = { [TCF_EM_ALIGN_U8] = "u8", [TCF_EM_ALIGN_U16] = "u16", [TCF_EM_ALIGN_U32] = "u32" }; static uint32_t align_mask[] = { [TCF_EM_ALIGN_U8] = 0xff, [TCF_EM_ALIGN_U16] = 0xffff, [TCF_EM_ALIGN_U32] = 0xffffffff, }; static const char *layer_txt[] = { [TCF_LAYER_LINK] = "eth", [TCF_LAYER_NETWORK] = "ip", [TCF_LAYER_TRANSPORT] = "tcp" }; static void dump_u32_style(struct rtnl_pktloc *loc, uint32_t value) { if (loc->align > 4) nl_cli_fatal(EINVAL, "u32 only supports alignments u8|u16|u32."); if (loc->layer == TCF_LAYER_LINK) nl_cli_fatal(EINVAL, "u32 does not support link " "layer locations."); if (loc->shift > 0) nl_cli_fatal(EINVAL, "u32 does not support shifting."); printf("%s %x %x at %s%u\n", align_txt[loc->align], value, loc->mask ? loc->mask : align_mask[loc->align], loc->layer == TCF_LAYER_TRANSPORT ? "nexthdr+" : "", loc->offset); } static char *get_align_txt(struct rtnl_pktloc *loc) { static char buf[16]; if (loc->align <= 4) strcpy(buf, align_txt[loc->align]); else snprintf(buf, sizeof(buf), "%u", loc->align); return buf; } static void dump_loc(struct rtnl_pktloc *loc) { printf("%s = %s at %s+%u & %#x >> %u\n", loc->name, get_align_txt(loc), layer_txt[loc->layer], loc->offset, loc->mask, loc->shift); } static void list_cb(struct rtnl_pktloc *loc, void *arg) { printf("%-26s %-5s %3s+%-4u %#-10x %-8u %u\n", loc->name, get_align_txt(loc), layer_txt[loc->layer], loc->offset, loc->mask, loc->shift, loc->refcnt); } static void do_list(void) { printf( "name align offset mask shift refcnt\n"); printf("---------------------------------------------------------\n"); rtnl_pktloc_foreach(&list_cb, NULL); } int main(int argc, char *argv[]) { struct rtnl_pktloc *loc; int err, ustyle = 0; uint32_t uvalue = 0; for (;;) { int c, optidx = 0; enum { ARG_U32 = 257, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "list", 0, 0, 'l' }, { "u32", 1, 0, ARG_U32 }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hvl", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'l': do_list(); exit(0); case ARG_U32: ustyle = 1; uvalue = nl_cli_parse_u32(optarg); break; } } if (optind >= argc) print_usage(); if ((err = rtnl_pktloc_lookup(argv[optind++], &loc)) < 0) nl_cli_fatal(err, "Unable to lookup packet location: %s", nl_geterror(err)); if (ustyle) dump_u32_style(loc, uvalue); else dump_loc(loc); return 0; } libnl-3.2.29/src/nl-list-caches.c0000644000175000017500000000565213023014600013366 00000000000000/* * nl-list-caches.c List registered cache types * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include static void print_usage(void) { fprintf(stderr, "Usage: nl-list-caches\n"); exit(1); } static char *id_attr_list(struct nl_object_ops *ops, char *buf, size_t len) { if (ops->oo_attrs2str != NULL) return ops->oo_attrs2str(ops->oo_id_attrs, buf, len); else { memset(buf, 0, len); return buf; } } static void print(struct nl_cache_ops *ops, void *arg) { char buf[64]; printf("%s:\n" \ " hdrsize: %d bytes\n" \ " protocol: %s\n" \ " request-update: %s\n" \ " msg-parser: %s\n", ops->co_name, ops->co_hdrsize, nl_nlfamily2str(ops->co_protocol, buf, sizeof(buf)), ops->co_request_update ? "yes" : "no", ops->co_msg_parser ? "yes" : "no"); if (ops->co_obj_ops) { struct nl_object_ops *obj_ops = ops->co_obj_ops; const char *dump_names[NL_DUMP_MAX+1] = { "brief", "detailed", "stats", }; int i; printf(" cacheable object:\n" \ " name: %s:\n" \ " size: %zu bytes\n" \ " constructor: %s\n" \ " free-data: %s\n" \ " clone: %s\n" \ " compare: %s\n" \ " id attributes: %s\n" \ " dump: ", obj_ops->oo_name, obj_ops->oo_size, obj_ops->oo_constructor ? "yes" : "no", obj_ops->oo_free_data ? "yes" : "no", obj_ops->oo_clone ? "yes" : "no", obj_ops->oo_compare ? "yes" : "no", id_attr_list(obj_ops, buf, sizeof(buf))); for (i = 0; i <= NL_DUMP_MAX; i++) if (obj_ops->oo_dump[i]) printf("%s%s", i == 0 ? "" : ", ", dump_names[i]); printf("\n"); } if (ops->co_genl) { struct genl_ops *genl_ops = ops->co_genl; printf(" genl:\n" \ " name: %s\n" \ " user-hdr: %d\n" \ " id: %d\n", genl_ops->o_name, genl_ops->o_hdrsize, genl_ops->o_id); if (genl_ops->o_ncmds) { int i; printf(" cmds:\n"); for (i = 0; i < genl_ops->o_ncmds; i++) { struct genl_cmd *cmd = &genl_ops->o_cmds[i]; printf(" %s:\n" " id: %d\n" \ " maxattr: %d\n" \ " msg-parser: %s\n" \ " attr-policy: %s\n", cmd->c_name, cmd->c_id, cmd->c_maxattr, cmd->c_msg_parser ? "yes" : "no", cmd->c_attr_policy ? "yes" : "no"); } } } } int main(int argc, char *argv[]) { if (argc > 1 && !strcasecmp(argv[1], "-h")) print_usage(); nl_cache_ops_foreach(print, NULL); return 0; } libnl-3.2.29/src/nl-route-list.c0000644000175000017500000001002713023014600013266 00000000000000/* * src/nl-route-list.c List route attributes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static void print_usage(void) { printf( "Usage: nl-route-list [OPTION]... [ROUTE]\n" "\n" "Options\n" " -c, --cache List the contents of the route cache\n" " -f, --format=TYPE Output format { brief | details | stats }\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Route Options\n" " -d, --dst=ADDR destination prefix, e.g. 10.10.0.0/16\n" " -n, --nexthop=NH nexthop configuration:\n" " dev=DEV route via device\n" " weight=WEIGHT weight of nexthop\n" " flags=FLAGS\n" " via=GATEWAY route via other node\n" " realms=REALMS\n" " e.g. dev=eth0,via=192.168.1.12\n" " -t, --table=TABLE Routing table\n" " --family=FAMILY Address family\n" " --src=ADDR Source prefix\n" " --iif=DEV Incomming interface\n" " --pref-src=ADDR Preferred source address\n" " --metrics=OPTS Metrics configurations\n" " --priority=NUM Priotity\n" " --scope=SCOPE Scope\n" " --protocol=PROTO Protocol\n" " --type=TYPE { unicast | local | broadcast | multicast }\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *link_cache, *route_cache; struct rtnl_route *route; struct nl_dump_params params = { .dp_fd = stdout, .dp_type = NL_DUMP_LINE, }; int print_cache = 0; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); route = nl_cli_route_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_SRC = 258, ARG_IIF, ARG_PREF_SRC, ARG_METRICS, ARG_PRIORITY, ARG_SCOPE, ARG_PROTOCOL, ARG_TYPE, }; static struct option long_opts[] = { { "cache", 0, 0, 'c' }, { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dst", 1, 0, 'd' }, { "nexthop", 1, 0, 'n' }, { "table", 1, 0, 't' }, { "family", 1, 0, ARG_FAMILY }, { "src", 1, 0, ARG_SRC }, { "iif", 1, 0, ARG_IIF }, { "pref-src", 1, 0, ARG_PREF_SRC }, { "metrics", 1, 0, ARG_METRICS }, { "priority", 1, 0, ARG_PRIORITY }, { "scope", 1, 0, ARG_SCOPE }, { "protocol", 1, 0, ARG_PROTOCOL }, { "type", 1, 0, ARG_TYPE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "cf:hvd:n:t:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'c': print_cache = 1; break; case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_route_parse_dst(route, optarg); break; case 'n': nl_cli_route_parse_nexthop(route, optarg, link_cache); break; case 't': nl_cli_route_parse_table(route, optarg); break; case ARG_FAMILY: nl_cli_route_parse_family(route, optarg); break; case ARG_SRC: nl_cli_route_parse_src(route, optarg); break; case ARG_IIF: nl_cli_route_parse_iif(route, optarg, link_cache); break; case ARG_PREF_SRC: nl_cli_route_parse_pref_src(route, optarg); break; case ARG_METRICS: nl_cli_route_parse_metric(route, optarg); break; case ARG_PRIORITY: nl_cli_route_parse_prio(route, optarg); break; case ARG_SCOPE: nl_cli_route_parse_scope(route, optarg); break; case ARG_PROTOCOL: nl_cli_route_parse_protocol(route, optarg); break; case ARG_TYPE: nl_cli_route_parse_type(route, optarg); break; } } route_cache = nl_cli_route_alloc_cache(sock, print_cache ? ROUTE_CACHE_CONTENT : 0); nl_cache_dump_filter(route_cache, ¶ms, OBJ_CAST(route)); return 0; } libnl-3.2.29/src/nl-fib-lookup.c0000644000175000017500000000471613023014600013236 00000000000000/* * src/nl-fib-lookup.c FIB Route Lookup * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include static void print_usage(void) { printf( "Usage: nl-fib-lookup [options] \n" "Options:\n" " -t, --table Table id\n" " -f, --fwmark Firewall mark\n" " -s, --scope Routing scope\n" " -T, --tos Type of Service\n"); exit(1); } int main(int argc, char *argv[]) { struct nl_sock *nlh; struct nl_cache *result; struct flnl_request *request; struct nl_addr *addr; struct nl_dump_params params = { .dp_fd = stdout, .dp_type = NL_DUMP_DETAILS, }; int table = RT_TABLE_UNSPEC, scope = RT_SCOPE_UNIVERSE; int tos = 0, err = 1; uint64_t fwmark = 0; while (1) { static struct option long_opts[] = { {"table", 1, 0, 't'}, {"fwmark", 1, 0, 'f'}, {"scope", 1, 0, 's'}, {"tos", 1, 0, 'T'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0}, }; int c, idx = 0; c = getopt_long(argc, argv, "t:f:s:T:h", long_opts, &idx); if (c == -1) break; switch (c) { case 't': table = strtoul(optarg, NULL, 0); break; case 'f': fwmark = strtoul(optarg, NULL, 0); break; case 's': scope = strtoul(optarg, NULL, 0); break; case 'T': tos = strtoul(optarg, NULL, 0); break; default: print_usage(); } } if (optind >= argc) print_usage(); nlh = nl_cli_alloc_socket(); if ((err = nl_addr_parse(argv[optind], AF_INET, &addr)) < 0) nl_cli_fatal(err, "Unable to parse address \"%s\": %s\n", argv[optind], nl_geterror(err)); result = flnl_result_alloc_cache(); if (!result) nl_cli_fatal(ENOMEM, "Unable to allocate cache"); request = flnl_request_alloc(); if (!request) nl_cli_fatal(ENOMEM, "Unable to allocate request"); flnl_request_set_table(request, table); flnl_request_set_fwmark(request, fwmark); flnl_request_set_scope(request, scope); flnl_request_set_tos(request, tos); err = flnl_request_set_addr(request, addr); nl_addr_put(addr); if (err < 0) nl_cli_fatal(err, "Unable to send request: %s", nl_geterror(err)); nl_cli_connect(nlh, NETLINK_FIB_LOOKUP); err = flnl_lookup(nlh, request, result); if (err < 0) nl_cli_fatal(err, "Unable to lookup: %s\n", nl_geterror(err)); nl_cache_dump(result, ¶ms); return 0; } libnl-3.2.29/src/idiag-socket-details.c0000644000175000017500000000432613023014600014543 00000000000000/* * src/idiag-socket-details.c List socket details * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2 of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #include #include #include #include static void print_usage(void) { printf( "Usage: idiag-socket-details [OPTION]\n" "\n" "Options\n" " --summary Show socket detail summary.\n" " --details Show socket details on multiple lines.\n" " --stats Show full socket statistics.\n" " -h, --help Show this help.\n" " -v, --version Show versioning information.\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *idiag_cache; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_nl_cb = NULL, .dp_fd = stdout, }; int err = 0; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_INET_DIAG); for (;;) { int c, optidx = 0; enum { ARG_SUMMARY = 257, ARG_DETAILS = 258, ARG_STATS = 259, ARG_FAMILY, }; static struct option long_opts[] = { { "details", 0, 0, ARG_DETAILS }, { "summary", 0, 0, ARG_SUMMARY }, { "stats", 0, 0, ARG_STATS}, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hv", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case ARG_SUMMARY: params.dp_type = NL_DUMP_LINE; break; case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break; case ARG_STATS: params.dp_type = NL_DUMP_STATS; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; } } if ((err = idiagnl_msg_alloc_cache(sock, AF_INET, IDIAGNL_SS_ALL, &idiag_cache))) { nl_cli_fatal(err, "Unable to allocate idiag msg cache: %s", nl_geterror(err)); } nl_cache_mngt_provide(idiag_cache); nl_cache_dump_filter(idiag_cache, ¶ms, NULL); nl_cache_mngt_unprovide(idiag_cache); nl_cache_free(idiag_cache); nl_socket_free(sock); return 0; } libnl-3.2.29/src/nl-list-sockets.c0000644000175000017500000000217013023014600013603 00000000000000/* * nl-list-sockets.c Pretty-print /proc/net/netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #define PROC_NETLINK "/proc/net/netlink" int main(int argc, char *argv[]) { FILE *fd; char buf[2048], p[64]; fd = fopen(PROC_NETLINK, "r"); if (fd == NULL) { perror("fopen"); return -1; } printf("Address Family PID Groups rmem " "wmem CB refcnt\n"); while (fgets(buf, sizeof(buf), fd)) { unsigned long sk, cb; int ret, proto, pid, rmem, wmem, refcnt; unsigned int groups; ret = sscanf(buf, "%lx %d %d %08x %d %d %lx %d\n", &sk, &proto, &pid, &groups, &rmem, &wmem, &cb, &refcnt); if (ret != 8) continue; printf("0x%016lx %-16s %-6d %08x %-6d %-6d 0x%08lx %d\n", sk, nl_nlfamily2str(proto, p, sizeof(p)), pid, groups, rmem, wmem, cb, refcnt); } fclose(fd); return 0; } libnl-3.2.29/src/nl-class-delete.c0000644000175000017500000000653513023014600013535 00000000000000/* * src/nl-class-delete.c Delete Traffic Classes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include #include #include static int quiet = 0, default_yes = 0, deleted = 0, interactive = 0; static struct nl_sock *sock; static void print_usage(void) { printf( "Usage: nl-class-delete [OPTION]... [class]\n" "\n" "OPTIONS\n" " --interactive Run interactively.\n" " --yes Set default answer to yes.\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help text and exit.\n" " -v, --version Show versioning information and exit.\n" "\n" " -d, --dev=DEV Device the class is attached to.\n" " -p, --parent=ID Identifier of parent qdisc/class.\n" " -i, --id=ID Identifier\n" " -k, --kind=NAME Kind of class (e.g. pfifo_fast)\n" "\n" "EXAMPLE\n" " # Delete all classes on eth0 attached to parent 1:\n" " $ nl-class-delete --dev eth0 --parent 1:\n" "\n" ); exit(0); } static void delete_cb(struct nl_object *obj, void *arg) { struct rtnl_class *class = nl_object_priv(obj); struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; if (interactive && !nl_cli_confirm(obj, ¶ms, default_yes)) return; if ((err = rtnl_class_delete(sock, class)) < 0) nl_cli_fatal(err, "Unable to delete class: %s\n", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(obj, ¶ms); } deleted++; } int main(int argc, char *argv[]) { struct rtnl_class *class; struct rtnl_tc *tc; struct nl_cache *link_cache, *class_cache; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); class = nl_cli_class_alloc(); tc = (struct rtnl_tc *) class; for (;;) { int c, optidx = 0; enum { ARG_YES = 257, ARG_INTERACTIVE = 258, }; static struct option long_opts[] = { { "interactive", 0, 0, ARG_INTERACTIVE }, { "yes", 0, 0, ARG_YES }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "kind", 1, 0, 'k' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhvd:p:i:k:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': nl_cli_fatal(EINVAL, "Invalid options"); case ARG_INTERACTIVE: interactive = 1; break; case ARG_YES: default_yes = 1; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': nl_cli_tc_parse_handle(tc, optarg, 0); break; case 'k': nl_cli_tc_parse_kind(tc, optarg); break; } } if (!rtnl_tc_get_ifindex(tc)) nl_cli_fatal(EINVAL, "You must specify a network device (--dev=XXX)"); class_cache = nl_cli_class_alloc_cache(sock, rtnl_tc_get_ifindex(tc)); nl_cache_foreach_filter(class_cache, OBJ_CAST(class), delete_cb, NULL); if (!quiet) printf("Deleted %d classs\n", deleted); return 0; } libnl-3.2.29/src/nf-exp-delete.c0000644000175000017500000001367513023014600013221 00000000000000/* * src/nf-exp-delete.c Delete an expectation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2012 Rich Fought */ #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nf-exp-list [OPTION]... [CONNTRACK ENTRY]\n" "\n" "Options\n" " --replace Replace the address if it exists.\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Expectation Selection\n" " -i, --id=NUM Identifier\n" " --expect-proto=PROTOCOL Expectation protocol\n" " --expect-src=ADDR Expectation source address\n" " --expect-sport=PORT Expectation source port\n" " --expect-dst=ADDR Expectation destination address\n" " --expect-dport=PORT Expectation destination port\n" " --master-proto=PROTOCOL Master conntrack protocol\n" " --master-src=ADDR Master conntrack source address\n" " --master-sport=PORT Master conntrack source port\n" " --master-dst=ADDR Master conntrack destination address\n" " --master-dport=PORT Master conntrack destination port\n" " --mask-proto=PROTOCOL Mask protocol\n" " --mask-src=ADDR Mask source address\n" " --mask-sport=PORT Mask source port\n" " --mask-dst=ADDR Mask destination address\n" " --mask-dport=PORT Mask destination port\n" " -F, --family=FAMILY Address family\n" " --timeout=NUM Timeout value\n" " --helper=STRING Helper Name\n" " --flags Flags\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nfnl_exp *exp; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err, nlflags = 0; exp = nl_cli_exp_alloc(); for (;;) { int c, optidx = 0; enum { ARG_MARK = 270, ARG_TCP_STATE = 271, ARG_EXPECT_PROTO, ARG_EXPECT_SRC, ARG_EXPECT_SPORT, ARG_EXPECT_DST, ARG_EXPECT_DPORT, ARG_MASTER_PROTO, ARG_MASTER_SRC, ARG_MASTER_SPORT, ARG_MASTER_DST, ARG_MASTER_DPORT, ARG_MASK_PROTO, ARG_MASK_SRC, ARG_MASK_SPORT, ARG_MASK_DST, ARG_MASK_DPORT, ARG_TIMEOUT, ARG_HELPER_NAME, ARG_FLAGS, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "id", 1, 0, 'i' }, { "expect-proto", 1, 0, ARG_EXPECT_PROTO }, { "expect-src", 1, 0, ARG_EXPECT_SRC }, { "expect-sport", 1, 0, ARG_EXPECT_SPORT }, { "expect-dst", 1, 0, ARG_EXPECT_DST }, { "expect-dport", 1, 0, ARG_EXPECT_DPORT }, { "master-proto", 1, 0, ARG_MASTER_PROTO }, { "master-src", 1, 0, ARG_MASTER_SRC }, { "master-sport", 1, 0, ARG_MASTER_SPORT }, { "master-dst", 1, 0, ARG_MASTER_DST }, { "master-dport", 1, 0, ARG_MASTER_DPORT }, { "mask-proto", 1, 0, ARG_MASK_PROTO }, { "mask-src", 1, 0, ARG_MASK_SRC }, { "mask-sport", 1, 0, ARG_MASK_SPORT }, { "mask-dst", 1, 0, ARG_MASK_DST }, { "mask-dport", 1, 0, ARG_MASK_DPORT }, { "family", 1, 0, 'F' }, { "timeout", 1, 0, ARG_TIMEOUT }, { "helper", 1, 0, ARG_HELPER_NAME }, { "flags", 1, 0, ARG_FLAGS}, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "46f:hvi:p:F:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case 'q': quiet = 1; break; case '4': nfnl_exp_set_family(exp, AF_INET); break; case '6': nfnl_exp_set_family(exp, AF_INET6); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'i': nl_cli_exp_parse_id(exp, optarg); break; case ARG_EXPECT_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_EXPECT_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_EXPECT, optarg); break; case ARG_MASTER_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASTER_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_MASTER, optarg); break; case ARG_MASK_PROTO: nl_cli_exp_parse_l4protonum(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_SRC: nl_cli_exp_parse_src(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_SPORT: nl_cli_exp_parse_src_port(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_DST: nl_cli_exp_parse_dst(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case ARG_MASK_DPORT: nl_cli_exp_parse_dst_port(exp, NFNL_EXP_TUPLE_MASK, optarg); break; case 'F': nl_cli_exp_parse_family(exp, optarg); break; case ARG_TIMEOUT: nl_cli_exp_parse_timeout(exp, optarg); break; case ARG_HELPER_NAME: nl_cli_exp_parse_helper_name(exp, optarg); break; case ARG_FLAGS: nl_cli_exp_parse_flags(exp, optarg); break; } } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_NETFILTER); if ((err = nfnl_exp_del(sock, exp, nlflags)) < 0) nl_cli_fatal(err, "Unable to delete expectation: %s", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(OBJ_CAST(exp), ¶ms); } return 0; } libnl-3.2.29/src/nf-ct-add.c0000644000175000017500000001036013023014600012305 00000000000000/* * src/nf-ct-list.c List Conntrack Entries * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nf-ct-add [OPTION]... [CONNTRACK ENTRY]\n" "\n" "Options\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Conntrack Selection\n" " -p, --proto=PROTOCOL Protocol\n" " --orig-src=ADDR Original source address\n" " --orig-sport=PORT Original source port\n" " --orig-dst=ADDR Original destination address\n" " --orig-dport=PORT Original destination port\n" " --reply-src=ADDR Reply source address\n" " --reply-sport=PORT Reply source port\n" " --reply-dst=ADDR Reply destination address\n" " --reply-dport=PORT Reply destination port\n" " -F, --family=FAMILY Address family\n" " --mark=NUM Mark value\n" " --timeout=NUM Timeout value\n" " --status Bitset representing status of connection.\n" " --zone=NUM Zone value\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nfnl_ct *ct; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err, nlflags = NLM_F_CREATE; ct = nl_cli_ct_alloc(); for (;;) { int c, optidx = 0; enum { ARG_ORIG_SRC = 257, ARG_ORIG_SPORT = 258, ARG_ORIG_DST, ARG_ORIG_DPORT, ARG_REPLY_SRC, ARG_REPLY_SPORT, ARG_REPLY_DST, ARG_REPLY_DPORT, ARG_MARK, ARG_TIMEOUT, ARG_STATUS, ARG_ZONE, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "proto", 1, 0, 'p' }, { "orig-src", 1, 0, ARG_ORIG_SRC }, { "orig-sport", 1, 0, ARG_ORIG_SPORT }, { "orig-dst", 1, 0, ARG_ORIG_DST }, { "orig-dport", 1, 0, ARG_ORIG_DPORT }, { "reply-src", 1, 0, ARG_REPLY_SRC }, { "reply-sport", 1, 0, ARG_REPLY_SPORT }, { "reply-dst", 1, 0, ARG_REPLY_DST }, { "reply-dport", 1, 0, ARG_REPLY_DPORT }, { "family", 1, 0, 'F' }, { "mark", 1, 0, ARG_MARK }, { "timeout", 1, 0, ARG_TIMEOUT }, { "status", 1, 0, ARG_STATUS }, { "zone", 1, 0, ARG_ZONE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "46q:hv:p:F:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case 'q': quiet = 1; break; case '4': nfnl_ct_set_family(ct, AF_INET); break; case '6': nfnl_ct_set_family(ct, AF_INET6); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'p': nl_cli_ct_parse_protocol(ct, optarg); break; case ARG_ORIG_SRC: nl_cli_ct_parse_src(ct, 0, optarg); break; case ARG_ORIG_SPORT: nl_cli_ct_parse_src_port(ct, 0, optarg); break; case ARG_ORIG_DST: nl_cli_ct_parse_dst(ct, 0, optarg); break; case ARG_ORIG_DPORT: nl_cli_ct_parse_dst_port(ct, 0, optarg); break; case ARG_REPLY_SRC: nl_cli_ct_parse_src(ct, 1, optarg); break; case ARG_REPLY_SPORT: nl_cli_ct_parse_src_port(ct, 1, optarg); break; case ARG_REPLY_DST: nl_cli_ct_parse_dst(ct, 1, optarg); break; case ARG_REPLY_DPORT: nl_cli_ct_parse_dst_port(ct, 1, optarg); break; case 'F': nl_cli_ct_parse_family(ct, optarg); break; case ARG_MARK: nl_cli_ct_parse_mark(ct, optarg); break; case ARG_TIMEOUT: nl_cli_ct_parse_timeout(ct, optarg); break; case ARG_STATUS: nl_cli_ct_parse_status(ct, optarg); break; case ARG_ZONE: nl_cli_ct_parse_zone(ct, optarg); break; } } if (!quiet) { printf("Adding "); nl_object_dump(OBJ_CAST(ct), ¶ms); } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_NETFILTER); if ((err = nfnl_ct_add(sock, ct, nlflags)) < 0) nl_cli_fatal(err, "Unable to add conntrack: %s", nl_geterror(err)); if (!quiet) { printf("Added "); nl_object_dump(OBJ_CAST(ct), ¶ms); } return 0; } libnl-3.2.29/src/nl-qdisc-list.c0000644000175000017500000001160313023014600013234 00000000000000/* * src/nl-qdisc-list.c List Queueing Disciplines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2010 Thomas Graf */ #include #include #include #include #include #include #define NUM_INDENT 4 static struct nl_sock *sock; static int recursive = 0; static struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, }; static void print_usage(void) { printf( "Usage: nl-qdisc-list [OPTION]... [QDISC]\n" "\n" "OPTIONS\n" " --details Show details\n" " --stats Show statistics\n" " -r, --recursive Show recursive tree\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" " -d, --dev=DEV Device the qdisc is attached to. (default: all)\n" " -p, --parent=ID Identifier of parent qdisc.\n" " -i, --id=ID Identifier.\n" " -k, --kind=NAME Kind of qdisc (e.g. pfifo_fast)\n" "\n" "EXAMPLE\n" " # Display statistics of all qdiscs attached to eth0\n" " $ nl-qdisc-list --details --dev=eth0\n" "\n" ); exit(0); } static void list_classes(int ifindex, uint32_t parent); static void list_qdiscs(int ifindex, uint32_t parent); static void list_class(struct nl_object *obj, void *arg) { struct rtnl_tc *tc = nl_object_priv(obj); nl_object_dump(obj, ¶ms); list_classes(rtnl_tc_get_ifindex(tc), rtnl_tc_get_handle(tc)); list_qdiscs(rtnl_tc_get_ifindex(tc), rtnl_tc_get_handle(tc)); } static void list_classes(int ifindex, uint32_t parent) { struct nl_cache *class_cache; struct rtnl_class *filter = nl_cli_class_alloc(); class_cache = nl_cli_class_alloc_cache(sock, ifindex); rtnl_tc_set_parent((struct rtnl_tc *) filter, parent); params.dp_prefix += NUM_INDENT; nl_cache_foreach_filter(class_cache, OBJ_CAST(filter), list_class, NULL); params.dp_prefix -= NUM_INDENT; rtnl_class_put(filter); nl_cache_free(class_cache); } static void list_cls(int ifindex, uint32_t parent) { struct nl_cache *cls_cache; cls_cache = nl_cli_cls_alloc_cache(sock, ifindex, parent); params.dp_prefix += NUM_INDENT; nl_cache_dump(cls_cache, ¶ms); params.dp_prefix -= NUM_INDENT; nl_cache_free(cls_cache); } static void list_qdisc(struct nl_object *obj, void *arg) { struct rtnl_qdisc *qdisc = nl_object_priv(obj); struct rtnl_tc *tc = (struct rtnl_tc *) qdisc; nl_object_dump(obj, ¶ms); list_cls(rtnl_tc_get_ifindex(tc), rtnl_tc_get_handle(tc)); if (rtnl_tc_get_parent(tc) == TC_H_ROOT) { list_cls(rtnl_tc_get_ifindex(tc), TC_H_ROOT); list_classes(rtnl_tc_get_ifindex(tc), TC_H_ROOT); } list_classes(rtnl_tc_get_ifindex(tc), rtnl_tc_get_handle(tc)); } static void list_qdiscs(int ifindex, uint32_t parent) { struct nl_cache *qdisc_cache; struct rtnl_qdisc *filter = nl_cli_qdisc_alloc(); qdisc_cache = nl_cli_qdisc_alloc_cache(sock); rtnl_tc_set_ifindex((struct rtnl_tc *) filter, ifindex); rtnl_tc_set_parent((struct rtnl_tc *) filter, parent); params.dp_prefix += NUM_INDENT; nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(filter), list_qdisc, NULL); params.dp_prefix -= NUM_INDENT; rtnl_qdisc_put(filter); nl_cache_free(qdisc_cache); } int main(int argc, char *argv[]) { struct rtnl_qdisc *qdisc; struct rtnl_tc *tc; struct nl_cache *link_cache, *qdisc_cache; params.dp_fd = stdout; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); qdisc_cache = nl_cli_qdisc_alloc_cache(sock); qdisc = nl_cli_qdisc_alloc(); tc = (struct rtnl_tc *) qdisc; for (;;) { int c, optidx = 0; enum { ARG_DETAILS = 257, ARG_STATS = 258, }; static struct option long_opts[] = { { "details", 0, 0, ARG_DETAILS }, { "stats", 0, 0, ARG_STATS }, { "recursive", 0, 0, 'r' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "kind", 1, 0, 'k' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "rhvd:p:i:k:", long_opts, &optidx); if (c == -1) break; switch (c) { case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break; case ARG_STATS: params.dp_type = NL_DUMP_STATS; break; case 'r': recursive = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': nl_cli_tc_parse_handle(tc, optarg, 0); break; case 'k': nl_cli_tc_parse_kind(tc, optarg); break; } } if (recursive) nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(qdisc), list_qdisc, NULL); else nl_cache_dump_filter(qdisc_cache, ¶ms, OBJ_CAST(qdisc)); return 0; } libnl-3.2.29/src/nl-class-list.c0000644000175000017500000000562313023014600013243 00000000000000/* * src/nl-class-list.c List Traffic Classes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include #include #include #include static struct nl_sock *sock; static struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, }; static void print_usage(void) { printf( "Usage: nl-class-list [OPTION]...\n" "\n" "OPTIONS\n" " --details Show details\n" " --stats Show statistics\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" " -d, --dev=DEV Device the class is attached to. (default: all)\n" " -p, --parent=ID Identifier of parent class.\n" " -i, --id=ID Identifier.\n" " -k, --kind=NAME Kind of class (e.g. pfifo_fast)\n" "\n" "EXAMPLE\n" " # Display statistics of all classes on eth0\n" " $ nl-class-list --stats --dev=eth0\n" "\n" ); exit(0); } static void __dump_class(int ifindex, struct rtnl_class *filter) { struct nl_cache *cache; cache = nl_cli_class_alloc_cache(sock, ifindex); nl_cache_dump_filter(cache, ¶ms, OBJ_CAST(filter)); } static void dump_class(struct nl_object *obj, void *arg) { struct rtnl_link *link = nl_object_priv(obj); __dump_class(rtnl_link_get_ifindex(link), arg); } int main(int argc, char *argv[]) { struct rtnl_class *class; struct rtnl_tc *tc; struct nl_cache *link_cache; int ifindex; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); class = nl_cli_class_alloc(); tc = (struct rtnl_tc *) class; params.dp_fd = stdout; for (;;) { int c, optidx = 0; enum { ARG_DETAILS = 257, ARG_STATS = 258, }; static struct option long_opts[] = { { "details", 0, 0, ARG_DETAILS }, { "stats", 0, 0, ARG_STATS }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "kind", 1, 0, 'k' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hvd:p:i:k:", long_opts, &optidx); if (c == -1) break; switch (c) { case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break; case ARG_STATS: params.dp_type = NL_DUMP_STATS; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': nl_cli_tc_parse_handle(tc, optarg, 0); break; case 'k': nl_cli_tc_parse_kind(tc, optarg); break; } } if ((ifindex = rtnl_tc_get_ifindex(tc))) __dump_class(ifindex, class); else nl_cache_foreach(link_cache, dump_class, class); return 0; } libnl-3.2.29/src/nl-route-add.c0000644000175000017500000000773013023014600013052 00000000000000/* * src/nl-route-add.c Route addition utility * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static int quiet = 0; static struct nl_cache *link_cache, *route_cache; static void print_usage(void) { printf( "Usage: nl-route-add [OPTION]... [ROUTE]\n" "\n" "Options\n" " -q, --quiet Do not print informal notifications\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Route Options\n" " -d, --dst=ADDR destination prefix, e.g. 10.10.0.0/16\n" " -n, --nexthop=NH nexthop configuration:\n" " dev=DEV route via device\n" " weight=WEIGHT weight of nexthop\n" " flags=FLAGS\n" " via=GATEWAY route via other node\n" " realms=REALMS\n" " e.g. dev=eth0,via=192.168.1.12\n" " -t, --table=TABLE Routing table\n" " --family=FAMILY Address family\n" " --src=ADDR Source prefix\n" " --iif=DEV Incomming interface\n" " --pref-src=ADDR Preferred source address\n" " --metrics=OPTS Metrics configurations\n" " --priority=NUM Priotity\n" " --scope=SCOPE Scope\n" " --protocol=PROTO Protocol\n" " --type=TYPE { unicast | local | broadcast | multicast }\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_route *route; struct nl_dump_params dp = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err = 1; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); route_cache = nl_cli_route_alloc_cache(sock, 0); route = nl_cli_route_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_SRC = 258, ARG_IIF, ARG_PREF_SRC, ARG_METRICS, ARG_PRIORITY, ARG_SCOPE, ARG_PROTOCOL, ARG_TYPE, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dst", 1, 0, 'd' }, { "nexthop", 1, 0, 'n' }, { "table", 1, 0, 't' }, { "family", 1, 0, ARG_FAMILY }, { "src", 1, 0, ARG_SRC }, { "iif", 1, 0, ARG_IIF }, { "pref-src", 1, 0, ARG_PREF_SRC }, { "metrics", 1, 0, ARG_METRICS }, { "priority", 1, 0, ARG_PRIORITY }, { "scope", 1, 0, ARG_SCOPE }, { "protocol", 1, 0, ARG_PROTOCOL }, { "type", 1, 0, ARG_TYPE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhvd:n:t:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_route_parse_dst(route, optarg); break; case 'n': nl_cli_route_parse_nexthop(route, optarg, link_cache); break; case 't': nl_cli_route_parse_table(route, optarg); break; case ARG_FAMILY: nl_cli_route_parse_family(route, optarg); break; case ARG_SRC: nl_cli_route_parse_src(route, optarg); break; case ARG_IIF: nl_cli_route_parse_iif(route, optarg, link_cache); break; case ARG_PREF_SRC: nl_cli_route_parse_pref_src(route, optarg); break; case ARG_METRICS: nl_cli_route_parse_metric(route, optarg); break; case ARG_PRIORITY: nl_cli_route_parse_prio(route, optarg); break; case ARG_SCOPE: nl_cli_route_parse_scope(route, optarg); break; case ARG_PROTOCOL: nl_cli_route_parse_protocol(route, optarg); break; case ARG_TYPE: nl_cli_route_parse_type(route, optarg); break; } } if ((err = rtnl_route_add(sock, route, NLM_F_EXCL)) < 0) nl_cli_fatal(err, "Unable to add route: %s", nl_geterror(err)); if (!quiet) { printf("Added "); nl_object_dump(OBJ_CAST(route), &dp); } return 0; } libnl-3.2.29/src/nl-route-get.c0000644000175000017500000000370413023014600013076 00000000000000/* * src/nl-route-get.c Get Route Attributes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static void print_usage(void) { printf("Usage: nl-route-get \n"); exit(1); } static void parse_cb(struct nl_object *obj, void *arg) { //struct rtnl_route *route = (struct rtnl_route *) obj; struct nl_dump_params params = { .dp_fd = stdout, .dp_type = NL_DUMP_DETAILS, }; nl_object_dump(obj, ¶ms); } static int cb(struct nl_msg *msg, void *arg) { int err; if ((err = nl_msg_parse(msg, &parse_cb, NULL)) < 0) nl_cli_fatal(err, "Unable to parse object: %s", nl_geterror(err)); return 0; } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_addr *dst; int err = 1; if (argc < 2 || !strcmp(argv[1], "-h")) print_usage(); sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); nl_cli_link_alloc_cache(sock); nl_cli_route_alloc_cache(sock, 0); dst = nl_cli_addr_parse(argv[1], AF_INET); { struct nl_msg *m; struct rtmsg rmsg = { .rtm_family = nl_addr_get_family(dst), .rtm_dst_len = nl_addr_get_prefixlen(dst), }; m = nlmsg_alloc_simple(RTM_GETROUTE, 0); if (!m) nl_cli_fatal(ENOMEM, "out of memory"); if (nlmsg_append(m, &rmsg, sizeof(rmsg), NLMSG_ALIGNTO) < 0) nl_cli_fatal(ENOMEM, "out of memory"); if (nla_put_addr(m, RTA_DST, dst) < 0) nl_cli_fatal(ENOMEM, "out of memory"); err = nl_send_auto_complete(sock, m); nlmsg_free(m); if (err < 0) nl_cli_fatal(err, "%s", nl_geterror(err)); nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL); if (nl_recvmsgs_default(sock) < 0) nl_cli_fatal(err, "%s", nl_geterror(err)); } return 0; } libnl-3.2.29/src/nl-link-set.c0000644000175000017500000000723713023014600012716 00000000000000/* * src/nl-link-set.c Set link attributes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2010 Thomas Graf */ #include #include #include static struct nl_sock *sock; static int quiet = 0; #if 0 " changes := [link LINK]\n" " [master MASTER] [qdisc QDISC] [addr ADDR] [broadcast BRD]\n" " [{ up | down }] [{ arp | noarp }] [{ promisc | nopromisc }]\n" " [{ dynamic | nodynamic }] [{ multicast | nomulticast }]\n" " [{ trailers | notrailers }] [{ allmulticast | noallmulticast }]\n"); #endif static void print_usage(void) { printf( "Usage: nl-link-set [OPTION]... [LINK]\n" "\n" "Options\n" " -q, --quiet Do not print informal notifications\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Selecting the Link\n" " -n, --name=NAME link name\n" " -i, --index interface index\n" "Change Options\n" " --rename=NAME rename interface\n" " --mtu=NUM MTU value\n" " --txqlen=NUM TX queue length\n" " --weight=NUM weight\n" " --ifalias=NAME alias name (SNMP IfAlias)\n" " --state=up/down set interface up/down\n" ); exit(0); } static void set_cb(struct nl_object *obj, void *arg) { struct rtnl_link *link = nl_object_priv(obj); struct rtnl_link *change = arg; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; if ((err = rtnl_link_change(sock, link, change, 0)) < 0) nl_cli_fatal(err, "Unable to change link: %s", nl_geterror(err)); if (!quiet) { printf("Changed "); nl_object_dump(OBJ_CAST(link), ¶ms); } } int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link, *change; int ok = 0; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); link = nl_cli_link_alloc(); change = nl_cli_link_alloc(); for (;;) { int c, optidx = 0; enum { ARG_RENAME = 257, ARG_MTU = 258, ARG_TXQLEN, ARG_WEIGHT, ARG_IFALIAS, ARG_STATE, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "name", 1, 0, 'n' }, { "index", 1, 0, 'i' }, { "rename", 1, 0, ARG_RENAME }, { "mtu", 1, 0, ARG_MTU }, { "txqlen", 1, 0, ARG_TXQLEN }, { "weight", 1, 0, ARG_WEIGHT }, { "ifalias", 1, 0, ARG_IFALIAS }, { "state", 1, 0, ARG_STATE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhvn:i:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'n': ok++; nl_cli_link_parse_name(link, optarg); break; case 'i': ok++; nl_cli_link_parse_ifindex(link, optarg); break; case ARG_RENAME: nl_cli_link_parse_name(change, optarg); break; case ARG_MTU: nl_cli_link_parse_mtu(change, optarg); break; case ARG_TXQLEN: nl_cli_link_parse_txqlen(change, optarg); break; case ARG_WEIGHT: nl_cli_link_parse_weight(change, optarg); break; case ARG_IFALIAS: nl_cli_link_parse_ifalias(change, optarg); break; case ARG_STATE: if(!strcmp(optarg, "up")) rtnl_link_set_flags(change, IFF_UP); else if(!strcmp(optarg, "down")) rtnl_link_unset_flags(change, IFF_UP); break; } } if (!ok) print_usage(); nl_cache_foreach_filter(link_cache, OBJ_CAST(link), set_cb, change); return 0; } libnl-3.2.29/src/nl-rule-list.c0000644000175000017500000000347113023014600013104 00000000000000/* * src/nl-rule-dump.c Dump rule attributes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static void print_usage(void) { printf( "Usage: nl-rule-list [OPTION]... [ROUTE]\n" "\n" "Options\n" " -c, --cache List the contents of the route cache\n" " -f, --format=TYPE Output format { brief | details | stats }\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Rule Options\n" " --family Address family\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_rule *rule; struct nl_cache *rule_cache; struct nl_dump_params params = { .dp_fd = stdout, .dp_type = NL_DUMP_LINE, }; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); nl_cli_link_alloc_cache(sock); rule_cache = nl_cli_rule_alloc_cache(sock); rule = nl_cli_rule_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, }; static struct option long_opts[] = { { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "family", 1, 0, ARG_FAMILY }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "f:hv", long_opts, &optidx); if (c == -1) break; switch (c) { case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case ARG_FAMILY: nl_cli_rule_parse_family(rule, optarg); break; } } nl_cache_dump_filter(rule_cache, ¶ms, OBJ_CAST(rule)); return 0; } libnl-3.2.29/src/nl-neigh-delete.c0000644000175000017500000000631213023014600013513 00000000000000/* * src/nl-neigh-delete.c Delete a neighbour * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static int quiet = 0, default_yes = 0, deleted = 0, interactive = 0; static struct nl_sock *sock; static void print_usage(void) { printf( "Usage: nl-neigh-delete [OPTION]... [NEIGHBOUR]\n" "\n" "Options\n" " -i, --interactive Run interactively\n" " --yes Set default answer to yes\n" " -q, --quiet Do not print informal notifications\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Neighbour Options\n" " -a, --addr=ADDR Destination address of neighbour\n" " -l, --lladdr=ADDR Link layer address of neighbour\n" " -d, --dev=DEV Device the neighbour is connected to\n" " --family=FAMILY Destination address family\n" " --state=STATE Neighbour state, (default = permanent)\n" ); exit(0); } static void delete_cb(struct nl_object *obj, void *arg) { struct rtnl_neigh *neigh = nl_object_priv(obj); struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; if (interactive && !nl_cli_confirm(obj, ¶ms, default_yes)) return; if ((err = rtnl_neigh_delete(sock, neigh, 0)) < 0) nl_cli_fatal(err, "Unable to delete neighbour: %s\n", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(obj, ¶ms); } deleted++; } int main(int argc, char *argv[]) { struct rtnl_neigh *neigh; struct nl_cache *link_cache, *neigh_cache; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); neigh_cache = nl_cli_neigh_alloc_cache(sock); neigh = nl_cli_neigh_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_STATE = 258, ARG_YES, }; static struct option long_opts[] = { { "interactive", 0, 0, 'i' }, { "yes", 0, 0, ARG_YES }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "addr", 1, 0, 'a' }, { "lladdr", 1, 0, 'l' }, { "dev", 1, 0, 'd' }, { "family", 1, 0, ARG_FAMILY }, { "state", 1, 0, ARG_STATE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhva:l:d:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'i': interactive = 1; break; case ARG_YES: default_yes = 1; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'a': nl_cli_neigh_parse_dst(neigh, optarg); break; case 'l': nl_cli_neigh_parse_lladdr(neigh, optarg); break; case 'd': nl_cli_neigh_parse_dev(neigh, link_cache, optarg); break; case ARG_FAMILY: nl_cli_neigh_parse_family(neigh, optarg); break; case ARG_STATE: nl_cli_neigh_parse_state(neigh, optarg); break; } } nl_cache_foreach_filter(neigh_cache, OBJ_CAST(neigh), delete_cb, NULL); if (!quiet) printf("Deleted %d neighbours\n", deleted); return 0; } libnl-3.2.29/src/nl-neigh-add.c0000644000175000017500000000566313023014600013011 00000000000000/* * src/ nl-neigh-add.c Add a neighbour * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nl-neigh-add [OPTION]... NEIGHBOUR\n" "\n" "Options\n" " --update-only Do not create neighbour, updates exclusively\n" " --create-only Do not update neighbour if it exists already.\n" " -q, --quiet Do not print informal notifications\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Neighbour Options\n" " -a, --addr=ADDR Destination address of neighbour\n" " -l, --lladdr=ADDR Link layer address of neighbour\n" " -d, --dev=DEV Device the neighbour is connected to\n" " --state=STATE Neighbour state, (default = permanent)\n" "\n" "Example\n" " nl-neigh-add --create-only --addr=10.0.0.1 --dev=eth0 \\\n" " --lladdr=AA:BB:CC:DD:EE:FF\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_neigh *neigh; struct nl_cache *link_cache; struct nl_dump_params dp = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err, ok = 0, nlflags = NLM_F_REPLACE | NLM_F_CREATE; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); neigh = nl_cli_neigh_alloc(); for (;;) { int c, optidx = 0; enum { ARG_UPDATE_ONLY = 257, ARG_CREATE_ONLY = 258, ARG_STATE, }; static struct option long_opts[] = { { "update-only", 0, 0, ARG_UPDATE_ONLY }, { "create-only", 0, 0, ARG_CREATE_ONLY }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "addr", 1, 0, 'a' }, { "lladdr", 1, 0, 'l' }, { "dev", 1, 0, 'd' }, { "state", 1, 0, ARG_STATE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhva:l:d:", long_opts, &optidx); if (c == -1) break; switch (c) { case ARG_UPDATE_ONLY: nlflags &= ~NLM_F_CREATE; break; case ARG_CREATE_ONLY: nlflags |= NLM_F_EXCL; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'a': ok++; nl_cli_neigh_parse_dst(neigh, optarg); break; case 'l': nl_cli_neigh_parse_lladdr(neigh, optarg); break; case 'd': nl_cli_neigh_parse_dev(neigh, link_cache, optarg); break; case ARG_STATE: nl_cli_neigh_parse_state(neigh, optarg); break; } } if (!ok) print_usage(); if ((err = rtnl_neigh_add(sock, neigh, nlflags)) < 0) nl_cli_fatal(err, "Unable to add neighbour: %s", nl_geterror(err)); if (!quiet) { printf("Added "); nl_object_dump(OBJ_CAST(neigh), &dp); } return 0; } libnl-3.2.29/src/nl-tctree-list.c0000644000175000017500000001004413023014600013415 00000000000000/* * src/nl-tctree-list.c List Traffic Control Tree * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include #include #include static struct nl_sock *sock; static struct nl_cache *qdisc_cache, *class_cache; static struct nl_dump_params params = { .dp_type = NL_DUMP_DETAILS, }; static int ifindex; static void print_qdisc(struct nl_object *, void *); static void print_tc_childs(struct rtnl_tc *, void *); static void print_usage(void) { printf( "Usage: nl-tctree-list [OPTION]...\n" "\n" "Options\n" " -f, --format=TYPE Output format { brief | details | stats }\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" ); exit(0); } static void print_class(struct nl_object *obj, void *arg) { struct rtnl_qdisc *leaf; struct rtnl_class *class = (struct rtnl_class *) obj; struct nl_cache *cls_cache; uint32_t parent = rtnl_tc_get_handle((struct rtnl_tc *) class); params.dp_prefix = (int)(long) arg; nl_object_dump(obj, ¶ms); leaf = rtnl_class_leaf_qdisc(class, qdisc_cache); if (leaf) print_qdisc((struct nl_object *) leaf, arg + 2); print_tc_childs(TC_CAST(class), arg + 2); if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0) return; params.dp_prefix = (int)(long) arg + 2; nl_cache_dump(cls_cache, ¶ms); nl_cache_free(cls_cache); } static void print_tc_childs(struct rtnl_tc *tc, void *arg) { struct rtnl_class *filter; filter = nl_cli_class_alloc(); rtnl_tc_set_parent(TC_CAST(filter), rtnl_tc_get_handle(tc)); rtnl_tc_set_ifindex(TC_CAST(filter), rtnl_tc_get_ifindex(tc)); nl_cache_foreach_filter(class_cache, OBJ_CAST(filter), &print_class, arg); rtnl_class_put(filter); } static void print_qdisc(struct nl_object *obj, void *arg) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) obj; struct nl_cache *cls_cache; uint32_t parent = rtnl_tc_get_handle((struct rtnl_tc *) qdisc); params.dp_prefix = (int)(long) arg; nl_object_dump(obj, ¶ms); print_tc_childs(TC_CAST(qdisc), arg + 2); if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0) return; params.dp_prefix = (int)(long) arg + 2; nl_cache_dump(cls_cache, ¶ms); nl_cache_free(cls_cache); } static void print_link(struct nl_object *obj, void *arg) { struct rtnl_link *link = (struct rtnl_link *) obj; struct rtnl_qdisc *qdisc; ifindex = rtnl_link_get_ifindex(link); params.dp_prefix = 0; nl_object_dump(obj, ¶ms); if (rtnl_class_alloc_cache(sock, ifindex, &class_cache) < 0) return; qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_ROOT); if (qdisc) { print_qdisc((struct nl_object *) qdisc, (void *) 2); rtnl_qdisc_put(qdisc); } qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, 0); if (qdisc) { print_qdisc((struct nl_object *) qdisc, (void *) 2); rtnl_qdisc_put(qdisc); } qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_INGRESS); if (qdisc) { print_qdisc((struct nl_object *) qdisc, (void *) 2); rtnl_qdisc_put(qdisc); } nl_cache_free(class_cache); } int main(int argc, char *argv[]) { struct nl_cache *link_cache; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); qdisc_cache = nl_cli_qdisc_alloc_cache(sock); params.dp_fd = stdout; for (;;) { int c, optidx = 0; static struct option long_opts[] = { { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "f:hv", long_opts, &optidx); if (c == -1) break; switch (c) { case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; } } nl_cache_foreach(link_cache, &print_link, NULL); return 0; } libnl-3.2.29/src/nf-queue.c0000644000175000017500000000736413023014600012307 00000000000000/* * src/nf-queue.c Monitor netfilter queue events * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy * Copyright (c) 2010 Karl Hiramoto */ #include #include #include #include #include #include #include #include static struct nl_sock *nf_sock; static struct nfnl_queue *alloc_queue(void) { struct nfnl_queue *queue; queue = nfnl_queue_alloc(); if (!queue) nl_cli_fatal(ENOMEM, "Unable to allocate queue object"); return queue; } static void obj_input(struct nl_object *obj, void *arg) { struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) obj; struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; nfnl_queue_msg_set_verdict(msg, NF_ACCEPT); nl_object_dump(obj, &dp); nfnl_queue_msg_send_verdict(nf_sock, msg); } static int event_input(struct nl_msg *msg, void *arg) { if (nl_msg_parse(msg, &obj_input, NULL) < 0) fprintf(stderr, "<> Unknown message type\n"); /* Exit nl_recvmsgs_def() and return to the main select() */ return NL_STOP; } int main(int argc, char *argv[]) { struct nl_sock *rt_sock; struct nfnl_queue *queue; int copy_mode; uint32_t copy_range; int err = 1; int family; nf_sock = nfnl_queue_socket_alloc(); if (nf_sock == NULL) nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket"); nl_socket_disable_seq_check(nf_sock); nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) { printf("Usage: nf-queue family group [ copy_mode ] " "[ copy_range ]\n"); printf("family: [ inet | inet6 | ... ] \n"); printf("group: the --queue-num arg that you gave to iptables\n"); printf("copy_mode: [ none | meta | packet ] \n"); return 2; } nl_cli_connect(nf_sock, NETLINK_NETFILTER); if ((family = nl_str2af(argv[1])) == AF_UNSPEC) nl_cli_fatal(NLE_INVAL, "Unknown family \"%s\"", argv[1]); nfnl_queue_pf_unbind(nf_sock, family); if ((err = nfnl_queue_pf_bind(nf_sock, family)) < 0) nl_cli_fatal(err, "Unable to bind logger: %s", nl_geterror(err)); queue = alloc_queue(); nfnl_queue_set_group(queue, atoi(argv[2])); copy_mode = NFNL_QUEUE_COPY_PACKET; if (argc > 3) { copy_mode = nfnl_queue_str2copy_mode(argv[3]); if (copy_mode < 0) nl_cli_fatal(copy_mode, "Unable to parse copy mode \"%s\": %s", argv[3], nl_geterror(copy_mode)); } nfnl_queue_set_copy_mode(queue, copy_mode); copy_range = 0xFFFF; if (argc > 4) copy_range = atoi(argv[4]); nfnl_queue_set_copy_range(queue, copy_range); if ((err = nfnl_queue_create(nf_sock, queue)) < 0) nl_cli_fatal(err, "Unable to bind queue: %s", nl_geterror(err)); rt_sock = nl_cli_alloc_socket(); nl_cli_connect(rt_sock, NETLINK_ROUTE); nl_cli_link_alloc_cache(rt_sock); nl_socket_set_buffer_size(nf_sock, 1024*127, 1024*127); while (1) { fd_set rfds; int nffd, rtfd, maxfd, retval; FD_ZERO(&rfds); maxfd = nffd = nl_socket_get_fd(nf_sock); FD_SET(nffd, &rfds); rtfd = nl_socket_get_fd(rt_sock); FD_SET(rtfd, &rfds); if (maxfd < rtfd) maxfd = rtfd; /* wait for an incoming message on the netlink socket */ retval = select(maxfd+1, &rfds, NULL, NULL, NULL); if (retval) { if (FD_ISSET(nffd, &rfds)) nl_recvmsgs_default(nf_sock); if (FD_ISSET(rtfd, &rfds)) nl_recvmsgs_default(rt_sock); } } return 0; } libnl-3.2.29/src/nl-qdisc-delete.c0000644000175000017500000000705013023014600013524 00000000000000/* * src/nl-qdisc-delete.c Delete Queuing Disciplines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2010 Thomas Graf */ #include #include #include #include static int quiet = 0, default_yes = 0, deleted = 0, interactive = 0; static struct nl_sock *sock; static void print_usage(void) { printf( "Usage: nl-qdisc-delete [OPTION]... [QDISC]\n" "\n" "OPTIONS\n" " --interactive Run interactively.\n" " --yes Set default answer to yes.\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help text and exit.\n" " -v, --version Show versioning information and exit.\n" "\n" " -d, --dev=DEV Device the qdisc is attached to.\n" " -p, --parent=ID Identifier of parent qdisc/class.\n" " -i, --id=ID Identifier\n" " -k, --kind=NAME Kind of qdisc (e.g. pfifo_fast)\n" ); exit(0); } static void delete_cb(struct nl_object *obj, void *arg) { struct rtnl_qdisc *qdisc = nl_object_priv(obj); struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; /* Ignore default qdiscs, unable to delete */ if (rtnl_tc_get_handle((struct rtnl_tc *) qdisc) == 0) return; if (interactive && !nl_cli_confirm(obj, ¶ms, default_yes)) return; if ((err = rtnl_qdisc_delete(sock, qdisc)) < 0) nl_cli_fatal(err, "Unable to delete qdisc: %s\n", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(obj, ¶ms); } deleted++; } int main(int argc, char *argv[]) { struct rtnl_qdisc *qdisc; struct rtnl_tc *tc; struct nl_cache *link_cache, *qdisc_cache; int nfilter = 0; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); qdisc_cache = nl_cli_qdisc_alloc_cache(sock); qdisc = nl_cli_qdisc_alloc(); tc = (struct rtnl_tc *) qdisc; for (;;) { int c, optidx = 0; enum { ARG_YES = 257, ARG_INTERACTIVE = 258, }; static struct option long_opts[] = { { "interactive", 0, 0, ARG_INTERACTIVE }, { "yes", 0, 0, ARG_YES }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "kind", 1, 0, 'k' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhvd:p:i:k:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': nl_cli_fatal(EINVAL, "Invalid options"); case ARG_INTERACTIVE: interactive = 1; break; case ARG_YES: default_yes = 1; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nfilter++; nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nfilter++; nl_cli_tc_parse_parent(tc, optarg); break; case 'i': nfilter++; nl_cli_tc_parse_handle(tc, optarg, 0); break; case 'k': nfilter++; nl_cli_tc_parse_kind(tc, optarg); break; } } if (nfilter == 0 && !interactive && !default_yes) { nl_cli_fatal(EINVAL, "You are attempting to delete all qdiscs on all devices.\n" "If you want to proceed, run nl-qdisc-delete --yes.\n" "Aborting..."); } nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(qdisc), delete_cb, NULL); if (!quiet) printf("Deleted %d qdiscs\n", deleted); return 0; } libnl-3.2.29/src/Makefile.in0000644000175000017500000017665213031473644012512 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_CLI_INSTALL_BIN_TRUE@bin_PROGRAMS = $(am__EXEEXT_1) @ENABLE_CLI_INSTALL_BIN_FALSE@@ENABLE_CLI_INSTALL_SBIN_TRUE@sbin_PROGRAMS = $(am__EXEEXT_1) @ENABLE_CLI_INSTALL_BIN_FALSE@@ENABLE_CLI_INSTALL_SBIN_FALSE@noinst_PROGRAMS = $(am__EXEEXT_1) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = genl-ctrl-list$(EXEEXT) idiag-socket-details$(EXEEXT) \ nf-ct-add$(EXEEXT) nf-ct-list$(EXEEXT) nf-exp-add$(EXEEXT) \ nf-exp-delete$(EXEEXT) nf-exp-list$(EXEEXT) nf-log$(EXEEXT) \ nf-monitor$(EXEEXT) nf-queue$(EXEEXT) nl-addr-add$(EXEEXT) \ nl-addr-delete$(EXEEXT) nl-addr-list$(EXEEXT) \ nl-class-add$(EXEEXT) nl-class-delete$(EXEEXT) \ nl-classid-lookup$(EXEEXT) nl-class-list$(EXEEXT) \ nl-cls-add$(EXEEXT) nl-cls-delete$(EXEEXT) \ nl-cls-list$(EXEEXT) nl-fib-lookup$(EXEEXT) \ nl-link-enslave$(EXEEXT) nl-link-ifindex2name$(EXEEXT) \ nl-link-list$(EXEEXT) nl-link-name2ifindex$(EXEEXT) \ nl-link-release$(EXEEXT) nl-link-set$(EXEEXT) \ nl-link-stats$(EXEEXT) nl-list-caches$(EXEEXT) \ nl-list-sockets$(EXEEXT) nl-monitor$(EXEEXT) \ nl-neigh-add$(EXEEXT) nl-neigh-delete$(EXEEXT) \ nl-neigh-list$(EXEEXT) nl-neightbl-list$(EXEEXT) \ nl-pktloc-lookup$(EXEEXT) nl-qdisc-add$(EXEEXT) \ nl-qdisc-delete$(EXEEXT) nl-qdisc-list$(EXEEXT) \ nl-route-add$(EXEEXT) nl-route-delete$(EXEEXT) \ nl-route-get$(EXEEXT) nl-route-list$(EXEEXT) \ nl-rule-list$(EXEEXT) nl-tctree-list$(EXEEXT) \ nl-util-addr$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) am_genl_ctrl_list_OBJECTS = genl-ctrl-list.$(OBJEXT) genl_ctrl_list_OBJECTS = $(am_genl_ctrl_list_OBJECTS) genl_ctrl_list_LDADD = $(LDADD) genl_ctrl_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_idiag_socket_details_OBJECTS = idiag-socket-details.$(OBJEXT) idiag_socket_details_OBJECTS = $(am_idiag_socket_details_OBJECTS) idiag_socket_details_LDADD = $(LDADD) idiag_socket_details_DEPENDENCIES = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_ct_add_OBJECTS = nf-ct-add.$(OBJEXT) nf_ct_add_OBJECTS = $(am_nf_ct_add_OBJECTS) nf_ct_add_LDADD = $(LDADD) nf_ct_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_ct_list_OBJECTS = nf-ct-list.$(OBJEXT) nf_ct_list_OBJECTS = $(am_nf_ct_list_OBJECTS) nf_ct_list_LDADD = $(LDADD) nf_ct_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_exp_add_OBJECTS = nf-exp-add.$(OBJEXT) nf_exp_add_OBJECTS = $(am_nf_exp_add_OBJECTS) nf_exp_add_LDADD = $(LDADD) nf_exp_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_exp_delete_OBJECTS = nf-exp-delete.$(OBJEXT) nf_exp_delete_OBJECTS = $(am_nf_exp_delete_OBJECTS) nf_exp_delete_LDADD = $(LDADD) nf_exp_delete_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_exp_list_OBJECTS = nf-exp-list.$(OBJEXT) nf_exp_list_OBJECTS = $(am_nf_exp_list_OBJECTS) nf_exp_list_LDADD = $(LDADD) nf_exp_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_log_OBJECTS = nf-log.$(OBJEXT) nf_log_OBJECTS = $(am_nf_log_OBJECTS) nf_log_LDADD = $(LDADD) nf_log_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_monitor_OBJECTS = nf-monitor.$(OBJEXT) nf_monitor_OBJECTS = $(am_nf_monitor_OBJECTS) nf_monitor_LDADD = $(LDADD) nf_monitor_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nf_queue_OBJECTS = nf-queue.$(OBJEXT) nf_queue_OBJECTS = $(am_nf_queue_OBJECTS) nf_queue_LDADD = $(LDADD) nf_queue_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_addr_add_OBJECTS = nl-addr-add.$(OBJEXT) nl_addr_add_OBJECTS = $(am_nl_addr_add_OBJECTS) nl_addr_add_LDADD = $(LDADD) nl_addr_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_addr_delete_OBJECTS = nl-addr-delete.$(OBJEXT) nl_addr_delete_OBJECTS = $(am_nl_addr_delete_OBJECTS) nl_addr_delete_LDADD = $(LDADD) nl_addr_delete_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_addr_list_OBJECTS = nl-addr-list.$(OBJEXT) nl_addr_list_OBJECTS = $(am_nl_addr_list_OBJECTS) nl_addr_list_LDADD = $(LDADD) nl_addr_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_class_add_OBJECTS = nl-class-add.$(OBJEXT) nl_class_add_OBJECTS = $(am_nl_class_add_OBJECTS) nl_class_add_LDADD = $(LDADD) nl_class_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_class_delete_OBJECTS = nl-class-delete.$(OBJEXT) nl_class_delete_OBJECTS = $(am_nl_class_delete_OBJECTS) nl_class_delete_LDADD = $(LDADD) nl_class_delete_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_class_list_OBJECTS = nl-class-list.$(OBJEXT) nl_class_list_OBJECTS = $(am_nl_class_list_OBJECTS) nl_class_list_LDADD = $(LDADD) nl_class_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_classid_lookup_OBJECTS = nl-classid-lookup.$(OBJEXT) nl_classid_lookup_OBJECTS = $(am_nl_classid_lookup_OBJECTS) nl_classid_lookup_LDADD = $(LDADD) nl_classid_lookup_DEPENDENCIES = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_cls_add_OBJECTS = nl-cls-add.$(OBJEXT) nl_cls_add_OBJECTS = $(am_nl_cls_add_OBJECTS) nl_cls_add_LDADD = $(LDADD) nl_cls_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_cls_delete_OBJECTS = nl-cls-delete.$(OBJEXT) nl_cls_delete_OBJECTS = $(am_nl_cls_delete_OBJECTS) nl_cls_delete_LDADD = $(LDADD) nl_cls_delete_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_cls_list_OBJECTS = nl-cls-list.$(OBJEXT) nl_cls_list_OBJECTS = $(am_nl_cls_list_OBJECTS) nl_cls_list_LDADD = $(LDADD) nl_cls_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_fib_lookup_OBJECTS = nl-fib-lookup.$(OBJEXT) nl_fib_lookup_OBJECTS = $(am_nl_fib_lookup_OBJECTS) nl_fib_lookup_LDADD = $(LDADD) nl_fib_lookup_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la nl_link_enslave_SOURCES = nl-link-enslave.c nl_link_enslave_OBJECTS = nl-link-enslave.$(OBJEXT) nl_link_enslave_LDADD = $(LDADD) nl_link_enslave_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_link_ifindex2name_OBJECTS = nl-link-ifindex2name.$(OBJEXT) nl_link_ifindex2name_OBJECTS = $(am_nl_link_ifindex2name_OBJECTS) nl_link_ifindex2name_LDADD = $(LDADD) nl_link_ifindex2name_DEPENDENCIES = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_link_list_OBJECTS = nl-link-list.$(OBJEXT) nl_link_list_OBJECTS = $(am_nl_link_list_OBJECTS) nl_link_list_LDADD = $(LDADD) nl_link_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_link_name2ifindex_OBJECTS = nl-link-name2ifindex.$(OBJEXT) nl_link_name2ifindex_OBJECTS = $(am_nl_link_name2ifindex_OBJECTS) nl_link_name2ifindex_LDADD = $(LDADD) nl_link_name2ifindex_DEPENDENCIES = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la nl_link_release_SOURCES = nl-link-release.c nl_link_release_OBJECTS = nl-link-release.$(OBJEXT) nl_link_release_LDADD = $(LDADD) nl_link_release_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_link_set_OBJECTS = nl-link-set.$(OBJEXT) nl_link_set_OBJECTS = $(am_nl_link_set_OBJECTS) nl_link_set_LDADD = $(LDADD) nl_link_set_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_link_stats_OBJECTS = nl-link-stats.$(OBJEXT) nl_link_stats_OBJECTS = $(am_nl_link_stats_OBJECTS) nl_link_stats_LDADD = $(LDADD) nl_link_stats_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_list_caches_OBJECTS = nl-list-caches.$(OBJEXT) nl_list_caches_OBJECTS = $(am_nl_list_caches_OBJECTS) nl_list_caches_LDADD = $(LDADD) nl_list_caches_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_list_sockets_OBJECTS = nl-list-sockets.$(OBJEXT) nl_list_sockets_OBJECTS = $(am_nl_list_sockets_OBJECTS) nl_list_sockets_LDADD = $(LDADD) nl_list_sockets_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_monitor_OBJECTS = nl-monitor.$(OBJEXT) nl_monitor_OBJECTS = $(am_nl_monitor_OBJECTS) nl_monitor_LDADD = $(LDADD) nl_monitor_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_neigh_add_OBJECTS = nl-neigh-add.$(OBJEXT) nl_neigh_add_OBJECTS = $(am_nl_neigh_add_OBJECTS) nl_neigh_add_LDADD = $(LDADD) nl_neigh_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_neigh_delete_OBJECTS = nl-neigh-delete.$(OBJEXT) nl_neigh_delete_OBJECTS = $(am_nl_neigh_delete_OBJECTS) nl_neigh_delete_LDADD = $(LDADD) nl_neigh_delete_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_neigh_list_OBJECTS = nl-neigh-list.$(OBJEXT) nl_neigh_list_OBJECTS = $(am_nl_neigh_list_OBJECTS) nl_neigh_list_LDADD = $(LDADD) nl_neigh_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_neightbl_list_OBJECTS = nl-neightbl-list.$(OBJEXT) nl_neightbl_list_OBJECTS = $(am_nl_neightbl_list_OBJECTS) nl_neightbl_list_LDADD = $(LDADD) nl_neightbl_list_DEPENDENCIES = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_pktloc_lookup_OBJECTS = nl-pktloc-lookup.$(OBJEXT) nl_pktloc_lookup_OBJECTS = $(am_nl_pktloc_lookup_OBJECTS) nl_pktloc_lookup_LDADD = $(LDADD) nl_pktloc_lookup_DEPENDENCIES = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_qdisc_add_OBJECTS = nl-qdisc-add.$(OBJEXT) nl_qdisc_add_OBJECTS = $(am_nl_qdisc_add_OBJECTS) nl_qdisc_add_LDADD = $(LDADD) nl_qdisc_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_qdisc_delete_OBJECTS = nl-qdisc-delete.$(OBJEXT) nl_qdisc_delete_OBJECTS = $(am_nl_qdisc_delete_OBJECTS) nl_qdisc_delete_LDADD = $(LDADD) nl_qdisc_delete_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_qdisc_list_OBJECTS = nl-qdisc-list.$(OBJEXT) nl_qdisc_list_OBJECTS = $(am_nl_qdisc_list_OBJECTS) nl_qdisc_list_LDADD = $(LDADD) nl_qdisc_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_route_add_OBJECTS = nl-route-add.$(OBJEXT) nl_route_add_OBJECTS = $(am_nl_route_add_OBJECTS) nl_route_add_LDADD = $(LDADD) nl_route_add_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_route_delete_OBJECTS = nl-route-delete.$(OBJEXT) nl_route_delete_OBJECTS = $(am_nl_route_delete_OBJECTS) nl_route_delete_LDADD = $(LDADD) nl_route_delete_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_route_get_OBJECTS = nl-route-get.$(OBJEXT) nl_route_get_OBJECTS = $(am_nl_route_get_OBJECTS) nl_route_get_LDADD = $(LDADD) nl_route_get_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_route_list_OBJECTS = nl-route-list.$(OBJEXT) nl_route_list_OBJECTS = $(am_nl_route_list_OBJECTS) nl_route_list_LDADD = $(LDADD) nl_route_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_rule_list_OBJECTS = nl-rule-list.$(OBJEXT) nl_rule_list_OBJECTS = $(am_nl_rule_list_OBJECTS) nl_rule_list_LDADD = $(LDADD) nl_rule_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_tctree_list_OBJECTS = nl-tctree-list.$(OBJEXT) nl_tctree_list_OBJECTS = $(am_nl_tctree_list_OBJECTS) nl_tctree_list_LDADD = $(LDADD) nl_tctree_list_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la am_nl_util_addr_OBJECTS = nl-util-addr.$(OBJEXT) nl_util_addr_OBJECTS = $(am_nl_util_addr_OBJECTS) nl_util_addr_LDADD = $(LDADD) nl_util_addr_DEPENDENCIES = ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/lib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(genl_ctrl_list_SOURCES) $(idiag_socket_details_SOURCES) \ $(nf_ct_add_SOURCES) $(nf_ct_list_SOURCES) \ $(nf_exp_add_SOURCES) $(nf_exp_delete_SOURCES) \ $(nf_exp_list_SOURCES) $(nf_log_SOURCES) $(nf_monitor_SOURCES) \ $(nf_queue_SOURCES) $(nl_addr_add_SOURCES) \ $(nl_addr_delete_SOURCES) $(nl_addr_list_SOURCES) \ $(nl_class_add_SOURCES) $(nl_class_delete_SOURCES) \ $(nl_class_list_SOURCES) $(nl_classid_lookup_SOURCES) \ $(nl_cls_add_SOURCES) $(nl_cls_delete_SOURCES) \ $(nl_cls_list_SOURCES) $(nl_fib_lookup_SOURCES) \ nl-link-enslave.c $(nl_link_ifindex2name_SOURCES) \ $(nl_link_list_SOURCES) $(nl_link_name2ifindex_SOURCES) \ nl-link-release.c $(nl_link_set_SOURCES) \ $(nl_link_stats_SOURCES) $(nl_list_caches_SOURCES) \ $(nl_list_sockets_SOURCES) $(nl_monitor_SOURCES) \ $(nl_neigh_add_SOURCES) $(nl_neigh_delete_SOURCES) \ $(nl_neigh_list_SOURCES) $(nl_neightbl_list_SOURCES) \ $(nl_pktloc_lookup_SOURCES) $(nl_qdisc_add_SOURCES) \ $(nl_qdisc_delete_SOURCES) $(nl_qdisc_list_SOURCES) \ $(nl_route_add_SOURCES) $(nl_route_delete_SOURCES) \ $(nl_route_get_SOURCES) $(nl_route_list_SOURCES) \ $(nl_rule_list_SOURCES) $(nl_tctree_list_SOURCES) \ $(nl_util_addr_SOURCES) DIST_SOURCES = $(genl_ctrl_list_SOURCES) \ $(idiag_socket_details_SOURCES) $(nf_ct_add_SOURCES) \ $(nf_ct_list_SOURCES) $(nf_exp_add_SOURCES) \ $(nf_exp_delete_SOURCES) $(nf_exp_list_SOURCES) \ $(nf_log_SOURCES) $(nf_monitor_SOURCES) $(nf_queue_SOURCES) \ $(nl_addr_add_SOURCES) $(nl_addr_delete_SOURCES) \ $(nl_addr_list_SOURCES) $(nl_class_add_SOURCES) \ $(nl_class_delete_SOURCES) $(nl_class_list_SOURCES) \ $(nl_classid_lookup_SOURCES) $(nl_cls_add_SOURCES) \ $(nl_cls_delete_SOURCES) $(nl_cls_list_SOURCES) \ $(nl_fib_lookup_SOURCES) nl-link-enslave.c \ $(nl_link_ifindex2name_SOURCES) $(nl_link_list_SOURCES) \ $(nl_link_name2ifindex_SOURCES) nl-link-release.c \ $(nl_link_set_SOURCES) $(nl_link_stats_SOURCES) \ $(nl_list_caches_SOURCES) $(nl_list_sockets_SOURCES) \ $(nl_monitor_SOURCES) $(nl_neigh_add_SOURCES) \ $(nl_neigh_delete_SOURCES) $(nl_neigh_list_SOURCES) \ $(nl_neightbl_list_SOURCES) $(nl_pktloc_lookup_SOURCES) \ $(nl_qdisc_add_SOURCES) $(nl_qdisc_delete_SOURCES) \ $(nl_qdisc_list_SOURCES) $(nl_route_add_SOURCES) \ $(nl_route_delete_SOURCES) $(nl_route_get_SOURCES) \ $(nl_route_list_SOURCES) $(nl_rule_list_SOURCES) \ $(nl_tctree_list_SOURCES) $(nl_util_addr_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = lib AM_CPPFLAGS = \ -I${top_srcdir}/include/linux-private \ -I${top_srcdir}/include \ -I${top_builddir}/include \ -D_GNU_SOURCE \ -DSYSCONFDIR=\"$(sysconfdir)/libnl\" AM_CFLAGS = -Wall LDADD = \ ${top_builddir}/src/lib/libnl-cli-3.la \ ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-idiag-3.la cli_programs = \ genl-ctrl-list \ idiag-socket-details \ nf-ct-add \ nf-ct-list \ nf-exp-add \ nf-exp-delete \ nf-exp-list \ nf-log \ nf-monitor \ nf-queue \ nl-addr-add \ nl-addr-delete \ nl-addr-list \ nl-class-add \ nl-class-delete \ nl-classid-lookup \ nl-class-list \ nl-cls-add \ nl-cls-delete \ nl-cls-list \ nl-fib-lookup \ nl-link-enslave \ nl-link-ifindex2name \ nl-link-list \ nl-link-name2ifindex \ nl-link-release \ nl-link-set \ nl-link-stats \ nl-list-caches \ nl-list-sockets \ nl-monitor \ nl-neigh-add \ nl-neigh-delete \ nl-neigh-list \ nl-neightbl-list \ nl-pktloc-lookup \ nl-qdisc-add \ nl-qdisc-delete \ nl-qdisc-list \ nl-route-add \ nl-route-delete \ nl-route-get \ nl-route-list \ nl-rule-list \ nl-tctree-list \ nl-util-addr genl_ctrl_list_SOURCES = genl-ctrl-list.c nf_ct_list_SOURCES = nf-ct-list.c nf_ct_add_SOURCES = nf-ct-add.c nf_log_SOURCES = nf-log.c nf_queue_SOURCES = nf-queue.c nf_monitor_SOURCES = nf-monitor.c nf_exp_list_SOURCES = nf-exp-list.c nf_exp_add_SOURCES = nf-exp-add.c nf_exp_delete_SOURCES = nf-exp-delete.c nl_addr_add_SOURCES = nl-addr-add.c nl_addr_delete_SOURCES = nl-addr-delete.c nl_addr_list_SOURCES = nl-addr-list.c nl_link_list_SOURCES = nl-link-list.c nl_link_set_SOURCES = nl-link-set.c nl_link_stats_SOURCES = nl-link-stats.c nl_link_ifindex2name_SOURCES = nl-link-ifindex2name.c nl_link_name2ifindex_SOURCES = nl-link-name2ifindex.c nl_monitor_SOURCES = nl-monitor.c nl_neigh_add_SOURCES = nl-neigh-add.c nl_neigh_delete_SOURCES = nl-neigh-delete.c nl_neigh_list_SOURCES = nl-neigh-list.c nl_neightbl_list_SOURCES = nl-neightbl-list.c nl_qdisc_add_SOURCES = nl-qdisc-add.c nl_qdisc_delete_SOURCES = nl-qdisc-delete.c nl_qdisc_list_SOURCES = nl-qdisc-list.c nl_class_add_SOURCES = nl-class-add.c nl_class_delete_SOURCES = nl-class-delete.c nl_class_list_SOURCES = nl-class-list.c nl_cls_add_SOURCES = nl-cls-add.c nl_cls_list_SOURCES = nl-cls-list.c nl_cls_delete_SOURCES = nl-cls-delete.c nl_route_add_SOURCES = nl-route-add.c nl_route_delete_SOURCES = nl-route-delete.c nl_route_get_SOURCES = nl-route-get.c nl_route_list_SOURCES = nl-route-list.c nl_rule_list_SOURCES = nl-rule-list.c nl_tctree_list_SOURCES = nl-tctree-list.c nl_fib_lookup_SOURCES = nl-fib-lookup.c nl_list_caches_SOURCES = nl-list-caches.c nl_list_sockets_SOURCES = nl-list-sockets.c nl_util_addr_SOURCES = nl-util-addr.c nl_pktloc_lookup_SOURCES = nl-pktloc-lookup.c nl_classid_lookup_SOURCES = nl-classid-lookup.c idiag_socket_details_SOURCES = idiag-socket-details.c all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list genl-ctrl-list$(EXEEXT): $(genl_ctrl_list_OBJECTS) $(genl_ctrl_list_DEPENDENCIES) $(EXTRA_genl_ctrl_list_DEPENDENCIES) @rm -f genl-ctrl-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(genl_ctrl_list_OBJECTS) $(genl_ctrl_list_LDADD) $(LIBS) idiag-socket-details$(EXEEXT): $(idiag_socket_details_OBJECTS) $(idiag_socket_details_DEPENDENCIES) $(EXTRA_idiag_socket_details_DEPENDENCIES) @rm -f idiag-socket-details$(EXEEXT) $(AM_V_CCLD)$(LINK) $(idiag_socket_details_OBJECTS) $(idiag_socket_details_LDADD) $(LIBS) nf-ct-add$(EXEEXT): $(nf_ct_add_OBJECTS) $(nf_ct_add_DEPENDENCIES) $(EXTRA_nf_ct_add_DEPENDENCIES) @rm -f nf-ct-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_ct_add_OBJECTS) $(nf_ct_add_LDADD) $(LIBS) nf-ct-list$(EXEEXT): $(nf_ct_list_OBJECTS) $(nf_ct_list_DEPENDENCIES) $(EXTRA_nf_ct_list_DEPENDENCIES) @rm -f nf-ct-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_ct_list_OBJECTS) $(nf_ct_list_LDADD) $(LIBS) nf-exp-add$(EXEEXT): $(nf_exp_add_OBJECTS) $(nf_exp_add_DEPENDENCIES) $(EXTRA_nf_exp_add_DEPENDENCIES) @rm -f nf-exp-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_exp_add_OBJECTS) $(nf_exp_add_LDADD) $(LIBS) nf-exp-delete$(EXEEXT): $(nf_exp_delete_OBJECTS) $(nf_exp_delete_DEPENDENCIES) $(EXTRA_nf_exp_delete_DEPENDENCIES) @rm -f nf-exp-delete$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_exp_delete_OBJECTS) $(nf_exp_delete_LDADD) $(LIBS) nf-exp-list$(EXEEXT): $(nf_exp_list_OBJECTS) $(nf_exp_list_DEPENDENCIES) $(EXTRA_nf_exp_list_DEPENDENCIES) @rm -f nf-exp-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_exp_list_OBJECTS) $(nf_exp_list_LDADD) $(LIBS) nf-log$(EXEEXT): $(nf_log_OBJECTS) $(nf_log_DEPENDENCIES) $(EXTRA_nf_log_DEPENDENCIES) @rm -f nf-log$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_log_OBJECTS) $(nf_log_LDADD) $(LIBS) nf-monitor$(EXEEXT): $(nf_monitor_OBJECTS) $(nf_monitor_DEPENDENCIES) $(EXTRA_nf_monitor_DEPENDENCIES) @rm -f nf-monitor$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_monitor_OBJECTS) $(nf_monitor_LDADD) $(LIBS) nf-queue$(EXEEXT): $(nf_queue_OBJECTS) $(nf_queue_DEPENDENCIES) $(EXTRA_nf_queue_DEPENDENCIES) @rm -f nf-queue$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nf_queue_OBJECTS) $(nf_queue_LDADD) $(LIBS) nl-addr-add$(EXEEXT): $(nl_addr_add_OBJECTS) $(nl_addr_add_DEPENDENCIES) $(EXTRA_nl_addr_add_DEPENDENCIES) @rm -f nl-addr-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_addr_add_OBJECTS) $(nl_addr_add_LDADD) $(LIBS) nl-addr-delete$(EXEEXT): $(nl_addr_delete_OBJECTS) $(nl_addr_delete_DEPENDENCIES) $(EXTRA_nl_addr_delete_DEPENDENCIES) @rm -f nl-addr-delete$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_addr_delete_OBJECTS) $(nl_addr_delete_LDADD) $(LIBS) nl-addr-list$(EXEEXT): $(nl_addr_list_OBJECTS) $(nl_addr_list_DEPENDENCIES) $(EXTRA_nl_addr_list_DEPENDENCIES) @rm -f nl-addr-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_addr_list_OBJECTS) $(nl_addr_list_LDADD) $(LIBS) nl-class-add$(EXEEXT): $(nl_class_add_OBJECTS) $(nl_class_add_DEPENDENCIES) $(EXTRA_nl_class_add_DEPENDENCIES) @rm -f nl-class-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_class_add_OBJECTS) $(nl_class_add_LDADD) $(LIBS) nl-class-delete$(EXEEXT): $(nl_class_delete_OBJECTS) $(nl_class_delete_DEPENDENCIES) $(EXTRA_nl_class_delete_DEPENDENCIES) @rm -f nl-class-delete$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_class_delete_OBJECTS) $(nl_class_delete_LDADD) $(LIBS) nl-class-list$(EXEEXT): $(nl_class_list_OBJECTS) $(nl_class_list_DEPENDENCIES) $(EXTRA_nl_class_list_DEPENDENCIES) @rm -f nl-class-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_class_list_OBJECTS) $(nl_class_list_LDADD) $(LIBS) nl-classid-lookup$(EXEEXT): $(nl_classid_lookup_OBJECTS) $(nl_classid_lookup_DEPENDENCIES) $(EXTRA_nl_classid_lookup_DEPENDENCIES) @rm -f nl-classid-lookup$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_classid_lookup_OBJECTS) $(nl_classid_lookup_LDADD) $(LIBS) nl-cls-add$(EXEEXT): $(nl_cls_add_OBJECTS) $(nl_cls_add_DEPENDENCIES) $(EXTRA_nl_cls_add_DEPENDENCIES) @rm -f nl-cls-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_cls_add_OBJECTS) $(nl_cls_add_LDADD) $(LIBS) nl-cls-delete$(EXEEXT): $(nl_cls_delete_OBJECTS) $(nl_cls_delete_DEPENDENCIES) $(EXTRA_nl_cls_delete_DEPENDENCIES) @rm -f nl-cls-delete$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_cls_delete_OBJECTS) $(nl_cls_delete_LDADD) $(LIBS) nl-cls-list$(EXEEXT): $(nl_cls_list_OBJECTS) $(nl_cls_list_DEPENDENCIES) $(EXTRA_nl_cls_list_DEPENDENCIES) @rm -f nl-cls-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_cls_list_OBJECTS) $(nl_cls_list_LDADD) $(LIBS) nl-fib-lookup$(EXEEXT): $(nl_fib_lookup_OBJECTS) $(nl_fib_lookup_DEPENDENCIES) $(EXTRA_nl_fib_lookup_DEPENDENCIES) @rm -f nl-fib-lookup$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_fib_lookup_OBJECTS) $(nl_fib_lookup_LDADD) $(LIBS) nl-link-enslave$(EXEEXT): $(nl_link_enslave_OBJECTS) $(nl_link_enslave_DEPENDENCIES) $(EXTRA_nl_link_enslave_DEPENDENCIES) @rm -f nl-link-enslave$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_link_enslave_OBJECTS) $(nl_link_enslave_LDADD) $(LIBS) nl-link-ifindex2name$(EXEEXT): $(nl_link_ifindex2name_OBJECTS) $(nl_link_ifindex2name_DEPENDENCIES) $(EXTRA_nl_link_ifindex2name_DEPENDENCIES) @rm -f nl-link-ifindex2name$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_link_ifindex2name_OBJECTS) $(nl_link_ifindex2name_LDADD) $(LIBS) nl-link-list$(EXEEXT): $(nl_link_list_OBJECTS) $(nl_link_list_DEPENDENCIES) $(EXTRA_nl_link_list_DEPENDENCIES) @rm -f nl-link-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_link_list_OBJECTS) $(nl_link_list_LDADD) $(LIBS) nl-link-name2ifindex$(EXEEXT): $(nl_link_name2ifindex_OBJECTS) $(nl_link_name2ifindex_DEPENDENCIES) $(EXTRA_nl_link_name2ifindex_DEPENDENCIES) @rm -f nl-link-name2ifindex$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_link_name2ifindex_OBJECTS) $(nl_link_name2ifindex_LDADD) $(LIBS) nl-link-release$(EXEEXT): $(nl_link_release_OBJECTS) $(nl_link_release_DEPENDENCIES) $(EXTRA_nl_link_release_DEPENDENCIES) @rm -f nl-link-release$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_link_release_OBJECTS) $(nl_link_release_LDADD) $(LIBS) nl-link-set$(EXEEXT): $(nl_link_set_OBJECTS) $(nl_link_set_DEPENDENCIES) $(EXTRA_nl_link_set_DEPENDENCIES) @rm -f nl-link-set$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_link_set_OBJECTS) $(nl_link_set_LDADD) $(LIBS) nl-link-stats$(EXEEXT): $(nl_link_stats_OBJECTS) $(nl_link_stats_DEPENDENCIES) $(EXTRA_nl_link_stats_DEPENDENCIES) @rm -f nl-link-stats$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_link_stats_OBJECTS) $(nl_link_stats_LDADD) $(LIBS) nl-list-caches$(EXEEXT): $(nl_list_caches_OBJECTS) $(nl_list_caches_DEPENDENCIES) $(EXTRA_nl_list_caches_DEPENDENCIES) @rm -f nl-list-caches$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_list_caches_OBJECTS) $(nl_list_caches_LDADD) $(LIBS) nl-list-sockets$(EXEEXT): $(nl_list_sockets_OBJECTS) $(nl_list_sockets_DEPENDENCIES) $(EXTRA_nl_list_sockets_DEPENDENCIES) @rm -f nl-list-sockets$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_list_sockets_OBJECTS) $(nl_list_sockets_LDADD) $(LIBS) nl-monitor$(EXEEXT): $(nl_monitor_OBJECTS) $(nl_monitor_DEPENDENCIES) $(EXTRA_nl_monitor_DEPENDENCIES) @rm -f nl-monitor$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_monitor_OBJECTS) $(nl_monitor_LDADD) $(LIBS) nl-neigh-add$(EXEEXT): $(nl_neigh_add_OBJECTS) $(nl_neigh_add_DEPENDENCIES) $(EXTRA_nl_neigh_add_DEPENDENCIES) @rm -f nl-neigh-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_neigh_add_OBJECTS) $(nl_neigh_add_LDADD) $(LIBS) nl-neigh-delete$(EXEEXT): $(nl_neigh_delete_OBJECTS) $(nl_neigh_delete_DEPENDENCIES) $(EXTRA_nl_neigh_delete_DEPENDENCIES) @rm -f nl-neigh-delete$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_neigh_delete_OBJECTS) $(nl_neigh_delete_LDADD) $(LIBS) nl-neigh-list$(EXEEXT): $(nl_neigh_list_OBJECTS) $(nl_neigh_list_DEPENDENCIES) $(EXTRA_nl_neigh_list_DEPENDENCIES) @rm -f nl-neigh-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_neigh_list_OBJECTS) $(nl_neigh_list_LDADD) $(LIBS) nl-neightbl-list$(EXEEXT): $(nl_neightbl_list_OBJECTS) $(nl_neightbl_list_DEPENDENCIES) $(EXTRA_nl_neightbl_list_DEPENDENCIES) @rm -f nl-neightbl-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_neightbl_list_OBJECTS) $(nl_neightbl_list_LDADD) $(LIBS) nl-pktloc-lookup$(EXEEXT): $(nl_pktloc_lookup_OBJECTS) $(nl_pktloc_lookup_DEPENDENCIES) $(EXTRA_nl_pktloc_lookup_DEPENDENCIES) @rm -f nl-pktloc-lookup$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_pktloc_lookup_OBJECTS) $(nl_pktloc_lookup_LDADD) $(LIBS) nl-qdisc-add$(EXEEXT): $(nl_qdisc_add_OBJECTS) $(nl_qdisc_add_DEPENDENCIES) $(EXTRA_nl_qdisc_add_DEPENDENCIES) @rm -f nl-qdisc-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_qdisc_add_OBJECTS) $(nl_qdisc_add_LDADD) $(LIBS) nl-qdisc-delete$(EXEEXT): $(nl_qdisc_delete_OBJECTS) $(nl_qdisc_delete_DEPENDENCIES) $(EXTRA_nl_qdisc_delete_DEPENDENCIES) @rm -f nl-qdisc-delete$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_qdisc_delete_OBJECTS) $(nl_qdisc_delete_LDADD) $(LIBS) nl-qdisc-list$(EXEEXT): $(nl_qdisc_list_OBJECTS) $(nl_qdisc_list_DEPENDENCIES) $(EXTRA_nl_qdisc_list_DEPENDENCIES) @rm -f nl-qdisc-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_qdisc_list_OBJECTS) $(nl_qdisc_list_LDADD) $(LIBS) nl-route-add$(EXEEXT): $(nl_route_add_OBJECTS) $(nl_route_add_DEPENDENCIES) $(EXTRA_nl_route_add_DEPENDENCIES) @rm -f nl-route-add$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_route_add_OBJECTS) $(nl_route_add_LDADD) $(LIBS) nl-route-delete$(EXEEXT): $(nl_route_delete_OBJECTS) $(nl_route_delete_DEPENDENCIES) $(EXTRA_nl_route_delete_DEPENDENCIES) @rm -f nl-route-delete$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_route_delete_OBJECTS) $(nl_route_delete_LDADD) $(LIBS) nl-route-get$(EXEEXT): $(nl_route_get_OBJECTS) $(nl_route_get_DEPENDENCIES) $(EXTRA_nl_route_get_DEPENDENCIES) @rm -f nl-route-get$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_route_get_OBJECTS) $(nl_route_get_LDADD) $(LIBS) nl-route-list$(EXEEXT): $(nl_route_list_OBJECTS) $(nl_route_list_DEPENDENCIES) $(EXTRA_nl_route_list_DEPENDENCIES) @rm -f nl-route-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_route_list_OBJECTS) $(nl_route_list_LDADD) $(LIBS) nl-rule-list$(EXEEXT): $(nl_rule_list_OBJECTS) $(nl_rule_list_DEPENDENCIES) $(EXTRA_nl_rule_list_DEPENDENCIES) @rm -f nl-rule-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_rule_list_OBJECTS) $(nl_rule_list_LDADD) $(LIBS) nl-tctree-list$(EXEEXT): $(nl_tctree_list_OBJECTS) $(nl_tctree_list_DEPENDENCIES) $(EXTRA_nl_tctree_list_DEPENDENCIES) @rm -f nl-tctree-list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_tctree_list_OBJECTS) $(nl_tctree_list_LDADD) $(LIBS) nl-util-addr$(EXEEXT): $(nl_util_addr_OBJECTS) $(nl_util_addr_DEPENDENCIES) $(EXTRA_nl_util_addr_DEPENDENCIES) @rm -f nl-util-addr$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nl_util_addr_OBJECTS) $(nl_util_addr_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genl-ctrl-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idiag-socket-details.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-ct-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-ct-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-exp-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-exp-delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-exp-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-log.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nf-queue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-addr-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-addr-delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-addr-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-class-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-class-delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-class-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-classid-lookup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-cls-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-cls-delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-cls-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-fib-lookup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-link-enslave.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-link-ifindex2name.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-link-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-link-name2ifindex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-link-release.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-link-set.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-link-stats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-list-caches.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-list-sockets.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-neigh-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-neigh-delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-neigh-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-neightbl-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-pktloc-lookup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-qdisc-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-qdisc-delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-qdisc-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-route-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-route-delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-route-get.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-route-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-rule-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-tctree-list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl-util-addr.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstPROGRAMS clean-sbinPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-sbinPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstPROGRAMS clean-sbinPROGRAMS cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-sbinPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/src/nl-cls-add.c0000644000175000017500000001111213023014600012462 00000000000000/* * src/nl-cls-add.c Add classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2 of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #include #include #include #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nl-cls-add [OPTIONS]... classifier [CONFIGURATION]...\n" "\n" "OPTIONS\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help text.\n" " -v, --version Show versioning information.\n" " --update Update classifier if it exists.\n" " --update-only Only update classifier, never create it.\n" " -d, --dev=DEV Network device the classifier should be attached to.\n" " -i, --id=ID ID of new classifier (default: auto-generated)\n" " -p, --parent=ID ID of parent { root | ingress | class-ID }\n" " --proto=PROTO Protocol to match (default: all)\n" " --prio=PRIO Priority (default: 0)\n" " --mtu=SIZE Overwrite MTU (default: MTU of network device)\n" " --mpu=SIZE Minimum packet size on the link (default: 0).\n" " --overhead=SIZE Overhead in bytes per packet (default: 0).\n" " --linktype=TYPE Overwrite linktype (default: type of network device)\n" "\n" "CONFIGURATION\n" " -h, --help Show help text of classifier specific options.\n" "\n" "EXAMPLE\n" " $ nl-cls-add --dev=eth1 --parent=q_root basic --target c_www\n" "\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_cls *cls; struct rtnl_tc *tc; struct nl_cache *link_cache; struct nl_dump_params dp = { .dp_type = NL_DUMP_DETAILS, .dp_fd = stdout, }; struct nl_cli_tc_module *tm; struct rtnl_tc_ops *ops; int err, flags = NLM_F_CREATE | NLM_F_EXCL; char *kind, *id = NULL; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); cls = nl_cli_cls_alloc(); tc = (struct rtnl_tc *) cls; for (;;) { int c, optidx = 0; enum { ARG_UPDATE = 257, ARG_UPDATE_ONLY = 258, ARG_MTU, ARG_MPU, ARG_OVERHEAD, ARG_LINKTYPE, ARG_PROTO, ARG_PRIO, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "proto", 1, 0, ARG_PROTO }, { "prio", 1, 0, ARG_PRIO }, { "update", 0, 0, ARG_UPDATE }, { "update-only", 0, 0, ARG_UPDATE_ONLY }, { "mtu", 1, 0, ARG_MTU }, { "mpu", 1, 0, ARG_MPU }, { "overhead", 1, 0, ARG_OVERHEAD }, { "linktype", 1, 0, ARG_LINKTYPE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "+qhvd:p:i:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': id = strdup(optarg); break; case ARG_UPDATE: flags = NLM_F_CREATE; break; case ARG_UPDATE_ONLY: flags = 0; break; case ARG_MTU: nl_cli_tc_parse_mtu(tc, optarg); break; case ARG_MPU: nl_cli_tc_parse_mpu(tc, optarg); break; case ARG_OVERHEAD: nl_cli_tc_parse_overhead(tc, optarg); break; case ARG_LINKTYPE: nl_cli_tc_parse_linktype(tc, optarg); break; case ARG_PROTO: nl_cli_cls_parse_proto(cls, optarg); break; case ARG_PRIO: rtnl_cls_set_prio(cls, nl_cli_parse_u32(optarg)); break; } } if (optind >= argc) print_usage(); if (!rtnl_tc_get_ifindex(tc)) nl_cli_fatal(EINVAL, "You must specify a network device (--dev=XXX)"); if (!rtnl_tc_get_parent(tc)) nl_cli_fatal(EINVAL, "You must specify a parent (--parent=XXX)"); if (id) { nl_cli_tc_parse_handle(tc, id, 1); free(id); } kind = argv[optind++]; rtnl_tc_set_kind(tc, kind); if (!(ops = rtnl_tc_get_ops(tc))) nl_cli_fatal(ENOENT, "Unknown classifier \"%s\".", kind); if (!(tm = nl_cli_tc_lookup(ops))) nl_cli_fatal(ENOTSUP, "Classifier type \"%s\" not supported.", kind); tm->tm_parse_argv(tc, argc, argv); if (!quiet) { printf("Adding "); nl_object_dump(OBJ_CAST(cls), &dp); } if ((err = rtnl_cls_add(sock, cls, flags)) < 0) nl_cli_fatal(EINVAL, "Unable to add classifier: %s", nl_geterror(err)); return 0; } libnl-3.2.29/src/nl-addr-add.c0000644000175000017500000000670113023014600012623 00000000000000/* * src/nl-addr-add.c Add addresses * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2 of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nl-addr-add [OPTION]... [ADDRESS]\n" "\n" "Options\n" " --replace Replace the address if it exists.\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help.\n" " -v, --version Show versioning information.\n" "\n" "Address Options\n" " -a, --local=ADDR Address to be considered local.\n" " -d, --dev=DEV Device the address should be assigned to.\n" " --family=FAMILY Address family (normally autodetected).\n" " --broadcast=ADDR Broadcast address of network (IPv4).\n" " --peer=ADDR Peer address (IPv4).\n" " --label=STRING Additional address label (IPv4).\n" " --scope=SCOPE Scope of local address (IPv4).\n" " --preferred=TIME Preferred lifetime (IPv6).\n" " --valid=TIME Valid lifetime (IPv6).\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_addr *addr; struct nl_cache *link_cache; struct nl_dump_params dp = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err, nlflags = NLM_F_CREATE; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); addr = nl_cli_addr_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_LABEL = 258, ARG_PEER, ARG_SCOPE, ARG_BROADCAST, ARG_REPLACE, ARG_PREFERRED, ARG_VALID, }; static struct option long_opts[] = { { "replace", 0, 0, ARG_REPLACE }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "local", 1, 0, 'a' }, { "dev", 1, 0, 'd' }, { "family", 1, 0, ARG_FAMILY }, { "label", 1, 0, ARG_LABEL }, { "peer", 1, 0, ARG_PEER }, { "scope", 1, 0, ARG_SCOPE }, { "broadcast", 1, 0, ARG_BROADCAST }, { "preferred", 1, 0, ARG_PREFERRED }, { "valid", 1, 0, ARG_VALID }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "qhva:d:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case ARG_REPLACE: nlflags |= NLM_F_REPLACE; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'a': nl_cli_addr_parse_local(addr, optarg); break; case 'd': nl_cli_addr_parse_dev(addr, link_cache, optarg); break; case ARG_FAMILY: nl_cli_addr_parse_family(addr, optarg); break; case ARG_LABEL: nl_cli_addr_parse_label(addr, optarg); break; case ARG_PEER: nl_cli_addr_parse_peer(addr, optarg); break; case ARG_SCOPE: nl_cli_addr_parse_scope(addr, optarg); break; case ARG_BROADCAST: nl_cli_addr_parse_broadcast(addr, optarg); break; case ARG_PREFERRED: nl_cli_addr_parse_preferred(addr, optarg); break; case ARG_VALID: nl_cli_addr_parse_valid(addr, optarg); break; } } if ((err = rtnl_addr_add(sock, addr, nlflags)) < 0) nl_cli_fatal(err, "Unable to add address: %s", nl_geterror(err)); if (!quiet) { printf("Added "); nl_object_dump(OBJ_CAST(addr), &dp); } return 0; } libnl-3.2.29/src/nl-link-enslave.c0000644000175000017500000000227313023014600013553 00000000000000/* * src/nl-link-enslave.c Enslave a link * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2011 Thomas Graf */ #include #include #include int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *link_cache; struct rtnl_link *master, *slave; int err; if (argc < 3) { fprintf(stderr, "Usage: nl-link-enslave master slave\n"); return 1; } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); if (!(master = rtnl_link_get_by_name(link_cache, argv[1]))) { fprintf(stderr, "Unknown link: %s\n", argv[1]); return 1; } if (!(slave = rtnl_link_get_by_name(link_cache, argv[2]))) { fprintf(stderr, "Unknown link: %s\n", argv[2]); return 1; } if ((err = rtnl_link_bond_enslave(sock, master, slave)) < 0) { fprintf(stderr, "Unable to enslave %s to %s: %s\n", argv[2], argv[1], nl_geterror(err)); return 1; } return 0; } libnl-3.2.29/src/nl-neightbl-list.c0000644000175000017500000000301413023014600013722 00000000000000/* * src/nl-neightbl-list.c Dump neighbour tables * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include static void print_usage(void) { printf( "Usage: nl-neightbl-list [OPTION]...\n" "\n" "Options\n" " -f, --format=TYPE Output format { brief | details | stats }\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *neightbl_cache; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); nl_cli_link_alloc_cache(sock); neightbl_cache = nl_cli_alloc_cache(sock, "neighbour table", rtnl_neightbl_alloc_cache); for (;;) { int c, optidx = 0; static struct option long_opts[] = { { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "f:hv", long_opts, &optidx); if (c == -1) break; switch (c) { case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; } } nl_cache_dump(neightbl_cache, ¶ms); return 0; } libnl-3.2.29/src/nl-link-ifindex2name.c0000644000175000017500000000176613023014600014475 00000000000000/* * src/nl-link-ifindex2name.c Transform a interface index to its name * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include static void print_usage(void) { printf("Usage: nl-link-ifindex2name \n"); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *link_cache; char name[IFNAMSIZ]; uint32_t ifindex; if (argc < 2) print_usage(); sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); ifindex = nl_cli_parse_u32(argv[1]); if (!rtnl_link_i2name(link_cache, ifindex, name, sizeof(name))) nl_cli_fatal(ENOENT, "Interface index %d does not exist", ifindex); printf("%s\n", name); return 0; } libnl-3.2.29/src/lib/0000755000175000017500000000000013031473756011256 500000000000000libnl-3.2.29/src/lib/Makefile.am0000644000175000017500000000334413023014600013212 00000000000000# -*- Makefile -*- AM_CPPFLAGS = \ -I${top_srcdir}/include/linux-private \ -I${top_srcdir}/include \ -I${top_builddir}/include \ -D_GNU_SOURCE \ -DPKGLIBDIR=\"$(pkglibdir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" AM_CFLAGS = -Wall AM_LDFLAGS = \ -rdynamic \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) NL_LIBADD = \ -L${top_builddir}/lib \ -ldl #nobase_pkglib_LTLIBRARIES = cls/basic.la cls/ematch/cmp.la #cls_basic_la_LDFLAGS = -module -version-info 2:0:0 #cls_ematch_cmp_la_LDFLAGS = -module -version-info 2:0:0 #cls/ematch_grammar.c: cls/ematch_grammar.l # $(LEX) --header-file=cls/ematch_grammar.h $(LFLAGS) -o $@ $^ #cls/ematch_syntax.c: cls/ematch_syntax.y # $(YACC) -d $(YFLAGS) -o $@ $^ #cls/pktloc_grammar.c: cls/pktloc_grammar.l # $(LEX) --header-file=cls/pktloc_grammar.h $(LFLAGS) -o $@ $^ #cls/pktloc_syntax.c: cls/pktloc_syntax.y # $(YACC) -d $(YFLAGS) -o $@ $^ #CLEANFILES = \ # cls/ematch_grammar.c cls/ematch_grammar.h \ # cls/ematch_syntax.c cls/ematch_syntax.h \ # cls/pktloc_grammar.c cls/pktloc_grammar.h \ # cls/pktloc_syntax.c cls/pktloc_syntax.h lib_LTLIBRARIES = \ libnl-cli-3.la libnl_cli_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-cli-3.sym libnl_cli_3_la_DEPENDENCIES = \ $(top_srcdir)/libnl-cli-3.sym libnl_cli_3_la_LIBADD = ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la ${NL_LIBADD} libnl_cli_3_la_SOURCES = \ utils.c addr.c ct.c link.c neigh.c rule.c route.c \ tc.c qdisc.c class.c cls.c exp.c # cls/ematch_syntax.c cls/ematch_grammar.c cls/ematch.c # cls/pktloc_syntax.c cls/pktloc_grammar.c cls/utils.c libnl-3.2.29/src/lib/neigh.c0000644000175000017500000000360113023014600012410 00000000000000/* * src/lib/neigh.c CLI Neighbour Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ /** * @ingroup cli * @defgroup cli_neigh Neighbour * * @{ */ #include #include struct rtnl_neigh *nl_cli_neigh_alloc(void) { struct rtnl_neigh *neigh; neigh = rtnl_neigh_alloc(); if (!neigh) nl_cli_fatal(ENOMEM, "Unable to allocate neighbour object"); return neigh; } void nl_cli_neigh_parse_dst(struct rtnl_neigh *neigh, char *arg) { struct nl_addr *a; int err; a = nl_cli_addr_parse(arg, rtnl_neigh_get_family(neigh)); if ((err = rtnl_neigh_set_dst(neigh, a)) < 0) nl_cli_fatal(err, "Unable to set local address: %s", nl_geterror(err)); nl_addr_put(a); } void nl_cli_neigh_parse_lladdr(struct rtnl_neigh *neigh, char *arg) { struct nl_addr *a; a = nl_cli_addr_parse(arg, AF_UNSPEC); rtnl_neigh_set_lladdr(neigh, a); nl_addr_put(a); } void nl_cli_neigh_parse_dev(struct rtnl_neigh *neigh, struct nl_cache *link_cache, char *arg) { int ival; if (!(ival = rtnl_link_name2i(link_cache, arg))) nl_cli_fatal(ENOENT, "Link \"%s\" does not exist", arg); rtnl_neigh_set_ifindex(neigh, ival); } void nl_cli_neigh_parse_family(struct rtnl_neigh *neigh, char *arg) { int family; if ((family = nl_str2af(arg)) == AF_UNSPEC) nl_cli_fatal(EINVAL, "Unable to translate address family \"%s\"", arg); rtnl_neigh_set_family(neigh, family); } void nl_cli_neigh_parse_state(struct rtnl_neigh *neigh, char *arg) { int state; if ((state = rtnl_neigh_str2state(arg)) < 0) nl_cli_fatal(state, "Unable to translate state \"%s\": %s", arg, state); rtnl_neigh_set_state(neigh, state); } /** @} */ libnl-3.2.29/src/lib/ct.c0000644000175000017500000001011513023014600011722 00000000000000/* * src/lib/ct.c CLI Conntrack Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ /** * @ingroup cli * @defgroup cli_ct Connection Tracking * * @{ */ #include #include struct nfnl_ct *nl_cli_ct_alloc(void) { struct nfnl_ct *ct; ct = nfnl_ct_alloc(); if (!ct) nl_cli_fatal(ENOMEM, "Unable to allocate conntrack object"); return ct; } struct nl_cache *nl_cli_ct_alloc_cache(struct nl_sock *sk) { return nl_cli_alloc_cache(sk, "conntrack", nfnl_ct_alloc_cache); } void nl_cli_ct_parse_family(struct nfnl_ct *ct, char *arg) { int family; if ((family = nl_str2af(arg)) == AF_UNSPEC) nl_cli_fatal(EINVAL, "Unable to nl_cli_ct_parse family \"%s\": %s", arg, nl_geterror(NLE_INVAL)); nfnl_ct_set_family(ct, family); } void nl_cli_ct_parse_protocol(struct nfnl_ct *ct, char *arg) { int proto; if ((proto = nl_str2ip_proto(arg)) < 0) nl_cli_fatal(proto, "Unable to nl_cli_ct_parse protocol \"%s\": %s", arg, nl_geterror(proto)); nfnl_ct_set_proto(ct, proto); } void nl_cli_ct_parse_mark(struct nfnl_ct *ct, char *arg) { uint32_t mark = nl_cli_parse_u32(arg); nfnl_ct_set_mark(ct, mark); } void nl_cli_ct_parse_timeout(struct nfnl_ct *ct, char *arg) { uint32_t timeout = nl_cli_parse_u32(arg); nfnl_ct_set_timeout(ct, timeout); } void nl_cli_ct_parse_id(struct nfnl_ct *ct, char *arg) { uint32_t id = nl_cli_parse_u32(arg); nfnl_ct_set_id(ct, id); } void nl_cli_ct_parse_use(struct nfnl_ct *ct, char *arg) { uint32_t use = nl_cli_parse_u32(arg); nfnl_ct_set_use(ct, use); } void nl_cli_ct_parse_src(struct nfnl_ct *ct, int reply, char *arg) { int err; struct nl_addr *a = nl_cli_addr_parse(arg, nfnl_ct_get_family(ct)); if ((err = nfnl_ct_set_src(ct, reply, a)) < 0) nl_cli_fatal(err, "Unable to set source address: %s", nl_geterror(err)); } void nl_cli_ct_parse_dst(struct nfnl_ct *ct, int reply, char *arg) { int err; struct nl_addr *a = nl_cli_addr_parse(arg, nfnl_ct_get_family(ct)); if ((err = nfnl_ct_set_dst(ct, reply, a)) < 0) nl_cli_fatal(err, "Unable to set destination address: %s", nl_geterror(err)); } void nl_cli_ct_parse_src_port(struct nfnl_ct *ct, int reply, char *arg) { uint32_t port = nl_cli_parse_u32(arg); nfnl_ct_set_src_port(ct, reply, port); } void nl_cli_ct_parse_dst_port(struct nfnl_ct *ct, int reply, char *arg) { uint32_t port = nl_cli_parse_u32(arg); nfnl_ct_set_dst_port(ct, reply, port); } void nl_cli_ct_parse_tcp_state(struct nfnl_ct *ct, char *arg) { int state; if ((state = nfnl_ct_str2tcp_state(arg)) < 0) nl_cli_fatal(state, "Unable to nl_cli_ct_parse tcp state \"%s\": %s", arg, nl_geterror(state)); nfnl_ct_set_tcp_state(ct, state); } void nl_cli_ct_parse_status(struct nfnl_ct *ct, char *arg) { int status; if ((status = nfnl_ct_str2status(arg)) < 0) nl_cli_fatal(status, "Unable to nl_cli_ct_parse flags \"%s\": %s", arg, nl_geterror(status)); nfnl_ct_set_status(ct, status); } void nl_cli_ct_parse_zone(struct nfnl_ct *ct, char *arg) { uint32_t zone = nl_cli_parse_u32(arg); nfnl_ct_set_zone(ct, zone); } #if 0 } else if (arg_match("origicmpid")) { if (argc > ++idx) nfnl_ct_set_icmp_id(ct, 0, strtoul(argv[idx++], NULL, 0)); } else if (arg_match("origicmptype")) { if (argc > ++idx) nfnl_ct_set_icmp_type(ct, 0, strtoul(argv[idx++], NULL, 0)); } else if (arg_match("origicmpcode")) { if (argc > ++idx) nfnl_ct_set_icmp_code(ct, 0, strtoul(argv[idx++], NULL, 0)); } else if (arg_match("replyicmpid")) { if (argc > ++idx) nfnl_ct_set_icmp_id(ct, 1, strtoul(argv[idx++], NULL, 0)); } else if (arg_match("replyicmptype")) { if (argc > ++idx) nfnl_ct_set_icmp_type(ct, 1, strtoul(argv[idx++], NULL, 0)); } else if (arg_match("replyicmpcode")) { if (argc > ++idx) nfnl_ct_set_icmp_code(ct, 1, strtoul(argv[idx++], NULL, 0)); } #endif /** @} */ libnl-3.2.29/src/lib/rule.c0000644000175000017500000000215313023014600012266 00000000000000/* * src/lib/rule.c CLI Routing Rule Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ /** * @ingroup cli * @defgroup cli_rule Routing Rules * * @{ */ #include #include struct rtnl_rule *nl_cli_rule_alloc(void) { struct rtnl_rule *rule; rule = rtnl_rule_alloc(); if (!rule) nl_cli_fatal(ENOMEM, "Unable to allocate rule object"); return rule; } struct nl_cache *nl_cli_rule_alloc_cache(struct nl_sock *sk) { struct nl_cache *cache; int err; if ((err = rtnl_rule_alloc_cache(sk, AF_UNSPEC, &cache)) < 0) nl_cli_fatal(err, "Unable to allocate routing rule cache: %s\n", nl_geterror(err)); nl_cache_mngt_provide(cache); return cache; } void nl_cli_rule_parse_family(struct rtnl_rule *rule, char *arg) { int family; if ((family = nl_str2af(arg)) != AF_UNSPEC) rtnl_rule_set_family(rule, family); } /** @} */ libnl-3.2.29/src/lib/link.c0000644000175000017500000000500013023014600012246 00000000000000/* * src/lib/link.c CLI Link Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2010 Thomas Graf */ /** * @ingroup cli * @defgroup cli_link Links * * @{ */ #include #include #include struct rtnl_link *nl_cli_link_alloc(void) { struct rtnl_link *link; link = rtnl_link_alloc(); if (!link) nl_cli_fatal(ENOMEM, "Unable to allocate link object"); return link; } struct nl_cache *nl_cli_link_alloc_cache_family_flags(struct nl_sock *sock, int family, unsigned int flags) { struct nl_cache *cache; int err; if ((err = rtnl_link_alloc_cache_flags(sock, family, &cache, flags)) < 0) nl_cli_fatal(err, "Unable to allocate link cache: %s", nl_geterror(err)); nl_cache_mngt_provide(cache); return cache; } struct nl_cache *nl_cli_link_alloc_cache_family(struct nl_sock *sock, int family) { return nl_cli_link_alloc_cache_family_flags(sock, family, 0); } struct nl_cache *nl_cli_link_alloc_cache(struct nl_sock *sock) { return nl_cli_link_alloc_cache_family(sock, AF_UNSPEC); } struct nl_cache *nl_cli_link_alloc_cache_flags(struct nl_sock *sock, unsigned int flags) { return nl_cli_link_alloc_cache_family_flags(sock, AF_UNSPEC, flags); } void nl_cli_link_parse_family(struct rtnl_link *link, char *arg) { int family; if ((family = nl_str2af(arg)) < 0) nl_cli_fatal(EINVAL, "Unable to translate address family \"%s\"", arg); rtnl_link_set_family(link, family); } void nl_cli_link_parse_name(struct rtnl_link *link, char *arg) { rtnl_link_set_name(link, arg); } void nl_cli_link_parse_mtu(struct rtnl_link *link, char *arg) { uint32_t mtu = nl_cli_parse_u32(arg); rtnl_link_set_mtu(link, mtu); } void nl_cli_link_parse_ifindex(struct rtnl_link *link, char *arg) { uint32_t index = nl_cli_parse_u32(arg); rtnl_link_set_ifindex(link, index); } void nl_cli_link_parse_txqlen(struct rtnl_link *link, char *arg) { uint32_t qlen = nl_cli_parse_u32(arg); rtnl_link_set_txqlen(link, qlen); } void nl_cli_link_parse_weight(struct rtnl_link *link, char *arg) { } void nl_cli_link_parse_ifalias(struct rtnl_link *link, char *arg) { if (strlen(arg) > IFALIASZ) nl_cli_fatal(ERANGE, "Link ifalias too big, must not exceed %u in length.", IFALIASZ); rtnl_link_set_ifalias(link, arg); } /** @} */ libnl-3.2.29/src/lib/utils.c0000644000175000017500000001177713023014600012473 00000000000000/* * src/utils.c Utilities * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ /** * @defgroup cli Command Line Interface API * * @{ * * These modules provide an interface for text based applications. The * functions provided are wrappers for their libnl equivalent with * added error handling. The functions check for allocation failures, * invalid input, and unknown types and will print error messages * accordingly via nl_cli_fatal(). */ #include #include /** * Parse a text based 32 bit unsigned integer argument * @arg arg Integer in text form. * * Tries to convert the number provided in arg to a uint32_t. Will call * nl_cli_fatal() if the conversion fails. * * @return 32bit unsigned integer. */ uint32_t nl_cli_parse_u32(const char *arg) { unsigned long lval; char *endptr; lval = strtoul(arg, &endptr, 0); if (endptr == arg || lval == ULONG_MAX) nl_cli_fatal(EINVAL, "Unable to parse \"%s\", not a number.", arg); return (uint32_t) lval; } void nl_cli_print_version(void) { printf("libnl tools version %s\n", LIBNL_VERSION); printf( "Copyright (C) 2003-2010 Thomas Graf \n" "\n" "This program comes with ABSOLUTELY NO WARRANTY. This is free \n" "software, and you are welcome to redistribute it under certain\n" "conditions. See the GNU General Public License for details.\n" ); exit(0); } /** * Print error message and quit application * @arg err Error code. * @arg fmt Error message. * * Prints the formatted error message to stderr and quits the application * using the provided error code. */ void nl_cli_fatal(int err, const char *fmt, ...) { va_list ap; fprintf(stderr, "Error: "); if (fmt) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); } else { char *buf; locale_t loc = newlocale(LC_MESSAGES_MASK, "", (locale_t)0); if (loc == (locale_t)0) { if (errno == ENOENT) loc = newlocale(LC_MESSAGES_MASK, "POSIX", (locale_t)0); if (loc == (locale_t)0) buf = "newlocale() failed"; } if (loc != (locale_t)0) buf = strerror_l(err, loc); fprintf(stderr, "%s\n", buf); if (loc != (locale_t)0) freelocale(loc); } exit(abs(err)); } int nl_cli_connect(struct nl_sock *sk, int protocol) { int err; if ((err = nl_connect(sk, protocol)) < 0) nl_cli_fatal(err, "Unable to connect netlink socket: %s", nl_geterror(err)); return err; } struct nl_sock *nl_cli_alloc_socket(void) { struct nl_sock *sock; if (!(sock = nl_socket_alloc())) nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket"); return sock; } struct nl_addr *nl_cli_addr_parse(const char *str, int family) { struct nl_addr *addr; int err; if ((err = nl_addr_parse(str, family, &addr)) < 0) nl_cli_fatal(err, "Unable to parse address \"%s\": %s", str, nl_geterror(err)); return addr; } int nl_cli_parse_dumptype(const char *str) { if (!strcasecmp(str, "brief")) return NL_DUMP_LINE; else if (!strcasecmp(str, "details") || !strcasecmp(str, "detailed")) return NL_DUMP_DETAILS; else if (!strcasecmp(str, "stats")) return NL_DUMP_STATS; else nl_cli_fatal(EINVAL, "Invalid dump type \"%s\".\n", str); return 0; } int nl_cli_confirm(struct nl_object *obj, struct nl_dump_params *params, int default_yes) { nl_object_dump(obj, params); for (;;) { char buf[32] = { 0 }; int answer; printf("Delete? (%c/%c) ", default_yes ? 'Y' : 'y', default_yes ? 'n' : 'N'); if (!fgets(buf, sizeof(buf), stdin)) { fprintf(stderr, "Error while reading\n."); continue; } switch ((answer = tolower(buf[0]))) { case '\n': answer = default_yes ? 'y' : 'n'; case 'y': case 'n': return answer == 'y'; } fprintf(stderr, "Invalid input, try again.\n"); } return 0; } struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name, int (*ac)(struct nl_sock *, struct nl_cache **)) { struct nl_cache *cache; int err; if ((err = ac(sock, &cache)) < 0) nl_cli_fatal(err, "Unable to allocate %s cache: %s", name, nl_geterror(err)); nl_cache_mngt_provide(cache); return cache; } struct nl_cache *nl_cli_alloc_cache_flags(struct nl_sock *sock, const char *name, unsigned int flags, int (*ac)(struct nl_sock *, struct nl_cache **, unsigned int)) { struct nl_cache *cache; int err; if ((err = ac(sock, &cache, flags)) < 0) nl_cli_fatal(err, "Unable to allocate %s cache: %s", name, nl_geterror(err)); nl_cache_mngt_provide(cache); return cache; } void nl_cli_load_module(const char *prefix, const char *name) { char path[FILENAME_MAX+1]; void *handle; snprintf(path, sizeof(path), "%s/%s/%s.so", PKGLIBDIR, prefix, name); if (!(handle = dlopen(path, RTLD_NOW))) nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n", path, dlerror()); } /** @} */ libnl-3.2.29/src/lib/addr.c0000644000175000017500000000565013023014600012236 00000000000000/* * src/lib/addr.c Address Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ /** * @ingroup cli * @defgroup cli_addr Addresses * * @{ */ #include #include struct rtnl_addr *nl_cli_addr_alloc(void) { struct rtnl_addr *addr; addr = rtnl_addr_alloc(); if (!addr) nl_cli_fatal(ENOMEM, "Unable to allocate address object"); return addr; } void nl_cli_addr_parse_family(struct rtnl_addr *addr, char *arg) { int family; if ((family = nl_str2af(arg)) != AF_UNSPEC) rtnl_addr_set_family(addr, family); } void nl_cli_addr_parse_local(struct rtnl_addr *addr, char *arg) { struct nl_addr *a; int err; a = nl_cli_addr_parse(arg, rtnl_addr_get_family(addr)); if ((err = rtnl_addr_set_local(addr, a)) < 0) nl_cli_fatal(err, "Unable to set local address: %s", nl_geterror(err)); nl_addr_put(a); } void nl_cli_addr_parse_dev(struct rtnl_addr *addr, struct nl_cache *link_cache, char *arg) { int ival; if (!(ival = rtnl_link_name2i(link_cache, arg))) nl_cli_fatal(ENOENT, "Link \"%s\" does not exist", arg); rtnl_addr_set_ifindex(addr, ival); } void nl_cli_addr_parse_label(struct rtnl_addr *addr, char *arg) { int err; if ((err = rtnl_addr_set_label(addr, arg)) < 0) nl_cli_fatal(err, "Unable to set address label: %s", nl_geterror(err)); } void nl_cli_addr_parse_peer(struct rtnl_addr *addr, char *arg) { struct nl_addr *a; int err; a = nl_cli_addr_parse(arg, rtnl_addr_get_family(addr)); if ((err = rtnl_addr_set_peer(addr, a)) < 0) nl_cli_fatal(err, "Unable to set peer address: %s", nl_geterror(err)); nl_addr_put(a); } void nl_cli_addr_parse_scope(struct rtnl_addr *addr, char *arg) { int ival; if ((ival = rtnl_str2scope(arg)) < 0) nl_cli_fatal(EINVAL, "Unknown address scope \"%s\"", arg); rtnl_addr_set_scope(addr, ival); } void nl_cli_addr_parse_broadcast(struct rtnl_addr *addr, char *arg) { struct nl_addr *a; int err; a = nl_cli_addr_parse(arg, rtnl_addr_get_family(addr)); if ((err = rtnl_addr_set_broadcast(addr, a)) < 0) nl_cli_fatal(err, "Unable to set broadcast address: %s", nl_geterror(err)); nl_addr_put(a); } static uint32_t parse_lifetime(const char *arg) { uint64_t msecs; int err; if (!strcasecmp(arg, "forever")) return 0xFFFFFFFFU; if ((err = nl_str2msec(arg, &msecs)) < 0) nl_cli_fatal(err, "Unable to parse time string \"%s\": %s", arg, nl_geterror(err)); return (msecs / 1000); } void nl_cli_addr_parse_preferred(struct rtnl_addr *addr, char *arg) { rtnl_addr_set_preferred_lifetime(addr, parse_lifetime(arg)); } void nl_cli_addr_parse_valid(struct rtnl_addr *addr, char *arg) { rtnl_addr_set_valid_lifetime(addr, parse_lifetime(arg)); } /** @} */ libnl-3.2.29/src/lib/cls.c0000644000175000017500000000301213023014600012073 00000000000000/* * src/lib/cls.c CLI Classifier Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ /** * @ingroup cli * @defgroup cli_cls Classifiers * @{ */ #include #include #include struct rtnl_cls *nl_cli_cls_alloc(void) { struct rtnl_cls *cls; if (!(cls = rtnl_cls_alloc())) nl_cli_fatal(ENOMEM, "Unable to allocate classifier object"); return cls; } struct nl_cache *nl_cli_cls_alloc_cache(struct nl_sock *sock, int ifindex, uint32_t parent) { struct nl_cache *cache; int err; if ((err = rtnl_cls_alloc_cache(sock, ifindex, parent, &cache)) < 0) nl_cli_fatal(err, "Unable to allocate classifier cache: %s", nl_geterror(err)); return cache; } void nl_cli_cls_parse_proto(struct rtnl_cls *cls, char *arg) { int proto; if ((proto = nl_str2ether_proto(arg)) < 0) nl_cli_fatal(proto, "Unknown protocol \"%s\".", arg); rtnl_cls_set_protocol(cls, proto); } struct rtnl_ematch_tree *nl_cli_cls_parse_ematch(struct rtnl_cls *cls, char *arg) { struct rtnl_ematch_tree *tree; char *errstr = NULL; int err; if ((err = rtnl_ematch_parse_expr(arg, &errstr, &tree)) < 0) nl_cli_fatal(err, "Unable to parse ematch expression: %s", errstr); if (errstr) free(errstr); return tree; } /** @} */ libnl-3.2.29/src/lib/route.c0000644000175000017500000001401313023014600012453 00000000000000/* * src/lib/route.c CLI Route Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf */ /** * @ingroup cli * @defgroup cli_route Routing * * @{ */ #include #include struct rtnl_route *nl_cli_route_alloc(void) { struct rtnl_route *route; route = rtnl_route_alloc(); if (!route) nl_cli_fatal(ENOMEM, "Unable to allocate route object"); return route; } struct nl_cache *nl_cli_route_alloc_cache(struct nl_sock *sk, int flags) { struct nl_cache *cache; int err; if ((err = rtnl_route_alloc_cache(sk, AF_UNSPEC, flags, &cache)) < 0) nl_cli_fatal(err, "Unable to allocate route cache: %s\n", nl_geterror(err)); nl_cache_mngt_provide(cache); return cache; } void nl_cli_route_parse_family(struct rtnl_route *route, char *arg) { int family; if ((family = nl_str2af(arg)) != AF_UNSPEC) rtnl_route_set_family(route, family); } void nl_cli_route_parse_dst(struct rtnl_route *route, char *arg) { struct nl_addr *addr; int err; addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route)); if ((err = rtnl_route_set_dst(route, addr)) < 0) nl_cli_fatal(err, "Unable to set destination address: %s", nl_geterror(err)); nl_addr_put(addr); } void nl_cli_route_parse_src(struct rtnl_route *route, char *arg) { struct nl_addr *addr; int err; addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route)); if ((err = rtnl_route_set_src(route, addr)) < 0) nl_cli_fatal(err, "Unable to set source address: %s", nl_geterror(err)); nl_addr_put(addr); } void nl_cli_route_parse_pref_src(struct rtnl_route *route, char *arg) { struct nl_addr *addr; int err; addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route)); if ((err = rtnl_route_set_pref_src(route, addr)) < 0) nl_cli_fatal(err, "Unable to set preferred source address: %s", nl_geterror(err)); nl_addr_put(addr); } void nl_cli_route_parse_metric(struct rtnl_route *route, char *subopts) { /* strict equal order to RTAX_* */ static char *const tokens[] = { "unspec", "lock", "mtu", "window", "rtt", "rttvar", "sstresh", "cwnd", "advmss", "reordering", "hoplimit", "initcwnd", "features", NULL, }; unsigned long lval; char *arg, *endptr; while (*subopts != '\0') { int ret = getsubopt(&subopts, tokens, &arg); if (ret == -1) nl_cli_fatal(EINVAL, "Unknown metric token \"%s\"", arg); if (ret == 0) nl_cli_fatal(EINVAL, "Invalid metric \"%s\"", tokens[ret]); if (arg == NULL) nl_cli_fatal(EINVAL, "Metric \"%s\", no value given", tokens[ret]); lval = strtoul(arg, &endptr, 0); if (endptr == arg) nl_cli_fatal(EINVAL, "Metric \"%s\", value not numeric", tokens[ret]); if ((ret = rtnl_route_set_metric(route, ret, lval)) < 0) nl_cli_fatal(ret, "Unable to set metric: %s", nl_geterror(ret)); } } void nl_cli_route_parse_nexthop(struct rtnl_route *route, char *subopts, struct nl_cache *link_cache) { enum { NH_DEV, NH_VIA, NH_WEIGHT, }; static char *const tokens[] = { "dev", "via", "weight", NULL, }; struct rtnl_nexthop *nh; unsigned long lval; struct nl_addr *addr; int ival; char *arg, *endptr; if (!(nh = rtnl_route_nh_alloc())) nl_cli_fatal(ENOMEM, "Out of memory"); while (*subopts != '\0') { int ret = getsubopt(&subopts, tokens, &arg); if (ret == -1) nl_cli_fatal(EINVAL, "Unknown nexthop token \"%s\"", arg); if (arg == NULL) nl_cli_fatal(EINVAL, "Missing argument to option \"%s\"\n", tokens[ret]); switch (ret) { case NH_DEV: if (!(ival = rtnl_link_name2i(link_cache, arg))) nl_cli_fatal(ENOENT,"Link \"%s\" does not exist", arg); rtnl_route_nh_set_ifindex(nh, ival); break; case NH_VIA: addr = nl_cli_addr_parse(arg,rtnl_route_get_family(route)); rtnl_route_nh_set_gateway(nh, addr); nl_addr_put(addr); break; case NH_WEIGHT: lval = strtoul(arg, &endptr, 0); if (endptr == arg) nl_cli_fatal(EINVAL, "Invalid weight \"%s\", not numeric", arg); rtnl_route_nh_set_weight(nh, lval); break; } } rtnl_route_add_nexthop(route, nh); } void nl_cli_route_parse_table(struct rtnl_route *route, char *arg) { unsigned long lval; char *endptr; int table; lval = strtoul(arg, &endptr, 0); if (endptr == arg) { if ((table = rtnl_route_str2table(arg)) < 0) nl_cli_fatal(EINVAL, "Unknown table name \"%s\"", arg); } else { table = lval; } rtnl_route_set_table(route, table); } void nl_cli_route_parse_prio(struct rtnl_route *route, char *arg) { unsigned long lval; char *endptr; lval = strtoul(arg, &endptr, 0); if (endptr == arg) nl_cli_fatal(EINVAL, "Invalid priority value, not numeric"); rtnl_route_set_priority(route, lval); } void nl_cli_route_parse_scope(struct rtnl_route *route, char *arg) { int ival; if ((ival = rtnl_str2scope(arg)) < 0) nl_cli_fatal(EINVAL, "Unknown routing scope \"%s\"", arg); rtnl_route_set_scope(route, ival); } void nl_cli_route_parse_protocol(struct rtnl_route *route, char *arg) { unsigned long lval; char *endptr; int proto; lval = strtoul(arg, &endptr, 0); if (endptr == arg) { if ((proto = rtnl_route_str2proto(arg)) < 0) nl_cli_fatal(EINVAL, "Unknown routing protocol name \"%s\"", arg); } else { proto = lval; } rtnl_route_set_protocol(route, proto); } void nl_cli_route_parse_type(struct rtnl_route *route, char *arg) { int ival; if ((ival = nl_str2rtntype(arg)) < 0) nl_cli_fatal(EINVAL, "Unknown routing type \"%s\"", arg); if ((ival = rtnl_route_set_type(route, ival)) < 0) nl_cli_fatal(ival, "Unable to set routing type: %s", nl_geterror(ival)); } void nl_cli_route_parse_iif(struct rtnl_route *route, char *arg, struct nl_cache *link_cache) { int ival; if (!(ival = rtnl_link_name2i(link_cache, arg))) nl_cli_fatal(ENOENT, "Link \"%s\" does not exist", arg); rtnl_route_set_iif(route, ival); } /** @} */ libnl-3.2.29/src/lib/Makefile.in0000644000175000017500000005527113031473644013251 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = am_libnl_cli_3_la_OBJECTS = utils.lo addr.lo ct.lo link.lo neigh.lo \ rule.lo route.lo tc.lo qdisc.lo class.lo cls.lo exp.lo libnl_cli_3_la_OBJECTS = $(am_libnl_cli_3_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libnl_cli_3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libnl_cli_3_la_LDFLAGS) $(LDFLAGS) -o \ $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/lib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libnl_cli_3_la_SOURCES) DIST_SOURCES = $(libnl_cli_3_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = \ -I${top_srcdir}/include/linux-private \ -I${top_srcdir}/include \ -I${top_builddir}/include \ -D_GNU_SOURCE \ -DPKGLIBDIR=\"$(pkglibdir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" AM_CFLAGS = -Wall AM_LDFLAGS = \ -rdynamic \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) NL_LIBADD = \ -L${top_builddir}/lib \ -ldl #nobase_pkglib_LTLIBRARIES = cls/basic.la cls/ematch/cmp.la #cls_basic_la_LDFLAGS = -module -version-info 2:0:0 #cls_ematch_cmp_la_LDFLAGS = -module -version-info 2:0:0 #cls/ematch_grammar.c: cls/ematch_grammar.l # $(LEX) --header-file=cls/ematch_grammar.h $(LFLAGS) -o $@ $^ #cls/ematch_syntax.c: cls/ematch_syntax.y # $(YACC) -d $(YFLAGS) -o $@ $^ #cls/pktloc_grammar.c: cls/pktloc_grammar.l # $(LEX) --header-file=cls/pktloc_grammar.h $(LFLAGS) -o $@ $^ #cls/pktloc_syntax.c: cls/pktloc_syntax.y # $(YACC) -d $(YFLAGS) -o $@ $^ #CLEANFILES = \ # cls/ematch_grammar.c cls/ematch_grammar.h \ # cls/ematch_syntax.c cls/ematch_syntax.h \ # cls/pktloc_grammar.c cls/pktloc_grammar.h \ # cls/pktloc_syntax.c cls/pktloc_syntax.h lib_LTLIBRARIES = \ libnl-cli-3.la libnl_cli_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-cli-3.sym libnl_cli_3_la_DEPENDENCIES = \ $(top_srcdir)/libnl-cli-3.sym libnl_cli_3_la_LIBADD = ${top_builddir}/lib/libnl-3.la \ ${top_builddir}/lib/libnl-route-3.la \ ${top_builddir}/lib/libnl-nf-3.la \ ${top_builddir}/lib/libnl-genl-3.la ${NL_LIBADD} libnl_cli_3_la_SOURCES = \ utils.c addr.c ct.c link.c neigh.c rule.c route.c \ tc.c qdisc.c class.c cls.c exp.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libnl-cli-3.la: $(libnl_cli_3_la_OBJECTS) $(libnl_cli_3_la_DEPENDENCIES) $(EXTRA_libnl_cli_3_la_DEPENDENCIES) $(AM_V_CCLD)$(libnl_cli_3_la_LINK) -rpath $(libdir) $(libnl_cli_3_la_OBJECTS) $(libnl_cli_3_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/class.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ct.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/neigh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qdisc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rule.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile # cls/ematch_syntax.c cls/ematch_grammar.c cls/ematch.c # cls/pktloc_syntax.c cls/pktloc_grammar.c cls/utils.c # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/src/lib/class.c0000644000175000017500000000171213023014600012424 00000000000000/* * src/lib/class.c CLI Class Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ /** * @ingroup cli * @defgroup cli_class Traffic Classes * @{ */ #include #include struct rtnl_class *nl_cli_class_alloc(void) { struct rtnl_class *class; if (!(class = rtnl_class_alloc())) nl_cli_fatal(ENOMEM, "Unable to allocate class object"); return class; } struct nl_cache *nl_cli_class_alloc_cache(struct nl_sock *sock, int ifindex) { struct nl_cache *cache; int err; if ((err = rtnl_class_alloc_cache(sock, ifindex, &cache)) < 0) nl_cli_fatal(err, "Unable to allocate class cache: %s", nl_geterror(err)); nl_cache_mngt_provide(cache); return cache; } /** @} */ libnl-3.2.29/src/lib/exp.c0000644000175000017500000001033513023014600012114 00000000000000/* * src/lib/exp.c CLI Expectation Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2009 Thomas Graf * Copyright (c) 2012 Rich Fought */ /** * @ingroup cli * @defgroup cli_exp Expectation Tracking * * @{ */ #include #include struct nfnl_exp *nl_cli_exp_alloc(void) { struct nfnl_exp *exp; exp = nfnl_exp_alloc(); if (!exp) nl_cli_fatal(ENOMEM, "Unable to allocate expectation object"); return exp; } struct nl_cache *nl_cli_exp_alloc_cache(struct nl_sock *sk) { return nl_cli_alloc_cache(sk, "expectation", nfnl_exp_alloc_cache); } void nl_cli_exp_parse_family(struct nfnl_exp *exp, char *arg) { int family; if ((family = nl_str2af(arg)) == AF_UNSPEC) nl_cli_fatal(EINVAL, "Unable to nl_cli_exp_parse family \"%s\": %s", arg, nl_geterror(NLE_INVAL)); nfnl_exp_set_family(exp, family); } void nl_cli_exp_parse_timeout(struct nfnl_exp *exp, char *arg) { uint32_t timeout = nl_cli_parse_u32(arg); nfnl_exp_set_timeout(exp, timeout); } void nl_cli_exp_parse_id(struct nfnl_exp *exp, char *arg) { uint32_t id = nl_cli_parse_u32(arg); nfnl_exp_set_id(exp, id); } void nl_cli_exp_parse_helper_name(struct nfnl_exp *exp, char *arg) { nfnl_exp_set_helper_name(exp, arg); } void nl_cli_exp_parse_zone(struct nfnl_exp *exp, char *arg) { uint32_t zone = nl_cli_parse_u32(arg); nfnl_exp_set_zone(exp, zone); } void nl_cli_exp_parse_flags(struct nfnl_exp *exp, char *arg) { uint32_t flags = nl_cli_parse_u32(arg); nfnl_exp_set_flags(exp, flags); } void nl_cli_exp_parse_class(struct nfnl_exp *exp, char *arg) { uint32_t class = nl_cli_parse_u32(arg); nfnl_exp_set_class(exp, class); } void nl_cli_exp_parse_nat_dir(struct nfnl_exp *exp, char *arg) { uint32_t nat_dir = nl_cli_parse_u32(arg); nfnl_exp_set_nat_dir(exp, nat_dir); } void nl_cli_exp_parse_fn(struct nfnl_exp *exp, char *arg) { nfnl_exp_set_fn(exp, arg); } void nl_cli_exp_parse_src(struct nfnl_exp *exp, int tuple, char *arg) { int err; struct nl_addr *a = nl_cli_addr_parse(arg, nfnl_exp_get_family(exp)); if ((err = nfnl_exp_set_src(exp, tuple, a)) < 0) nl_cli_fatal(err, "Unable to set source address: %s", nl_geterror(err)); } void nl_cli_exp_parse_dst(struct nfnl_exp *exp, int tuple, char *arg) { int err; struct nl_addr *a = nl_cli_addr_parse(arg, nfnl_exp_get_family(exp)); if ((err = nfnl_exp_set_dst(exp, tuple, a)) < 0) nl_cli_fatal(err, "Unable to set destination address: %s", nl_geterror(err)); } void nl_cli_exp_parse_l4protonum(struct nfnl_exp *exp, int tuple, char *arg) { int l4protonum; if ((l4protonum = nl_str2ip_proto(arg)) < 0) nl_cli_fatal(l4protonum, "Unable to nl_cli_exp_parse protocol \"%s\": %s", arg, nl_geterror(l4protonum)); nfnl_exp_set_l4protonum(exp, tuple, l4protonum); } void nl_cli_exp_parse_src_port(struct nfnl_exp *exp, int tuple, char *arg) { uint32_t sport = nl_cli_parse_u32(arg); uint16_t dport = nfnl_exp_get_dst_port(exp, tuple); nfnl_exp_set_ports(exp, tuple, sport, dport); } void nl_cli_exp_parse_dst_port(struct nfnl_exp *exp, int tuple, char *arg) { uint32_t dport = nl_cli_parse_u32(arg); uint16_t sport = nfnl_exp_get_src_port(exp, tuple); nfnl_exp_set_ports(exp, tuple, sport, dport); } void nl_cli_exp_parse_icmp_id(struct nfnl_exp *exp, int tuple, char *arg) { uint32_t id = nl_cli_parse_u32(arg); uint8_t type = nfnl_exp_get_icmp_type(exp, tuple); uint8_t code = nfnl_exp_get_icmp_code(exp, tuple); nfnl_exp_set_icmp(exp, tuple, id, type, code); } void nl_cli_exp_parse_icmp_type(struct nfnl_exp *exp, int tuple, char *arg) { uint32_t type = nl_cli_parse_u32(arg); uint16_t id = nfnl_exp_get_icmp_id(exp, tuple); uint8_t code = nfnl_exp_get_icmp_code(exp, tuple); nfnl_exp_set_icmp(exp, tuple, id, type, code); } void nl_cli_exp_parse_icmp_code(struct nfnl_exp *exp, int tuple, char *arg) { uint32_t code = nl_cli_parse_u32(arg); uint16_t id = nfnl_exp_get_icmp_id(exp, tuple); uint8_t type = nfnl_exp_get_icmp_type(exp, tuple); nfnl_exp_set_icmp(exp, tuple, id, type, code); } /** @} */ libnl-3.2.29/src/lib/tc.c0000644000175000017500000000716113023014600011731 00000000000000/* * src/lib/tc.c CLI Traffic Control Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include #include #include /** * @ingroup cli * @defgroup cli_tc Traffic Control * @{ */ void nl_cli_tc_parse_dev(struct rtnl_tc *tc, struct nl_cache *link_cache, char *name) { struct rtnl_link *link; link = rtnl_link_get_by_name(link_cache, name); if (!link) nl_cli_fatal(ENOENT, "Link \"%s\" does not exist.", name); rtnl_tc_set_link(tc, link); rtnl_link_put(link); } void nl_cli_tc_parse_parent(struct rtnl_tc *tc, char *arg) { uint32_t parent; int err; if ((err = rtnl_tc_str2handle(arg, &parent)) < 0) nl_cli_fatal(err, "Unable to parse handle \"%s\": %s", arg, nl_geterror(err)); rtnl_tc_set_parent(tc, parent); } void nl_cli_tc_parse_handle(struct rtnl_tc *tc, char *arg, int create) { uint32_t handle, parent; int err; parent = rtnl_tc_get_parent(tc); if ((err = rtnl_tc_str2handle(arg, &handle)) < 0) { if (err == -NLE_OBJ_NOTFOUND && create) err = rtnl_classid_generate(arg, &handle, parent); if (err < 0) nl_cli_fatal(err, "Unable to parse handle \"%s\": %s", arg, nl_geterror(err)); } rtnl_tc_set_handle(tc, handle); } void nl_cli_tc_parse_mtu(struct rtnl_tc *tc, char *arg) { rtnl_tc_set_mtu(tc, nl_cli_parse_u32(arg)); } void nl_cli_tc_parse_mpu(struct rtnl_tc *tc, char *arg) { rtnl_tc_set_mpu(tc, nl_cli_parse_u32(arg)); } void nl_cli_tc_parse_overhead(struct rtnl_tc *tc, char *arg) { rtnl_tc_set_overhead(tc, nl_cli_parse_u32(arg)); } void nl_cli_tc_parse_kind(struct rtnl_tc *tc, char *arg) { rtnl_tc_set_kind(tc, arg); } void nl_cli_tc_parse_linktype(struct rtnl_tc *tc, char *arg) { int type; if ((type = nl_str2llproto(arg)) < 0) nl_cli_fatal(type, "Unable to parse linktype \"%s\": %s", arg, nl_geterror(type)); rtnl_tc_set_linktype(tc, type); } static NL_LIST_HEAD(tc_modules); static struct nl_cli_tc_module *__nl_cli_tc_lookup(struct rtnl_tc_ops *ops) { struct nl_cli_tc_module *tm; nl_list_for_each_entry(tm, &tc_modules, tm_list) if (tm->tm_ops == ops) return tm; return NULL; } struct nl_cli_tc_module *nl_cli_tc_lookup(struct rtnl_tc_ops *ops) { struct nl_cli_tc_module *tm; if ((tm = __nl_cli_tc_lookup(ops))) return tm; switch (ops->to_type) { case RTNL_TC_TYPE_QDISC: case RTNL_TC_TYPE_CLASS: nl_cli_load_module("cli/qdisc", ops->to_kind); break; case RTNL_TC_TYPE_CLS: nl_cli_load_module("cli/cls", ops->to_kind); break; default: nl_cli_fatal(EINVAL, "BUG: unhandled TC object type %d", ops->to_type); } if (!(tm = __nl_cli_tc_lookup(ops))) { nl_cli_fatal(EINVAL, "Application bug: The shared library for " "the tc object \"%s\" was successfully loaded but it " "seems that module did not register itself", ops->to_kind); } return tm; } void nl_cli_tc_register(struct nl_cli_tc_module *tm) { struct rtnl_tc_ops *ops; if (!(ops = rtnl_tc_lookup_ops(tm->tm_type, tm->tm_name))) { nl_cli_fatal(ENOENT, "Unable to register CLI TC module " "\"%s\": No matching libnl TC module found.", tm->tm_name); } if (__nl_cli_tc_lookup(ops)) { nl_cli_fatal(EEXIST, "Unable to register CLI TC module " "\"%s\": Module already registered.", tm->tm_name); } tm->tm_ops = ops; nl_list_add_tail(&tm->tm_list, &tc_modules); } void nl_cli_tc_unregister(struct nl_cli_tc_module *tm) { nl_list_del(&tm->tm_list); } /** @} */ libnl-3.2.29/src/lib/qdisc.c0000644000175000017500000000126513023014600012425 00000000000000/* * src/lib/qdisc.c CLI QDisc Helpers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2011 Thomas Graf */ /** * @ingroup cli * @defgroup cli_qdisc Queueing Disciplines * @{ */ #include #include #include struct rtnl_qdisc *nl_cli_qdisc_alloc(void) { struct rtnl_qdisc *qdisc; if (!(qdisc = rtnl_qdisc_alloc())) nl_cli_fatal(ENOMEM, "Unable to allocate qdisc object"); return qdisc; } /** @} */ libnl-3.2.29/src/nl-link-stats.c0000644000175000017500000000510013023014600013244 00000000000000/* * src/nl-link-stats.c Retrieve link statistics * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include static void print_usage(void) { printf( "Usage: nl-link-stats [OPTION]... [LINK] [ListOfStats]\n" "\n" "Options\n" " -l, --list List available statistic names\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Link Options\n" " -n, --name=NAME link name\n" " -i, --index=NUM interface index\n" ); exit(0); } static void list_stat_names(void) { char buf[64]; int i; for (i = 0; i <= RTNL_LINK_STATS_MAX; i++) printf("%s\n", rtnl_link_stat2str(i, buf, sizeof(buf))); exit(0); } static int gargc; static void dump_stat(struct rtnl_link *link, int id) { uint64_t st = rtnl_link_get_stat(link, id); char buf[64]; printf("%s.%s %" PRIu64 "\n", rtnl_link_get_name(link), rtnl_link_stat2str(id, buf, sizeof(buf)), st); } static void dump_stats(struct nl_object *obj, void *arg) { struct rtnl_link *link = (struct rtnl_link *) obj; char **argv = arg; if (optind >= gargc) { int i; for (i = 0; i <= RTNL_LINK_STATS_MAX; i++) dump_stat(link, i); } else { while (optind < gargc) { int id = rtnl_link_str2stat(argv[optind]); if (id < 0) fprintf(stderr, "Warning: Unknown statistic " "\"%s\"\n", argv[optind]); else dump_stat(link, id); optind++; } } } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *link_cache; struct rtnl_link *link; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); link = nl_cli_link_alloc(); for (;;) { int c, optidx = 0; static struct option long_opts[] = { { "list", 0, 0, 'l' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "name", 1, 0, 'n' }, { "index", 1, 0, 'i' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "lhvn:i:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'l': list_stat_names(); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'n': nl_cli_link_parse_name(link, optarg); break; case 'i': nl_cli_link_parse_ifindex(link, optarg); break; } } gargc = argc; nl_cache_foreach_filter(link_cache, OBJ_CAST(link), dump_stats, argv); return 0; } libnl-3.2.29/src/nf-ct-list.c0000644000175000017500000001046413023014600012535 00000000000000/* * src/nf-ct-list.c List Conntrack Entries * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2009 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #include #include static void print_usage(void) { printf( "Usage: nf-ct-list [OPTION]... [CONNTRACK ENTRY]\n" "\n" "Options\n" " -f, --format=TYPE Output format { brief | details | stats }\n" " -h, --help Show this help\n" " -v, --version Show versioning information\n" "\n" "Conntrack Selection\n" " -i, --id=NUM Identifier\n" " -p, --proto=PROTOCOL Protocol\n" " --tcp-state=STATE TCP connection state\n" " --orig-src=ADDR Original source address\n" " --orig-sport=PORT Original source port\n" " --orig-dst=ADDR Original destination address\n" " --orig-dport=PORT Original destination port\n" " --reply-src=ADDR Reply source address\n" " --reply-sport=PORT Reply source port\n" " --reply-dst=ADDR Reply destination address\n" " --reply-dport=PORT Reply destination port\n" " -F, --family=FAMILY Address family\n" " --mark=NUM Mark value\n" " --timeout=NUM Timeout value\n" " --refcnt=NUM Use counter value\n" " --flags Flags\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *ct_cache; struct nfnl_ct *ct; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; ct = nl_cli_ct_alloc(); for (;;) { int c, optidx = 0; enum { ARG_MARK = 257, ARG_TCP_STATE = 258, ARG_ORIG_SRC, ARG_ORIG_SPORT, ARG_ORIG_DST, ARG_ORIG_DPORT, ARG_REPLY_SRC, ARG_REPLY_SPORT, ARG_REPLY_DST, ARG_REPLY_DPORT, ARG_TIMEOUT, ARG_REFCNT, ARG_FLAGS, }; static struct option long_opts[] = { { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "id", 1, 0, 'i' }, { "proto", 1, 0, 'p' }, { "tcp-state", 1, 0, ARG_TCP_STATE }, { "orig-src", 1, 0, ARG_ORIG_SRC }, { "orig-sport", 1, 0, ARG_ORIG_SPORT }, { "orig-dst", 1, 0, ARG_ORIG_DST }, { "orig-dport", 1, 0, ARG_ORIG_DPORT }, { "reply-src", 1, 0, ARG_REPLY_SRC }, { "reply-sport", 1, 0, ARG_REPLY_SPORT }, { "reply-dst", 1, 0, ARG_REPLY_DST }, { "reply-dport", 1, 0, ARG_REPLY_DPORT }, { "family", 1, 0, 'F' }, { "mark", 1, 0, ARG_MARK }, { "timeout", 1, 0, ARG_TIMEOUT }, { "refcnt", 1, 0, ARG_REFCNT }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "46f:hvi:p:F:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case '4': nfnl_ct_set_family(ct, AF_INET); break; case '6': nfnl_ct_set_family(ct, AF_INET6); break; case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'i': nl_cli_ct_parse_id(ct, optarg); break; case 'p': nl_cli_ct_parse_protocol(ct, optarg); break; case ARG_TCP_STATE: nl_cli_ct_parse_tcp_state(ct, optarg); break; case ARG_ORIG_SRC: nl_cli_ct_parse_src(ct, 0, optarg); break; case ARG_ORIG_SPORT: nl_cli_ct_parse_src_port(ct, 0, optarg); break; case ARG_ORIG_DST: nl_cli_ct_parse_dst(ct, 0, optarg); break; case ARG_ORIG_DPORT: nl_cli_ct_parse_dst_port(ct, 0, optarg); break; case ARG_REPLY_SRC: nl_cli_ct_parse_src(ct, 1, optarg); break; case ARG_REPLY_SPORT: nl_cli_ct_parse_src_port(ct, 1, optarg); break; case ARG_REPLY_DST: nl_cli_ct_parse_dst(ct, 1, optarg); break; case ARG_REPLY_DPORT: nl_cli_ct_parse_dst_port(ct, 1, optarg); break; case 'F': nl_cli_ct_parse_family(ct, optarg); break; case ARG_MARK: nl_cli_ct_parse_mark(ct, optarg); break; case ARG_TIMEOUT: nl_cli_ct_parse_timeout(ct, optarg); break; case ARG_REFCNT: nl_cli_ct_parse_use(ct, optarg); break; case ARG_FLAGS: nl_cli_ct_parse_status(ct, optarg); break; } } sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_NETFILTER); ct_cache = nl_cli_ct_alloc_cache(sock); nl_cache_dump_filter(ct_cache, ¶ms, OBJ_CAST(ct)); return 0; } libnl-3.2.29/src/nl-class-add.c0000644000175000017500000001041213023014600013010 00000000000000/* * src/nl-class-add.c Add/Update/Replace Traffic Class * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include #include #include #include #include #include static int quiet = 0; static void print_usage(void) { printf( "Usage: nl-class-add [OPTIONS]... class [CONFIGURATION]...\n" "\n" "OPTIONS\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help text.\n" " -v, --version Show versioning information.\n" " --update Update class if it exists.\n" " --update-only Only update class, never create it.\n" " -d, --dev=DEV Network device the class should be attached to.\n" " -i, --id=ID ID of new class (default: auto-generated)\n" " -p, --parent=ID ID of parent { root | ingress | class-ID }\n" " --mtu=SIZE Overwrite MTU (default: MTU of network device)\n" " --mpu=SIZE Minimum packet size on the link (default: 0).\n" " --overhead=SIZE Overhead in bytes per packet (default: 0).\n" " --linktype=TYPE Overwrite linktype (default: type of network device)\n" "\n" "CONFIGURATION\n" " -h, --help Show help text of class specific options.\n" "\n" "EXAMPLE\n" " $ nl-class-add --dev=eth1 --parent=root htb --rate=100mbit\n" "\n" ); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_class *class; struct rtnl_tc *tc; struct nl_cache *link_cache; struct nl_dump_params dp = { .dp_type = NL_DUMP_DETAILS, .dp_fd = stdout, }; struct nl_cli_tc_module *tm; struct rtnl_tc_ops *ops; int err, flags = NLM_F_CREATE | NLM_F_EXCL; char *kind, *id = NULL; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); class = nl_cli_class_alloc(); tc = (struct rtnl_tc *) class; for (;;) { int c, optidx = 0; enum { ARG_UPDATE = 257, ARG_UPDATE_ONLY = 258, ARG_MTU, ARG_MPU, ARG_OVERHEAD, ARG_LINKTYPE, }; static struct option long_opts[] = { { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, { "id", 1, 0, 'i' }, { "update", 0, 0, ARG_UPDATE }, { "update-only", 0, 0, ARG_UPDATE_ONLY }, { "mtu", 1, 0, ARG_MTU }, { "mpu", 1, 0, ARG_MPU }, { "overhead", 1, 0, ARG_OVERHEAD }, { "linktype", 1, 0, ARG_LINKTYPE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "+qhvd:p:i:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; case 'p': nl_cli_tc_parse_parent(tc, optarg); break; case 'i': id = strdup(optarg); break; case ARG_UPDATE: flags = NLM_F_CREATE; break; case ARG_UPDATE_ONLY: flags = 0; break; case ARG_MTU: nl_cli_tc_parse_mtu(tc, optarg); break; case ARG_MPU: nl_cli_tc_parse_mpu(tc, optarg); break; case ARG_OVERHEAD: nl_cli_tc_parse_overhead(tc, optarg); break; case ARG_LINKTYPE: nl_cli_tc_parse_linktype(tc, optarg); break; } } if (optind >= argc) print_usage(); if (!rtnl_tc_get_ifindex(tc)) nl_cli_fatal(EINVAL, "You must specify a network device (--dev=XXX)"); if (!rtnl_tc_get_parent(tc)) nl_cli_fatal(EINVAL, "You must specify a parent (--parent=XXX)"); if (id) { nl_cli_tc_parse_handle(tc, id, 1); free(id); } kind = argv[optind++]; rtnl_tc_set_kind(tc, kind); if (!(ops = rtnl_tc_get_ops(tc))) nl_cli_fatal(ENOENT, "Unknown class \"%s\"", kind); if (!(tm = nl_cli_tc_lookup(ops))) nl_cli_fatal(ENOTSUP, "class type \"%s\" not supported.", kind); tm->tm_parse_argv(tc, argc, argv); if (!quiet) { printf("Adding "); nl_object_dump(OBJ_CAST(class), &dp); } if ((err = rtnl_class_add(sock, class, flags)) < 0) nl_cli_fatal(EINVAL, "Unable to add class: %s", nl_geterror(err)); return 0; } libnl-3.2.29/src/nl-addr-delete.c0000644000175000017500000000766713023014600013351 00000000000000/* * src/nl-addr-delete.c Delete addresses * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2 of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static struct nl_sock *sock; static int interactive = 0, default_yes = 0, quiet = 0; static int deleted = 0; static void print_usage(void) { printf( "Usage: nl-addr-delete [OPTION]... [ADDRESS]\n" "\n" "Options\n" " -i, --interactive Run interactively.\n" " --yes Set default answer to yes.\n" " -q, --quiet Do not print informal notifications.\n" " -h, --help Show this help.\n" " -v, --version Show versioning information.\n" "\n" "Address Options\n" " -a, --local=ADDR Local address.\n" " -d, --dev=DEV Associated network device.\n" " --family=FAMILY Family of local address.\n" " --label=STRING Address label (IPv4).\n" " --peer=ADDR Peer address (IPv4).\n" " --scope=SCOPE Address scope (IPv4).\n" " --broadcast=ADDR Broadcast address of network (IPv4).\n" " --valid-lifetime=TS Valid lifetime before route expires (IPv6).\n" " --preferred=TIME Preferred lifetime (IPv6).\n" " --valid=TIME Valid lifetime (IPv6).\n" ); exit(0); } static void delete_cb(struct nl_object *obj, void *arg) { struct rtnl_addr *addr = nl_object_priv(obj); struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; if (interactive && !nl_cli_confirm(obj, ¶ms, default_yes)) return; if ((err = rtnl_addr_delete(sock, addr, 0)) < 0) nl_cli_fatal(err, "Unable to delete address: %s\n", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(obj, ¶ms); } deleted++; } int main(int argc, char *argv[]) { struct rtnl_addr *addr; struct nl_cache *link_cache, *addr_cache; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); addr_cache = nl_cli_addr_alloc_cache(sock); addr = nl_cli_addr_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_LABEL = 258, ARG_YES, ARG_PEER, ARG_SCOPE, ARG_BROADCAST, ARG_PREFERRED, ARG_VALID, }; static struct option long_opts[] = { { "interactive", 0, 0, 'i' }, { "yes", 0, 0, ARG_YES }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "local", 1, 0, 'a' }, { "dev", 1, 0, 'd' }, { "family", 1, 0, ARG_FAMILY }, { "label", 1, 0, ARG_LABEL }, { "peer", 1, 0, ARG_PEER }, { "scope", 1, 0, ARG_SCOPE }, { "broadcast", 1, 0, ARG_BROADCAST }, { "preferred", 1, 0, ARG_PREFERRED }, { "valid", 1, 0, ARG_VALID }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "iqhva:d:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'i': interactive = 1; break; case ARG_YES: default_yes = 1; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'a': nl_cli_addr_parse_local(addr, optarg); break; case 'd': nl_cli_addr_parse_dev(addr, link_cache, optarg); break; case ARG_FAMILY: nl_cli_addr_parse_family(addr, optarg); break; case ARG_LABEL: nl_cli_addr_parse_label(addr, optarg); break; case ARG_PEER: nl_cli_addr_parse_peer(addr, optarg); break; case ARG_SCOPE: nl_cli_addr_parse_scope(addr, optarg); break; case ARG_BROADCAST: nl_cli_addr_parse_broadcast(addr, optarg); break; case ARG_PREFERRED: nl_cli_addr_parse_preferred(addr, optarg); break; case ARG_VALID: nl_cli_addr_parse_valid(addr, optarg); break; } } nl_cache_foreach_filter(addr_cache, OBJ_CAST(addr), delete_cb, NULL); if (!quiet) printf("Deleted %d addresses\n", deleted); return 0; } libnl-3.2.29/src/nf-monitor.c0000644000175000017500000000470013023014600012641 00000000000000/* * src/nf-monitor.c Monitor netfilter events * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #include #include static void obj_input(struct nl_object *obj, void *arg) { struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; nl_object_dump(obj, &dp); } static int event_input(struct nl_msg *msg, void *arg) { if (nl_msg_parse(msg, &obj_input, NULL) < 0) fprintf(stderr, "<> Unknown message type\n"); /* Exit nl_recvmsgs_def() and return to the main select() */ return NL_STOP; } int main(int argc, char *argv[]) { struct nl_sock *sock; int err; int i, idx; static const struct { enum nfnetlink_groups gr_id; const char* gr_name; } groups[] = { { NFNLGRP_CONNTRACK_NEW, "ct-new" }, { NFNLGRP_CONNTRACK_UPDATE, "ct-update" }, { NFNLGRP_CONNTRACK_DESTROY, "ct-destroy" }, { NFNLGRP_NONE, NULL } }; sock = nl_cli_alloc_socket(); nl_socket_disable_seq_check(sock); nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); if (argc > 1 && !strcasecmp(argv[1], "-h")) { printf("Usage: nf-monitor []\n"); printf("Known groups:"); for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++) printf(" %s", groups[i].gr_name); printf("\n"); return 2; } nl_cli_connect(sock, NETLINK_NETFILTER); for (idx = 1; argc > idx; idx++) { for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++) { if (strcmp(argv[idx], groups[i].gr_name)) continue; err = nl_socket_add_membership(sock, groups[i].gr_id); if (err < 0) nl_cli_fatal(err, "Unable to add membership: %s", nl_geterror(err)); break; } if (groups[i].gr_id == NFNLGRP_NONE) nl_cli_fatal(NLE_OBJ_NOTFOUND, "Unknown group: \"%s\"", argv[idx]); } while (1) { fd_set rfds; int fd, retval; fd = nl_socket_get_fd(sock); FD_ZERO(&rfds); FD_SET(fd, &rfds); /* wait for an incoming message on the netlink socket */ retval = select(fd+1, &rfds, NULL, NULL, NULL); if (retval) { /* FD_ISSET(fd, &rfds) will be true */ nl_recvmsgs_default(sock); } } return 0; } libnl-3.2.29/src/nl-addr-list.c0000644000175000017500000001332713023014600013050 00000000000000/* * src/nl-addr-list.c List addresses * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2 of the License. * * Copyright (c) 2003-2009 Thomas Graf */ #include #include #include static void print_usage(void) { printf( "Usage: nl-addr-list [OPTION]... [ADDRESS]\n" "\n" "Options\n" " --details Show details on multiple lines.\n" " --env Print address details in sh env variable syntax.\n" " --prefix=STRING Prefix each printed line.\n" " -h, --help Show this help.\n" " -v, --version Show versioning information.\n" "\n" "Address Selection\n" " -a, --local=ADDR Local address.\n" " -d, --dev=DEV Associated network device.\n" " --family=FAMILY Family of local address.\n" " --label=STRING Address label (IPv4).\n" " --peer=ADDR Peer address (IPv4).\n" " --scope=SCOPE Address scope (IPv4).\n" " --broadcast=ADDR Broadcast address of network (IPv4).\n" " --valid-lifetime=TS Valid lifetime before route expires (IPv6).\n" " --preferred=TIME Preferred lifetime (IPv6).\n" " --valid=TIME Valid lifetime (IPv6).\n" ); exit(0); } static char *prefix; static void print_prefix(struct nl_dump_params *p, int line) { if (prefix) nl_dump(p, "%s", prefix); } static void env_dump(struct nl_object *obj, void *arg) { struct nl_dump_params *p = arg; struct rtnl_addr *addr = (struct rtnl_addr *) obj; struct nl_cache *link_cache; struct nl_addr *a; static int index = 0; char buf[128], pfx[32], *s; snprintf(pfx, sizeof(pfx), "ADDR%d", index++); nl_dump_line(p, "%s_FAMILY=%s\n", pfx, nl_af2str(rtnl_addr_get_family(addr), buf, sizeof(buf))); nl_dump_line(p, "%s_LOCAL=%s\n", pfx, nl_addr2str(rtnl_addr_get_local(addr), buf, sizeof(buf))); nl_dump_line(p, "%s_IFINDEX=%u\n", pfx, rtnl_addr_get_ifindex(addr)); link_cache = nl_cache_mngt_require_safe("route/link"); if (link_cache) nl_dump_line(p, "%s_IFNAME=%s\n", pfx, rtnl_link_i2name(link_cache, rtnl_addr_get_ifindex(addr), buf, sizeof(buf))); if ((a = rtnl_addr_get_peer(addr))) nl_dump_line(p, "%s_PEER=%s\n", pfx, nl_addr2str(a, buf, sizeof(buf))); if ((a = rtnl_addr_get_broadcast(addr))) nl_dump_line(p, "%s_BROADCAST=%s\n", pfx, nl_addr2str(a, buf, sizeof(buf))); nl_dump_line(p, "%s_SCOPE=%s\n", pfx, rtnl_scope2str(rtnl_addr_get_scope(addr), buf, sizeof(buf))); if ((s = rtnl_addr_get_label(addr))) nl_dump_line(p, "%s_LABEL=%s\n", pfx, s); rtnl_addr_flags2str(rtnl_addr_get_flags(addr), buf, sizeof(buf)); if (buf[0]) nl_dump_line(p, "%s_FLAGS=%s\n", pfx, buf); nl_dump_line(p, "%s_CACHEINFO_VALID=%u\n", pfx, rtnl_addr_get_valid_lifetime(addr)); if (link_cache) nl_cache_put(link_cache); #if 0 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) { struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo; nl_dump_line(p, "ADDR_CACHEINFO_PREFERRED=%u\n", ci->aci_prefered); nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%u\n", ci->aci_cstamp); nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%u\n", ci->aci_tstamp); } #endif } int main(int argc, char *argv[]) { struct nl_sock *sock; struct rtnl_addr *addr; struct nl_cache *link_cache, *addr_cache; struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_nl_cb = print_prefix, .dp_fd = stdout, }; int dump_env = 0; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); addr_cache = nl_cli_addr_alloc_cache(sock); addr = nl_cli_addr_alloc(); for (;;) { int c, optidx = 0; enum { ARG_FAMILY = 257, ARG_LABEL = 258, ARG_PEER, ARG_SCOPE, ARG_BROADCAST, ARG_DETAILS, ARG_ENV, ARG_PREFIX, ARG_PREFERRED, ARG_VALID, }; static struct option long_opts[] = { { "details", 0, 0, ARG_DETAILS }, { "env", 0, 0, ARG_ENV }, { "prefix", 1, 0, ARG_PREFIX }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "local", 1, 0, 'a' }, { "dev", 1, 0, 'd' }, { "family", 1, 0, ARG_FAMILY }, { "label", 1, 0, ARG_LABEL }, { "peer", 1, 0, ARG_PEER }, { "scope", 1, 0, ARG_SCOPE }, { "broadcast", 1, 0, ARG_BROADCAST }, { "preferred", 1, 0, ARG_PREFERRED }, { "valid", 1, 0, ARG_VALID }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "46hva:d:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case '4': rtnl_addr_set_family(addr, AF_INET); break; case '6': rtnl_addr_set_family(addr, AF_INET6); break; case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break; case ARG_ENV: dump_env = 1; break; case ARG_PREFIX: prefix = strdup(optarg); break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; case 'a': nl_cli_addr_parse_local(addr, optarg); break; case 'd': nl_cli_addr_parse_dev(addr, link_cache, optarg); break; case ARG_FAMILY: nl_cli_addr_parse_family(addr, optarg); break; case ARG_LABEL: nl_cli_addr_parse_label(addr, optarg); break; case ARG_PEER: nl_cli_addr_parse_peer(addr, optarg); break; case ARG_SCOPE: nl_cli_addr_parse_scope(addr, optarg); break; case ARG_BROADCAST: nl_cli_addr_parse_broadcast(addr, optarg); break; case ARG_PREFERRED: nl_cli_addr_parse_preferred(addr, optarg); break; case ARG_VALID: nl_cli_addr_parse_valid(addr, optarg); break; } } if (dump_env) nl_cache_foreach_filter(addr_cache, OBJ_CAST(addr), env_dump, ¶ms); else nl_cache_dump_filter(addr_cache, ¶ms, OBJ_CAST(addr)); return 0; } libnl-3.2.29/src/nl-link-name2ifindex.c0000644000175000017500000000165713023014600014474 00000000000000/* * src/nl-link-name2ifindex.c Transform a interface name to its index * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ #include #include static void print_usage(void) { printf("Usage: nl-link-name2ifindex \n"); exit(0); } int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_cache *link_cache; uint32_t ifindex; if (argc < 2) print_usage(); sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(sock); if (!(ifindex = rtnl_link_name2i(link_cache, argv[1]))) nl_cli_fatal(ENOENT, "Interface \"%s\" does not exist", argv[1]); printf("%u\n", ifindex); return 0; } libnl-3.2.29/COPYING0000644000175000017500000006364213023014600010663 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libnl-3.2.29/Makefile.in0000644000175000017500000007421413031473644011712 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_CLI_TRUE@am__append_1 = src @ENABLE_CLI_TRUE@am__append_2 = libnl-cli-3.0.pc subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = libnl-3.0.pc libnl-route-3.0.pc libnl-genl-3.0.pc \ libnl-nf-3.0.pc libnl-cli-3.0.pc libnl-xfrm-3.0.pc \ libnl-idiag-3.0.pc include/netlink/version.h CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(pkgsysconfdir)" DATA = $(pkgconfig_DATA) $(pkgsysconf_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = include lib man python tests src am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libnl-3.0.pc.in \ $(srcdir)/libnl-cli-3.0.pc.in $(srcdir)/libnl-genl-3.0.pc.in \ $(srcdir)/libnl-idiag-3.0.pc.in $(srcdir)/libnl-nf-3.0.pc.in \ $(srcdir)/libnl-route-3.0.pc.in $(srcdir)/libnl-xfrm-3.0.pc.in \ $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \ $(top_srcdir)/build-aux/config.guess \ $(top_srcdir)/build-aux/config.sub \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing \ $(top_srcdir)/include/netlink/version.h.in COPYING ChangeLog \ build-aux/ar-lib build-aux/compile build-aux/config.guess \ build-aux/config.sub build-aux/install-sh build-aux/ltmain.sh \ build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = include lib man python tests $(am__append_1) pkgconfig_DATA = libnl-3.0.pc libnl-route-3.0.pc libnl-genl-3.0.pc \ libnl-nf-3.0.pc libnl-xfrm-3.0.pc libnl-idiag-3.0.pc \ $(am__append_2) pkgsysconfdir = ${sysconfdir}/libnl pkgsysconf_DATA = etc/pktloc etc/classid EXTRA_DIST = \ $(pkgsysconf_DATA) \ libnl-3.sym \ libnl-cli-3.sym \ libnl-genl-3.sym \ libnl-idiag-3.sym \ libnl-nf-3.sym \ libnl-route-3.sym \ libnl-xfrm-3.sym all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): libnl-3.0.pc: $(top_builddir)/config.status $(srcdir)/libnl-3.0.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libnl-route-3.0.pc: $(top_builddir)/config.status $(srcdir)/libnl-route-3.0.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libnl-genl-3.0.pc: $(top_builddir)/config.status $(srcdir)/libnl-genl-3.0.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libnl-nf-3.0.pc: $(top_builddir)/config.status $(srcdir)/libnl-nf-3.0.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libnl-cli-3.0.pc: $(top_builddir)/config.status $(srcdir)/libnl-cli-3.0.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libnl-xfrm-3.0.pc: $(top_builddir)/config.status $(srcdir)/libnl-xfrm-3.0.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libnl-idiag-3.0.pc: $(top_builddir)/config.status $(srcdir)/libnl-idiag-3.0.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ include/netlink/version.h: $(top_builddir)/config.status $(top_srcdir)/include/netlink/version.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-pkgsysconfDATA: $(pkgsysconf_DATA) @$(NORMAL_INSTALL) @list='$(pkgsysconf_DATA)'; test -n "$(pkgsysconfdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgsysconfdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgsysconfdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgsysconfdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgsysconfdir)" || exit $$?; \ done uninstall-pkgsysconfDATA: @$(NORMAL_UNINSTALL) @list='$(pkgsysconf_DATA)'; test -n "$(pkgsysconfdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgsysconfdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgsysconfdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pkgconfigDATA install-pkgsysconfDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-pkgconfigDATA uninstall-pkgsysconfDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-pkgconfigDATA \ install-pkgsysconfDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-pkgconfigDATA \ uninstall-pkgsysconfDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/libnl-route-3.0.pc.in0000644000175000017500000000042613023014600013302 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnl-route Description: Netlink Routing Family Library Version: @PACKAGE_VERSION@ Requires: libnl-3.0 Libs: -L${libdir} -lnl-route-@MAJ_VERSION@ Cflags: -I${includedir}/libnl@MAJ_VERSION@ libnl-3.2.29/libnl-xfrm-3.0.pc.in0000644000175000017500000000042413023014600013116 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnl-xfrm Description: Netlink Routing Family Library Version: @PACKAGE_VERSION@ Requires: libnl-3.0 Libs: -L${libdir} -lnl-xfrm-@MAJ_VERSION@ Cflags: -I${includedir}/libnl@MAJ_VERSION@ libnl-3.2.29/libnl-xfrm-3.sym0000644000175000017500000001410713023014600012564 00000000000000libnl_3 { global: xfrmnl_ae_alloc; xfrmnl_ae_build_get_request; xfrmnl_ae_flags2str; xfrmnl_ae_get_curlifetime; xfrmnl_ae_get_daddr; xfrmnl_ae_get_family; xfrmnl_ae_get_flags; xfrmnl_ae_get_kernel; xfrmnl_ae_get_mark; xfrmnl_ae_get_proto; xfrmnl_ae_get_replay_maxage; xfrmnl_ae_get_replay_maxdiff; xfrmnl_ae_get_replay_state; xfrmnl_ae_get_replay_state_esn; xfrmnl_ae_get_reqid; xfrmnl_ae_get_saddr; xfrmnl_ae_get_spi; xfrmnl_ae_parse; xfrmnl_ae_put; xfrmnl_ae_set; xfrmnl_ae_set_curlifetime; xfrmnl_ae_set_daddr; xfrmnl_ae_set_family; xfrmnl_ae_set_flags; xfrmnl_ae_set_mark; xfrmnl_ae_set_proto; xfrmnl_ae_set_replay_maxage; xfrmnl_ae_set_replay_maxdiff; xfrmnl_ae_set_replay_state; xfrmnl_ae_set_replay_state_esn; xfrmnl_ae_set_reqid; xfrmnl_ae_set_saddr; xfrmnl_ae_set_spi; xfrmnl_ae_str2flag; xfrmnl_ltime_cfg_alloc; xfrmnl_ltime_cfg_clone; xfrmnl_ltime_cfg_cmp; xfrmnl_ltime_cfg_get; xfrmnl_ltime_cfg_get_hard_addexpires; xfrmnl_ltime_cfg_get_hard_bytelimit; xfrmnl_ltime_cfg_get_hard_packetlimit; xfrmnl_ltime_cfg_get_hard_useexpires; xfrmnl_ltime_cfg_get_soft_addexpires; xfrmnl_ltime_cfg_get_soft_bytelimit; xfrmnl_ltime_cfg_get_soft_packetlimit; xfrmnl_ltime_cfg_get_soft_useexpires; xfrmnl_ltime_cfg_put; xfrmnl_ltime_cfg_set_hard_addexpires; xfrmnl_ltime_cfg_set_hard_bytelimit; xfrmnl_ltime_cfg_set_hard_packetlimit; xfrmnl_ltime_cfg_set_hard_useexpires; xfrmnl_ltime_cfg_set_soft_addexpires; xfrmnl_ltime_cfg_set_soft_bytelimit; xfrmnl_ltime_cfg_set_soft_packetlimit; xfrmnl_ltime_cfg_set_soft_useexpires; xfrmnl_ltime_cfg_shared; xfrmnl_sa_add; xfrmnl_sa_alloc; xfrmnl_sa_alloc_cache; xfrmnl_sa_build_add_request; xfrmnl_sa_build_delete_request; xfrmnl_sa_build_get_request; xfrmnl_sa_build_update_request; xfrmnl_sa_delete; xfrmnl_sa_flags2str; xfrmnl_sa_get; xfrmnl_sa_get_aead_params; xfrmnl_sa_get_auth_params; xfrmnl_sa_get_coaddr; xfrmnl_sa_get_comp_params; xfrmnl_sa_get_crypto_params; xfrmnl_sa_get_curlifetime; xfrmnl_sa_get_daddr; xfrmnl_sa_get_encap_tmpl; xfrmnl_sa_get_family; xfrmnl_sa_get_flags; xfrmnl_sa_get_kernel; xfrmnl_sa_get_lifetime_cfg; xfrmnl_sa_get_mark; xfrmnl_sa_get_mode; xfrmnl_sa_get_proto; xfrmnl_sa_get_replay_maxage; xfrmnl_sa_get_replay_maxdiff; xfrmnl_sa_get_replay_state; xfrmnl_sa_get_replay_state_esn; xfrmnl_sa_get_replay_window; xfrmnl_sa_get_reqid; xfrmnl_sa_get_saddr; xfrmnl_sa_get_sec_ctx; xfrmnl_sa_get_sel; xfrmnl_sa_get_seq; xfrmnl_sa_get_spi; xfrmnl_sa_get_stats; xfrmnl_sa_get_tfcpad; xfrmnl_sa_is_expiry_reached; xfrmnl_sa_is_hardexpiry_reached; xfrmnl_sa_mode2str; xfrmnl_sa_parse; xfrmnl_sa_put; xfrmnl_sa_set_aead_params; xfrmnl_sa_set_auth_params; xfrmnl_sa_set_coaddr; xfrmnl_sa_set_comp_params; xfrmnl_sa_set_crypto_params; xfrmnl_sa_set_daddr; xfrmnl_sa_set_encap_tmpl; xfrmnl_sa_set_family; xfrmnl_sa_set_flags; xfrmnl_sa_set_lifetime_cfg; xfrmnl_sa_set_mark; xfrmnl_sa_set_mode; xfrmnl_sa_set_proto; xfrmnl_sa_set_replay_maxage; xfrmnl_sa_set_replay_maxdiff; xfrmnl_sa_set_replay_state; xfrmnl_sa_set_replay_state_esn; xfrmnl_sa_set_replay_window; xfrmnl_sa_set_reqid; xfrmnl_sa_set_saddr; xfrmnl_sa_set_sec_ctx; xfrmnl_sa_set_sel; xfrmnl_sa_set_spi; xfrmnl_sa_set_tfcpad; xfrmnl_sa_str2flag; xfrmnl_sa_str2mode; xfrmnl_sa_update; xfrmnl_sel_alloc; xfrmnl_sel_clone; xfrmnl_sel_cmp; xfrmnl_sel_dump; xfrmnl_sel_get; xfrmnl_sel_get_daddr; xfrmnl_sel_get_dport; xfrmnl_sel_get_dportmask; xfrmnl_sel_get_family; xfrmnl_sel_get_ifindex; xfrmnl_sel_get_prefixlen_d; xfrmnl_sel_get_prefixlen_s; xfrmnl_sel_get_proto; xfrmnl_sel_get_saddr; xfrmnl_sel_get_sport; xfrmnl_sel_get_sportmask; xfrmnl_sel_get_userid; xfrmnl_sel_put; xfrmnl_sel_set_daddr; xfrmnl_sel_set_dport; xfrmnl_sel_set_dportmask; xfrmnl_sel_set_family; xfrmnl_sel_set_ifindex; xfrmnl_sel_set_prefixlen_d; xfrmnl_sel_set_prefixlen_s; xfrmnl_sel_set_proto; xfrmnl_sel_set_saddr; xfrmnl_sel_set_sport; xfrmnl_sel_set_sportmask; xfrmnl_sel_set_userid; xfrmnl_sel_shared; xfrmnl_sp_action2str; xfrmnl_sp_add; xfrmnl_sp_add_usertemplate; xfrmnl_sp_alloc; xfrmnl_sp_alloc_cache; xfrmnl_sp_build_add_request; xfrmnl_sp_build_delete_request; xfrmnl_sp_build_get_request; xfrmnl_sp_build_update_request; xfrmnl_sp_delete; xfrmnl_sp_dir2str; xfrmnl_sp_flags2str; xfrmnl_sp_foreach_usertemplate; xfrmnl_sp_get; xfrmnl_sp_get_action; xfrmnl_sp_get_curlifetime; xfrmnl_sp_get_dir; xfrmnl_sp_get_flags; xfrmnl_sp_get_index; xfrmnl_sp_get_kernel; xfrmnl_sp_get_lifetime_cfg; xfrmnl_sp_get_mark; xfrmnl_sp_get_nusertemplates; xfrmnl_sp_get_priority; xfrmnl_sp_get_sec_ctx; xfrmnl_sp_get_sel; xfrmnl_sp_get_share; xfrmnl_sp_get_userpolicy_type; xfrmnl_sp_get_usertemplates; xfrmnl_sp_index2dir; xfrmnl_sp_parse; xfrmnl_sp_put; xfrmnl_sp_remove_usertemplate; xfrmnl_sp_set_action; xfrmnl_sp_set_dir; xfrmnl_sp_set_flags; xfrmnl_sp_set_index; xfrmnl_sp_set_lifetime_cfg; xfrmnl_sp_set_mark; xfrmnl_sp_set_priority; xfrmnl_sp_set_sec_ctx; xfrmnl_sp_set_sel; xfrmnl_sp_set_share; xfrmnl_sp_set_userpolicy_type; xfrmnl_sp_share2str; xfrmnl_sp_str2action; xfrmnl_sp_str2dir; xfrmnl_sp_str2flag; xfrmnl_sp_str2share; xfrmnl_sp_str2type; xfrmnl_sp_type2str; xfrmnl_sp_update; xfrmnl_sp_usertemplate_n; xfrmnl_user_tmpl_alloc; xfrmnl_user_tmpl_clone; xfrmnl_user_tmpl_cmp; xfrmnl_user_tmpl_dump; xfrmnl_user_tmpl_free; xfrmnl_user_tmpl_get_aalgos; xfrmnl_user_tmpl_get_calgos; xfrmnl_user_tmpl_get_daddr; xfrmnl_user_tmpl_get_ealgos; xfrmnl_user_tmpl_get_family; xfrmnl_user_tmpl_get_mode; xfrmnl_user_tmpl_get_optional; xfrmnl_user_tmpl_get_proto; xfrmnl_user_tmpl_get_reqid; xfrmnl_user_tmpl_get_saddr; xfrmnl_user_tmpl_get_share; xfrmnl_user_tmpl_get_spi; xfrmnl_user_tmpl_mode2str; xfrmnl_user_tmpl_set_aalgos; xfrmnl_user_tmpl_set_calgos; xfrmnl_user_tmpl_set_daddr; xfrmnl_user_tmpl_set_ealgos; xfrmnl_user_tmpl_set_family; xfrmnl_user_tmpl_set_mode; xfrmnl_user_tmpl_set_optional; xfrmnl_user_tmpl_set_proto; xfrmnl_user_tmpl_set_reqid; xfrmnl_user_tmpl_set_saddr; xfrmnl_user_tmpl_set_share; xfrmnl_user_tmpl_set_spi; xfrmnl_user_tmpl_str2mode; local: *; }; libnl-3.2.29/man/0000755000175000017500000000000013031473756010474 500000000000000libnl-3.2.29/man/Makefile.am0000644000175000017500000000023213023014600012421 00000000000000# -*- Makefile -*- dist_man8_MANS = \ nl-classid-lookup.8 \ nl-pktloc-lookup.8 \ nl-qdisc-add.8 nl-qdisc-delete.8 nl-qdisc-list.8 \ genl-ctrl-list.8 libnl-3.2.29/man/nl-qdisc-add.80000644000175000017500000000611313023014600012722 00000000000000.TH nl\-qdisc 8 "21 October 2010" "libnl" .SH NAME nl\-qdisc\-{add|list|delete} - Manage queueing disciplines .SH SYNOPSIS .B nl\-qdisc\-add \-\-dev .I dev .B \-\-parent .I id .B [OPTIONS] .I qdisc-type .B [QDISC] .sp .B nl\-qdisc\-delete [ \-\-interactive ] [OPTIONS] .sp .B nl\-qdisc\-list [OPTIONS] .SH DESCRIPTION .PP The nl\-qdisc tools allow to manage and configure queueing disciplines (qdiscs) in the kernel. .SH OPTIONS .TP .BR \-\^h " or " \-\-help Print help text to console and exit. .TP .BR \-\^v " or " \-\-version Print versioning information to console and exit. .TP .BR \-\^q " or " \-\-quiet Do not print informal notifications about actions taken to the console. By default a short description of each qdisc added/update/deleted will be printed to the console. This option disables this behaviour. .TP .BR \-\^d " or " \-\-dev "=DEV" Network device the qdisc is attached to. .TP .BR \-\^p " or " \-\-parent "=ID" Identifier of the parent qdisc/class this qdisc is attached to. The identifier can be specified as classid, name or one of the special values "root" or "ingress". .TP .BR \-\^i " or " \-\-id "=ID" Identifier of qdisc. It can be specified as classid or name. .SS nl\-qdisc\-add Options .TP .B \-\-update Update qdisc if it already exists, otherwise attempting to add a qdisc which already exists will result in an error. This does not include changing the type of the qdisc, use \-\-replace if you wish to do so. .TP .B \-\-replace Replace or update qdisc if it already exists. Same behaviour as \-\-update but will completely replace the qdisc if it exists already. .TP .B \-\-update\-only Update an existing qdisc but do not create it if it does not exist. .TP .B \-\-replace\-only Update or replace an existing qdisc but do not create it if it does exist. .SS nl\-qdisc\-delete Options .TP .B \-\-interactive The interactive mode requires confirmation by the user for each qdisc deleted. It will print a prompt for each qdisc matching the provided filter and requires the user to answer 'y'es or 'n'o. .TP .B \-\-yes Make the default answer for interactive prompts be 'y'es. This option is also required to delete all qdiscs on all network devices. .TP .BR \-\^k " or " \-\-kind "=TYPE" Only delete qdiscs of this type. .SS nl\-qdisc\-list Options .TP .B \-\-details Show detailed information for each qdisc listed. .TP .B \-\-stats Show statistics information for each qdisc listed. This option will also turn on detailed information automatically. .TP .BR \-\^r " or " \-\-recursive List all TC objects recurisvely attached to all qdiscs matching the filter. .TP .BR \-\^k " or " \-\-kind "=TYPE" Only list qdiscs of this type. .SH USAGE .PP Add a HTB root qdisc with id "5:": .PP .RS nl\-qdisc\-add \-\-dev eth0 \-\-parent root \-\-id 5: htb .RE .PP List all qdiscs on eth0 and print statistical data: .PP .RS nl\-qdisc\-list \-\-stats \-\-dev eth0 .RE .PP Delete the qdisc "5:": .RS nl\-qdisc\-delete \-\-id 5: .RE .SH "SEE ALSO" .PP .B nl\-classid\-lookup(8) .SH AUTHOR .PP Thomas Graf is the original author and current maintainer of libnl and libnl tools. Many people have contributed to it since. libnl-3.2.29/man/nl-qdisc-delete.80000644000175000017500000000003013023014600013424 00000000000000.so man8/nl-qdisc-add.8 libnl-3.2.29/man/genl-ctrl-list.80000644000175000017500000000367313023014600013332 00000000000000.TH genl\-ctrl-list 8 "20 April 2012" "libnl" .SH NAME genl\-ctrl\-list \- List available kernel-side Generic Netlink families .SH SYNOPSIS .B genl\-ctrl\-list [-d] .SH DESCRIPTION .PP Queries the Generic Netlink controller in kernel and prints a list of all registered Generic Netlink families including the version of the interface that has been registered. .SH OPTIONS .TP .BR \-\^h " or " \-\-help Print help text to console and exit. .TP .BR \-\^v " or " \-\-version Print versioning information to console and exit. .TP .BR \-\^d " or " \-\-details Include additional detailed information for each Generic Netlink family that is printed. The information includes: .RS .TP .B hdrsize N The size of the user specific header. .TP .B maxattr N The maximum Netlink attribute identifier expected by the interface. .TP .B op NAME (ID) A list of available operations including their name, numeric identifier and the flags indicating the capabilities of the opertion. Available flags: .RS .TP .I admin-perm Requires administrative privileges .TP .I has-doit Command can handle request .TP .I has-dump Command can handle a dump request .TP .I has-policy Command enforces attribute validation policy .RE .TP .B grp NAME (ID) A list of registered multicast groups including name (if available) and identifier. .RE .RS .B Example: .RS 0x0010 nlctrl version 2 .RS 0 hdrsize 0 maxattr 7 .RS 0 op GETFAMILY (0x03) .RS 0 grp notify (0x10) .RE .SH EXAMPLE .RS 0 $ genl-ctrl-list .RS 0 0x0010 nlctrl version 2 .RS 0 0x0011 NLBL_MGMT version 3 .RS 0 0x0012 NLBL_CIPSOv4 version 3 .RS 0 0x0013 NLBL_UNLBL version 3 .RS 0 0x0014 acpi_event version 1 .RS 0 0x0015 thermal_event version 1 .RS 0 0x0016 VFS_DQUOT version 1 .RS 0 0x0017 TASKSTATS version 1 .RS 0 0x0018 NET_DM version 2 .SH AUTHOR .PP Thomas Graf is the original author and current maintainer of libnl and libnl tools. Many people have contributed to it since. libnl-3.2.29/man/nl-classid-lookup.80000644000175000017500000000204213023014600014017 00000000000000.TH nl\-classid\-lookup 8 "19 October 2010" "libnl" .SH NAME nl\-classid\-lookup - Lookup classid definitions .SH SYNOPSIS .B nl\-classid\-lookup .RB [ \-hv ] .RB [ \-r ] .RB [ \-\-raw ] .I name .SH DESCRIPTION .PP nl\-classid\-lookup searches the classid database for a matching entry. It is used to resolve qdisc/class names to classid values and vice versa. .SH OPTIONS .TP .BR \-\^h " or " \-\-help Print help text to console and exit. .TP .BR \-\^v " or " \-\-version Print versioning information to console and exit. .TP .BR \-\^r " or " \-\-reverse Do a reverse lookup. Lookup a classid and print its name. .TP .B \-\-raw Print the raw classid in hexadecimal format, do not pretty print it. .SH USAGE .PP Resolve the qdisc/class name "interactive": .PP .RS # nl\-classid\-lookup interactive .RE .PP Lookup the name of classid 1:2: .PP .RS # nl\-classid\-lookup -r 1:2 .RE .SH FILES .PP /etc/libnl/classid .SH AUTHOR .PP Thomas Graf is the original author and current maintainer of libnl and libnl tools. Many people have contributed to it since. libnl-3.2.29/man/nl-qdisc-list.80000644000175000017500000000003013023014600013135 00000000000000.so man8/nl-qdisc-add.8 libnl-3.2.29/man/Makefile.in0000644000175000017500000003626513031473644012471 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = man ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/lib/defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man8dir = $(mandir)/man8 am__installdirs = "$(DESTDIR)$(man8dir)" NROFF = nroff MANS = $(dist_man8_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_man8_MANS = \ nl-classid-lookup.8 \ nl-pktloc-lookup.8 \ nl-qdisc-add.8 nl-qdisc-delete.8 nl-qdisc-list.8 \ genl-ctrl-list.8 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign man/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man8: $(dist_man8_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man8_MANS)'; \ list2=''; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man8 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man8 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags-am uninstall uninstall-am uninstall-man \ uninstall-man8 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/man/nl-pktloc-lookup.80000644000175000017500000000250413023014600013674 00000000000000.TH nl\-pktloc-lookup 8 "27 October 2010" "libnl" .SH NAME nl\-pktloc\-lookup - Lookup packet location definitions .SH SYNOPSIS .B nl\-pktloc\-lookup .I name .br .B nl\-pktloc\-lookup \-\-list .SH DESCRIPTION .PP nl\-pktloc\-lookup searches the packet location database for a matching entry. It is used to resolve packet location aliases to their definition, i.e. alignment, layer, offset, and mask. .SH OPTIONS .TP .BR \-\^h " or " \-\-help Print help text to console and exit. .TP .BR \-\^v " or " \-\-version Print versioning information to console and exit. .TP .BR \-\^l " or " \-\-list List all packet location definitions. .TP .BR \-\-u32=VALUE Prints the packet location definition in a special format that is understood by iproute2's u32 selector parser. It will output a u32 selector which will compare the provided value with the value specified by the packet location. Please note that due to the limitation of u32, it is not possible to use packet locations based on the link layer. nl-pktloc-lookup will print an error message in this case. Example: selector=$(nl-pktloc-lookup --u32 22 tcp.sport) tc filter add [...] u32 match $(selector) flowid 1:2 .SH FILES .PP /etc/libnl/pktloc .SH AUTHOR .PP Thomas Graf is the original author and current maintainer of libnl and libnl tools. Many people have contributed to it since. libnl-3.2.29/lib/0000755000175000017500000000000013031473756010467 500000000000000libnl-3.2.29/lib/Makefile.am0000644000175000017500000001415713023014600012427 00000000000000# -*- Makefile -*- AM_CPPFLAGS = \ -Wall \ -I${top_srcdir}/include/linux-private \ -I${top_srcdir}/include \ -I${top_builddir}/include \ -I${builddir}/route \ -I${builddir}/route/cls \ -D_GNU_SOURCE \ -DSYSCONFDIR=\"$(sysconfdir)/libnl\" AM_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) lib_LTLIBRARIES = \ libnl-3.la libnl-genl-3.la libnl-route-3.la libnl-nf-3.la libnl-idiag-3.la libnl-xfrm-3.la libnl_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-3.sym libnl_3_la_DEPENDENCIES = \ $(top_srcdir)/libnl-3.sym libnl_3_la_SOURCES = \ addr.c attr.c cache.c cache_mngr.c cache_mngt.c data.c \ error.c handlers.c msg.c nl.c object.c socket.c utils.c \ version.c hash.c hashtable.c libnl_idiag_3_la_LIBADD = libnl-3.la libnl_idiag_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-idiag-3.sym libnl_idiag_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-idiag-3.sym libnl_idiag_3_la_SOURCES = \ idiag/idiag_meminfo_obj.c idiag/idiag_vegasinfo_obj.c \ idiag/idiag_msg_obj.c idiag/idiag_req_obj.c idiag/idiag.c libnl_genl_3_la_LIBADD = libnl-3.la libnl_genl_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-genl-3.sym libnl_genl_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-genl-3.sym libnl_genl_3_la_SOURCES = \ genl/ctrl.c genl/family.c genl/genl.c genl/mngt.c libnl_nf_3_la_LIBADD = libnl-route-3.la libnl_nf_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-nf-3.sym libnl_nf_3_la_DEPENDENCIES = \ libnl-route-3.la \ $(top_srcdir)/libnl-nf-3.sym libnl_nf_3_la_SOURCES = \ netfilter/ct.c netfilter/ct_obj.c netfilter/log.c \ netfilter/log_msg.c netfilter/log_msg_obj.c netfilter/log_obj.c \ netfilter/netfilter.c netfilter/nfnl.c netfilter/queue.c \ netfilter/queue_msg.c netfilter/queue_msg_obj.c netfilter/queue_obj.c \ netfilter/exp.c netfilter/exp_obj.c CLEANFILES = \ route/pktloc_grammar.c route/pktloc_grammar.h \ route/pktloc_syntax.c route/pktloc_syntax.h \ route/cls/ematch_grammar.c route/cls/ematch_grammar.h \ route/cls/ematch_syntax.c route/cls/ematch_syntax.h # Hack to avoid using ylwrap. It does not function correctly in combination # with --header-file= route/pktloc_grammar.c: route/pktloc_grammar.l $(AM_V_GEN) $(MKDIR_P) route; $(FLEX) --header-file=route/pktloc_grammar.h $(LFLAGS) -o $@ $^ route/pktloc_syntax.c: route/pktloc_syntax.y $(AM_V_GEN) $(MKDIR_P) route; $(YACC) -d $(YFLAGS) -o $@ $^ route/cls/ematch_grammar.c: route/cls/ematch_grammar.l $(AM_V_GEN) $(MKDIR_P) route/cls; $(FLEX) --header-file=route/cls/ematch_grammar.h $(LFLAGS) -o $@ $^ route/cls/ematch_syntax.c: route/cls/ematch_syntax.y $(AM_V_GEN) $(MKDIR_P) route/cls; $(YACC) -d $(YFLAGS) -o $@ $^ libnl_route_3_la_LIBADD = libnl-3.la libnl_route_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-route-3.sym libnl_route_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-route-3.sym libnl_route_3_la_SOURCES = \ route/addr.c route/class.c route/cls.c route/act.c route/link.c \ route/neigh.c route/neightbl.c route/nexthop.c route/qdisc.c \ route/route.c route/route_obj.c route/route_utils.c route/rtnl.c \ route/rule.c route/tc.c route/classid.c route/link/sriov.c \ \ route/cls/fw.c route/cls/police.c route/cls/u32.c route/cls/basic.c \ route/cls/cgroup.c \ \ route/act/mirred.c \ route/act/skbedit.c \ route/act/gact.c \ \ route/cls/ematch.c \ route/cls/ematch/container.c route/cls/ematch/cmp.c \ route/cls/ematch/nbyte.c route/cls/ematch/text.c \ route/cls/ematch/meta.c \ \ route/link/api.c route/link/vlan.c route/link/dummy.c \ route/link/bridge.c route/link/inet6.c route/link/inet.c \ route/link/bonding.c route/link/can.c route/link/macvlan.c \ route/link/vxlan.c route/link/veth.c route/link/ipip.c \ route/link/ipgre.c route/link/sit.c route/link/ipvti.c \ route/link/ip6tnl.c route/link/ifb.c route/link/ipvlan.c \ route/link/vrf.c route/link/macsec.c route/link/ppp.c \ \ route/qdisc/blackhole.c route/qdisc/cbq.c route/qdisc/dsmark.c \ route/qdisc/fifo.c route/qdisc/htb.c route/qdisc/netem.c \ route/qdisc/prio.c route/qdisc/red.c route/qdisc/sfq.c \ route/qdisc/tbf.c route/qdisc/plug.c route/qdisc/ingress.c \ route/qdisc/fq_codel.c route/qdisc/hfsc.c \ \ fib_lookup/lookup.c fib_lookup/request.c \ \ route/pktloc.c nodist_libnl_route_3_la_SOURCES = \ route/pktloc_syntax.c route/pktloc_syntax.h \ route/pktloc_grammar.c route/pktloc_grammar.h \ route/cls/ematch_syntax.c route/cls/ematch_syntax.h \ route/cls/ematch_grammar.c route/cls/ematch_grammar.h BUILT_SOURCES = \ route/cls/ematch_grammar.c \ route/cls/ematch_syntax.c \ route/pktloc_grammar.c \ route/pktloc_syntax.c EXTRA_DIST = \ route/pktloc_grammar.l \ route/pktloc_syntax.y \ route/cls/ematch_grammar.l \ route/cls/ematch_syntax.y libnl_xfrm_3_la_LIBADD = libnl-3.la libnl_xfrm_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-xfrm-3.sym libnl_xfrm_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-xfrm-3.sym libnl_xfrm_3_la_SOURCES = \ xfrm/ae.c \ xfrm/lifetime.c \ xfrm/sa.c \ xfrm/selector.c \ xfrm/sp.c \ xfrm/template.c if ENABLE_CLI nobase_pkglib_LTLIBRARIES = \ cli/qdisc/htb.la \ cli/qdisc/blackhole.la \ cli/qdisc/pfifo.la \ cli/qdisc/plug.la \ cli/qdisc/bfifo.la \ cli/qdisc/ingress.la \ cli/qdisc/fq_codel.la \ cli/qdisc/hfsc.la \ cli/cls/basic.la \ cli/cls/cgroup.la cli_qdisc_htb_la_LDFLAGS = -module -avoid-version cli_qdisc_blackhole_la_LDFLAGS = -module -avoid-version cli_qdisc_pfifo_la_LDFLAGS = -module -avoid-version cli_qdisc_plug_la_LDFLAGS = -module -avoid-version cli_qdisc_bfifo_la_LDFLAGS = -module -avoid-version cli_qdisc_ingress_la_LDFLAGS = -module -avoid-version cli_qdisc_fq_codel_la_LDFLAGS = -module -avoid-version cli_qdisc_hfsc_la_LDFLAGS = -module -avoid-version cli_cls_basic_la_LDFLAGS = -module -avoid-version cli_cls_cgroup_la_LDFLAGS = -module -avoid-version endif libnl-3.2.29/lib/handlers.c0000644000175000017500000002027313023014600012333 00000000000000/* * lib/handlers.c default netlink message handlers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup core * @defgroup cb Callbacks/Customization * * Related sections in the development guide: * - @core_doc{core_cb, Callback Configuration} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include #include #include static void print_header_content(FILE *ofd, struct nlmsghdr *n) { char flags[128]; char type[32]; fprintf(ofd, "type=%s length=%u flags=<%s> sequence-nr=%u pid=%u", nl_nlmsgtype2str(n->nlmsg_type, type, sizeof(type)), n->nlmsg_len, nl_nlmsg_flags2str(n->nlmsg_flags, flags, sizeof(flags)), n->nlmsg_seq, n->nlmsg_pid); } static int nl_valid_handler_verbose(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stdout; fprintf(ofd, "-- Warning: unhandled valid message: "); print_header_content(ofd, nlmsg_hdr(msg)); fprintf(ofd, "\n"); return NL_OK; } static int nl_invalid_handler_verbose(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Error: Invalid message: "); print_header_content(ofd, nlmsg_hdr(msg)); fprintf(ofd, "\n"); return NL_STOP; } static int nl_overrun_handler_verbose(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Error: Netlink Overrun: "); print_header_content(ofd, nlmsg_hdr(msg)); fprintf(ofd, "\n"); return NL_STOP; } static int nl_error_handler_verbose(struct sockaddr_nl *who, struct nlmsgerr *e, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Error received: %s\n-- Original message: ", nl_strerror_l(-e->error)); print_header_content(ofd, &e->msg); fprintf(ofd, "\n"); return -nl_syserr2nlerr(e->error); } static int nl_valid_handler_debug(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Debug: Unhandled Valid message: "); print_header_content(ofd, nlmsg_hdr(msg)); fprintf(ofd, "\n"); return NL_OK; } static int nl_finish_handler_debug(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Debug: End of multipart message block: "); print_header_content(ofd, nlmsg_hdr(msg)); fprintf(ofd, "\n"); return NL_STOP; } static int nl_msg_in_handler_debug(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Debug: Received Message:\n"); nl_msg_dump(msg, ofd); return NL_OK; } static int nl_msg_out_handler_debug(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Debug: Sent Message:\n"); nl_msg_dump(msg, ofd); return NL_OK; } static int nl_skipped_handler_debug(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Debug: Skipped message: "); print_header_content(ofd, nlmsg_hdr(msg)); fprintf(ofd, "\n"); return NL_SKIP; } static int nl_ack_handler_debug(struct nl_msg *msg, void *arg) { FILE *ofd = arg ? arg : stderr; fprintf(ofd, "-- Debug: ACK: "); print_header_content(ofd, nlmsg_hdr(msg)); fprintf(ofd, "\n"); return NL_STOP; } static nl_recvmsg_msg_cb_t cb_def[NL_CB_TYPE_MAX+1][NL_CB_KIND_MAX+1] = { [NL_CB_VALID] = { [NL_CB_VERBOSE] = nl_valid_handler_verbose, [NL_CB_DEBUG] = nl_valid_handler_debug, }, [NL_CB_FINISH] = { [NL_CB_DEBUG] = nl_finish_handler_debug, }, [NL_CB_INVALID] = { [NL_CB_VERBOSE] = nl_invalid_handler_verbose, [NL_CB_DEBUG] = nl_invalid_handler_verbose, }, [NL_CB_MSG_IN] = { [NL_CB_DEBUG] = nl_msg_in_handler_debug, }, [NL_CB_MSG_OUT] = { [NL_CB_DEBUG] = nl_msg_out_handler_debug, }, [NL_CB_OVERRUN] = { [NL_CB_VERBOSE] = nl_overrun_handler_verbose, [NL_CB_DEBUG] = nl_overrun_handler_verbose, }, [NL_CB_SKIPPED] = { [NL_CB_DEBUG] = nl_skipped_handler_debug, }, [NL_CB_ACK] = { [NL_CB_DEBUG] = nl_ack_handler_debug, }, }; static nl_recvmsg_err_cb_t cb_err_def[NL_CB_KIND_MAX+1] = { [NL_CB_VERBOSE] = nl_error_handler_verbose, [NL_CB_DEBUG] = nl_error_handler_verbose, }; /** * @name Callback Handle Management * @{ */ /** * Allocate a new callback handle * @arg kind callback kind to be used for initialization * @return Newly allocated callback handle or NULL */ struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind) { int i; struct nl_cb *cb; if ((unsigned int) kind > NL_CB_KIND_MAX) return NULL; cb = calloc(1, sizeof(*cb)); if (!cb) return NULL; cb->cb_refcnt = 1; cb->cb_active = NL_CB_TYPE_MAX + 1; for (i = 0; i <= NL_CB_TYPE_MAX; i++) nl_cb_set(cb, i, kind, NULL, NULL); nl_cb_err(cb, kind, NULL, NULL); return cb; } /** * Clone an existing callback handle * @arg orig original callback handle * @return Newly allocated callback handle being a duplicate of * orig or NULL */ struct nl_cb *nl_cb_clone(struct nl_cb *orig) { struct nl_cb *cb; cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) return NULL; memcpy(cb, orig, sizeof(*orig)); cb->cb_refcnt = 1; return cb; } struct nl_cb *nl_cb_get(struct nl_cb *cb) { cb->cb_refcnt++; return cb; } void nl_cb_put(struct nl_cb *cb) { if (!cb) return; cb->cb_refcnt--; if (cb->cb_refcnt < 0) BUG(); if (cb->cb_refcnt <= 0) free(cb); } /** * Obtain type of current active callback * @arg cb callback to query * * @return type or __NL_CB_TYPE_MAX if none active */ enum nl_cb_type nl_cb_active_type(struct nl_cb *cb) { return cb->cb_active; } /** @} */ /** * @name Callback Setup * @{ */ /** * Set up a callback * @arg cb callback set * @arg type callback to modify * @arg kind kind of implementation * @arg func callback function (NL_CB_CUSTOM) * @arg arg argument passed to callback * * @return 0 on success or a negative error code */ int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg) { if ((unsigned int) type > NL_CB_TYPE_MAX) return -NLE_RANGE; if ((unsigned int) kind > NL_CB_KIND_MAX) return -NLE_RANGE; if (kind == NL_CB_CUSTOM) { cb->cb_set[type] = func; cb->cb_args[type] = arg; } else { cb->cb_set[type] = cb_def[type][kind]; cb->cb_args[type] = arg; } return 0; } /** * Set up a all callbacks * @arg cb callback set * @arg kind kind of callback * @arg func callback function * @arg arg argument to be passwd to callback function * * @return 0 on success or a negative error code */ int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg) { int i, err; for (i = 0; i <= NL_CB_TYPE_MAX; i++) { err = nl_cb_set(cb, i, kind, func, arg); if (err < 0) return err; } return 0; } /** * Set up an error callback * @arg cb callback set * @arg kind kind of callback * @arg func callback function * @arg arg argument to be passed to callback function */ int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, nl_recvmsg_err_cb_t func, void *arg) { if ((unsigned int) kind > NL_CB_KIND_MAX) return -NLE_RANGE; if (kind == NL_CB_CUSTOM) { cb->cb_err = func; cb->cb_err_arg = arg; } else { cb->cb_err = cb_err_def[kind]; cb->cb_err_arg = arg; } return 0; } /** @} */ /** * @name Overwriting * @{ */ /** * Overwrite internal calls to nl_recvmsgs() * @arg cb callback set * @arg func replacement callback for nl_recvmsgs() */ void nl_cb_overwrite_recvmsgs(struct nl_cb *cb, int (*func)(struct nl_sock *, struct nl_cb *)) { cb->cb_recvmsgs_ow = func; } /** * Overwrite internal calls to nl_recv() * @arg cb callback set * @arg func replacement callback for nl_recv() */ void nl_cb_overwrite_recv(struct nl_cb *cb, int (*func)(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **)) { cb->cb_recv_ow = func; } /** * Overwrite internal calls to nl_send() * @arg cb callback set * @arg func replacement callback for nl_send() */ void nl_cb_overwrite_send(struct nl_cb *cb, int (*func)(struct nl_sock *, struct nl_msg *)) { cb->cb_send_ow = func; } /** @} */ /** @} */ libnl-3.2.29/lib/cache_mngr.c0000644000175000017500000004252013023014600012620 00000000000000/* * lib/cache_mngr.c Cache Manager * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup cache_mngt * @defgroup cache_mngr Manager * @brief Manager keeping caches up to date automatically. * * The cache manager keeps caches up to date automatically by listening to * netlink notifications and integrating the received information into the * existing cache. * * @note This functionality is still considered experimental. * * Related sections in the development guide: * - @core_doc{_cache_manager,Cache Manager} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include #include /** @cond SKIP */ #define NASSOC_INIT 16 #define NASSOC_EXPAND 8 /** @endcond */ static int include_cb(struct nl_object *obj, struct nl_parser_param *p) { struct nl_cache_assoc *ca = p->pp_arg; struct nl_cache_ops *ops = ca->ca_cache->c_ops; NL_DBG(2, "Including object %p into cache %p\n", obj, ca->ca_cache); #ifdef NL_DEBUG if (nl_debug >= 4) nl_object_dump(obj, &nl_debug_dp); #endif if (ops->co_event_filter) if (ops->co_event_filter(ca->ca_cache, obj) != NL_OK) return 0; if (ops->co_include_event) return ops->co_include_event(ca->ca_cache, obj, ca->ca_change, ca->ca_change_v2, ca->ca_change_data); else { if (ca->ca_change_v2) return nl_cache_include_v2(ca->ca_cache, obj, ca->ca_change_v2, ca->ca_change_data); else return nl_cache_include(ca->ca_cache, obj, ca->ca_change, ca->ca_change_data); } } static int event_input(struct nl_msg *msg, void *arg) { struct nl_cache_mngr *mngr = arg; int protocol = nlmsg_get_proto(msg); int type = nlmsg_hdr(msg)->nlmsg_type; struct nl_cache_ops *ops; int i, n; struct nl_parser_param p = { .pp_cb = include_cb, }; NL_DBG(2, "Cache manager %p, handling new message %p as event\n", mngr, msg); #ifdef NL_DEBUG if (nl_debug >= 4) nl_msg_dump(msg, stderr); #endif if (mngr->cm_protocol != protocol) BUG(); for (i = 0; i < mngr->cm_nassocs; i++) { if (mngr->cm_assocs[i].ca_cache) { ops = mngr->cm_assocs[i].ca_cache->c_ops; for (n = 0; ops->co_msgtypes[n].mt_id >= 0; n++) if (ops->co_msgtypes[n].mt_id == type) goto found; } } return NL_SKIP; found: NL_DBG(2, "Associated message %p to cache %p\n", msg, mngr->cm_assocs[i].ca_cache); p.pp_arg = &mngr->cm_assocs[i]; return nl_cache_parse(ops, NULL, nlmsg_hdr(msg), &p); } /** * Allocate new cache manager * @arg sk Netlink socket or NULL to auto allocate * @arg protocol Netlink protocol this manager is used for * @arg flags Flags (\c NL_AUTO_PROVIDE) * @arg result Result pointer * * Allocates a new cache manager for the specified netlink protocol. * * 1. If sk is not specified (\c NULL) a netlink socket matching the * specified protocol will be automatically allocated. * * 2. The socket will be put in non-blocking mode and sequence checking * will be disabled regardless of whether the socket was provided by * the caller or automatically allocated. * * 3. The socket will be connected. * * If the flag \c NL_AUTO_PROVIDE is specified, any cache added to the * manager will automatically be made available to other users using * nl_cache_mngt_provide(). * * @note If the socket is provided by the caller, it is NOT recommended * to use the socket for anything else besides receiving netlink * notifications. * * @return 0 on success or a negative error code. */ int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags, struct nl_cache_mngr **result) { struct nl_cache_mngr *mngr; int err = -NLE_NOMEM; /* Catch abuse of flags */ if (flags & NL_ALLOCATED_SOCK) BUG(); mngr = calloc(1, sizeof(*mngr)); if (!mngr) return -NLE_NOMEM; if (!sk) { if (!(sk = nl_socket_alloc())) goto errout; flags |= NL_ALLOCATED_SOCK; } mngr->cm_sock = sk; mngr->cm_nassocs = NASSOC_INIT; mngr->cm_protocol = protocol; mngr->cm_flags = flags; mngr->cm_assocs = calloc(mngr->cm_nassocs, sizeof(struct nl_cache_assoc)); if (!mngr->cm_assocs) goto errout; /* Required to receive async event notifications */ nl_socket_disable_seq_check(mngr->cm_sock); if ((err = nl_connect(mngr->cm_sock, protocol)) < 0) goto errout; if ((err = nl_socket_set_nonblocking(mngr->cm_sock)) < 0) goto errout; /* Create and allocate socket for sync cache fills */ mngr->cm_sync_sock = nl_socket_alloc(); if (!mngr->cm_sync_sock) { err = -NLE_NOMEM; goto errout; } if ((err = nl_connect(mngr->cm_sync_sock, protocol)) < 0) goto errout_free_sync_sock; NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n", mngr, protocol, mngr->cm_nassocs); *result = mngr; return 0; errout_free_sync_sock: nl_socket_free(mngr->cm_sync_sock); errout: nl_cache_mngr_free(mngr); return err; } /** * Set change_func_v2 for cache manager * @arg mngr Cache manager. * @arg cache Cache associated with the callback * @arg cb Function to be called upon changes. * @arg data Argument passed on to change callback * * Adds callback change_func_v2 to a registered cache. This callback provides * in like the standard change_func the added or remove netlink object. In case * of a change the old and the new object is provided as well as the according * diff. If this callback is registered this has a higher priority then the * change_func registered during cache registration. Hence only one callback is * executed. * * The first netlink object in the callback is refering to the old object and * the second to the new. This means on NL_ACT_CHANGE the first is the previous * object in the cache and the second the updated version. On NL_ACT_DEL the * first is the deleted object the second is NULL. On NL_ACT_NEW the first is * NULL and the second the new netlink object. * * The user is responsible for calling nl_cache_mngr_poll() or monitor * the socket and call nl_cache_mngr_data_ready() to allow the library * to process netlink notification events. * * @see nl_cache_mngr_poll() * @see nl_cache_mngr_data_ready() * * @return 0 on success or a negative error code. * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and * cache type * @return -NLE_OPNOTSUPP Cache type does not support updates * @return -NLE_RANGE Cache of this type is not registered */ static int nl_cache_mngr_set_change_func_v2(struct nl_cache_mngr *mngr, struct nl_cache *cache, change_func_v2_t cb, void *data) { struct nl_cache_ops *ops; int i; ops = cache->c_ops; if (!ops) return -NLE_INVAL; if (ops->co_protocol != mngr->cm_protocol) return -NLE_PROTO_MISMATCH; if (ops->co_groups == NULL) return -NLE_OPNOTSUPP; for (i = 0; i < mngr->cm_nassocs; i++) if (mngr->cm_assocs[i].ca_cache == cache) break; if (i >= mngr->cm_nassocs) { return -NLE_RANGE; } mngr->cm_assocs[i].ca_change_v2 = cb; mngr->cm_assocs[i].ca_change_data = data; return 0; } /** * Add cache to cache manager * @arg mngr Cache manager. * @arg cache Cache to be added to cache manager * @arg cb Function to be called upon changes. * @arg data Argument passed on to change callback * * Adds cache to the manager. The operation will trigger a full * dump request from the kernel to initially fill the contents * of the cache. The manager will subscribe to the notification group * of the cache and keep track of any further changes. * * The user is responsible for calling nl_cache_mngr_poll() or monitor * the socket and call nl_cache_mngr_data_ready() to allow the library * to process netlink notification events. * * @see nl_cache_mngr_poll() * @see nl_cache_mngr_data_ready() * * @return 0 on success or a negative error code. * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and * cache type * @return -NLE_OPNOTSUPP Cache type does not support updates * @return -NLE_EXIST Cache of this type already being managed */ int nl_cache_mngr_add_cache(struct nl_cache_mngr *mngr, struct nl_cache *cache, change_func_t cb, void *data) { struct nl_cache_ops *ops; struct nl_af_group *grp; int err, i; ops = cache->c_ops; if (!ops) return -NLE_INVAL; if (ops->co_protocol != mngr->cm_protocol) return -NLE_PROTO_MISMATCH; if (ops->co_groups == NULL) return -NLE_OPNOTSUPP; for (i = 0; i < mngr->cm_nassocs; i++) if (mngr->cm_assocs[i].ca_cache && mngr->cm_assocs[i].ca_cache->c_ops == ops) return -NLE_EXIST; retry: for (i = 0; i < mngr->cm_nassocs; i++) if (!mngr->cm_assocs[i].ca_cache) break; if (i >= mngr->cm_nassocs) { mngr->cm_nassocs += NASSOC_EXPAND; mngr->cm_assocs = realloc(mngr->cm_assocs, mngr->cm_nassocs * sizeof(struct nl_cache_assoc)); if (mngr->cm_assocs == NULL) return -NLE_NOMEM; memset(mngr->cm_assocs + (mngr->cm_nassocs - NASSOC_EXPAND), 0, NASSOC_EXPAND * sizeof(struct nl_cache_assoc)); NL_DBG(1, "Increased capacity of cache manager %p " \ "to %d\n", mngr, mngr->cm_nassocs); goto retry; } for (grp = ops->co_groups; grp->ag_group; grp++) { err = nl_socket_add_membership(mngr->cm_sock, grp->ag_group); if (err < 0) return err; } err = nl_cache_refill(mngr->cm_sync_sock, cache); if (err < 0) goto errout_drop_membership; mngr->cm_assocs[i].ca_cache = cache; mngr->cm_assocs[i].ca_change = cb; mngr->cm_assocs[i].ca_change_data = data; if (mngr->cm_flags & NL_AUTO_PROVIDE) nl_cache_mngt_provide(cache); NL_DBG(1, "Added cache %p <%s> to cache manager %p\n", cache, nl_cache_name(cache), mngr); return 0; errout_drop_membership: for (grp = ops->co_groups; grp->ag_group; grp++) nl_socket_drop_membership(mngr->cm_sock, grp->ag_group); return err; } /** * Add cache to cache manager * @arg mngr Cache manager. * @arg cache Cache to be added to cache manager * @arg cb V2 function to be called upon changes. * @arg data Argument passed on to change callback * * Adds cache to the manager. The operation will trigger a full * dump request from the kernel to initially fill the contents * of the cache. The manager will subscribe to the notification group * of the cache and keep track of any further changes. * * The user is responsible for calling nl_cache_mngr_poll() or monitor * the socket and call nl_cache_mngr_data_ready() to allow the library * to process netlink notification events. * * @see nl_cache_mngr_poll() * @see nl_cache_mngr_data_ready() * * @return 0 on success or a negative error code. * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and * cache type * @return -NLE_OPNOTSUPP Cache type does not support updates * @return -NLE_EXIST Cache of this type already being managed */ int nl_cache_mngr_add_cache_v2(struct nl_cache_mngr *mngr, struct nl_cache *cache, change_func_v2_t cb, void *data) { int err; err = nl_cache_mngr_add_cache(mngr, cache, NULL, NULL); if (err < 0) return err; return nl_cache_mngr_set_change_func_v2(mngr, cache, cb, data); } /** * Add cache to cache manager * @arg mngr Cache manager. * @arg name Name of cache to keep track of * @arg cb Function to be called upon changes. * @arg data Argument passed on to change callback * @arg result Pointer to store added cache (optional) * * Allocates a new cache of the specified type and adds it to the manager. * The operation will trigger a full dump request from the kernel to * initially fill the contents of the cache. The manager will subscribe * to the notification group of the cache and keep track of any further * changes. * * The user is responsible for calling nl_cache_mngr_poll() or monitor * the socket and call nl_cache_mngr_data_ready() to allow the library * to process netlink notification events. * * @see nl_cache_mngr_poll() * @see nl_cache_mngr_data_ready() * * @return 0 on success or a negative error code. * @return -NLE_NOCACHE Unknown cache type * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and * cache type * @return -NLE_OPNOTSUPP Cache type does not support updates * @return -NLE_EXIST Cache of this type already being managed */ int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name, change_func_t cb, void *data, struct nl_cache **result) { struct nl_cache_ops *ops; struct nl_cache *cache; int err; ops = nl_cache_ops_lookup_safe(name); if (!ops) return -NLE_NOCACHE; cache = nl_cache_alloc(ops); nl_cache_ops_put(ops); if (!cache) return -NLE_NOMEM; err = nl_cache_mngr_add_cache(mngr, cache, cb, data); if (err < 0) goto errout_free_cache; *result = cache; return 0; errout_free_cache: nl_cache_free(cache); return err; } /** * Get socket file descriptor * @arg mngr Cache Manager * * Get the file descriptor of the socket associated with the manager. * * @note Do not use the socket for anything besides receiving * notifications. */ int nl_cache_mngr_get_fd(struct nl_cache_mngr *mngr) { return nl_socket_get_fd(mngr->cm_sock); } /** * Check for event notifications * @arg mngr Cache Manager * @arg timeout Upper limit poll() will block, in milliseconds. * * Causes poll() to be called to check for new event notifications * being available. Calls nl_cache_mngr_data_ready() to process * available data. * * This functionally is ideally called regularly during an idle * period. * * A timeout can be specified in milliseconds to limit the time the * function will wait for updates. * * @see nl_cache_mngr_data_ready() * * @return The number of messages processed or a negative error code. */ int nl_cache_mngr_poll(struct nl_cache_mngr *mngr, int timeout) { int ret; struct pollfd fds = { .fd = nl_socket_get_fd(mngr->cm_sock), .events = POLLIN, }; NL_DBG(3, "Cache manager %p, poll() fd %d\n", mngr, fds.fd); ret = poll(&fds, 1, timeout); NL_DBG(3, "Cache manager %p, poll() returned %d\n", mngr, ret); if (ret < 0) { NL_DBG(4, "nl_cache_mngr_poll(%p): poll() failed with %d (%s)\n", mngr, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } /* No events, return */ if (ret == 0) return 0; return nl_cache_mngr_data_ready(mngr); } /** * Receive available event notifications * @arg mngr Cache manager * * This function can be called if the socket associated to the manager * contains updates to be received. This function should only be used * if nl_cache_mngr_poll() is not used. * * The function will process messages until there is no more data to * be read from the socket. * * @see nl_cache_mngr_poll() * * @return The number of messages processed or a negative error code. */ int nl_cache_mngr_data_ready(struct nl_cache_mngr *mngr) { int err, nread = 0; struct nl_cb *cb; NL_DBG(2, "Cache manager %p, reading new data from fd %d\n", mngr, nl_socket_get_fd(mngr->cm_sock)); cb = nl_cb_clone(mngr->cm_sock->s_cb); if (cb == NULL) return -NLE_NOMEM; nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, event_input, mngr); while ((err = nl_recvmsgs_report(mngr->cm_sock, cb)) > 0) { NL_DBG(2, "Cache manager %p, recvmsgs read %d messages\n", mngr, err); nread += err; } nl_cb_put(cb); if (err < 0 && err != -NLE_AGAIN) return err; return nread; } /** * Print information about cache manager * @arg mngr Cache manager * @arg p Dumping parameters * * Prints information about the cache manager including all managed caches. * * @note This is a debugging function. */ void nl_cache_mngr_info(struct nl_cache_mngr *mngr, struct nl_dump_params *p) { char buf[128]; int i; nl_dump_line(p, "cache-manager <%p>\n", mngr); nl_dump_line(p, " .protocol = %s\n", nl_nlfamily2str(mngr->cm_protocol, buf, sizeof(buf))); nl_dump_line(p, " .flags = %#x\n", mngr->cm_flags); nl_dump_line(p, " .nassocs = %u\n", mngr->cm_nassocs); nl_dump_line(p, " .sock = <%p>\n", mngr->cm_sock); for (i = 0; i < mngr->cm_nassocs; i++) { struct nl_cache_assoc *assoc = &mngr->cm_assocs[i]; if (assoc->ca_cache) { nl_dump_line(p, " .cache[%d] = <%p> {\n", i, assoc->ca_cache); nl_dump_line(p, " .name = %s\n", assoc->ca_cache->c_ops->co_name); nl_dump_line(p, " .change_func = <%p>\n", assoc->ca_change); nl_dump_line(p, " .change_data = <%p>\n", assoc->ca_change_data); nl_dump_line(p, " .nitems = %u\n", nl_cache_nitems(assoc->ca_cache)); nl_dump_line(p, " .objects = {\n"); p->dp_prefix += 6; nl_cache_dump(assoc->ca_cache, p); p->dp_prefix -= 6; nl_dump_line(p, " }\n"); nl_dump_line(p, " }\n"); } } } /** * Free cache manager and all caches. * @arg mngr Cache manager. * * Release all resources held by a cache manager. */ void nl_cache_mngr_free(struct nl_cache_mngr *mngr) { int i; if (!mngr) return; if (mngr->cm_sock) nl_close(mngr->cm_sock); if (mngr->cm_sync_sock) { nl_close(mngr->cm_sync_sock); nl_socket_free(mngr->cm_sync_sock); } if (mngr->cm_flags & NL_ALLOCATED_SOCK) nl_socket_free(mngr->cm_sock); for (i = 0; i < mngr->cm_nassocs; i++) { if (mngr->cm_assocs[i].ca_cache) { nl_cache_mngt_unprovide(mngr->cm_assocs[i].ca_cache); nl_cache_free(mngr->cm_assocs[i].ca_cache); } } free(mngr->cm_assocs); NL_DBG(1, "Cache manager %p freed\n", mngr); free(mngr); } /** @} */ libnl-3.2.29/lib/cli/0000755000175000017500000000000013031473756011236 500000000000000libnl-3.2.29/lib/cli/cls/0000755000175000017500000000000013031473756012017 500000000000000libnl-3.2.29/lib/cli/cls/cgroup.c0000644000175000017500000000311313023014600013354 00000000000000/* * lib/cli/cls/cgroup.c cgroup classifier module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ #include #include #include #include static void print_usage(void) { printf( "Usage: nl-cls-add [...] cgroup [OPTIONS]...\n" "\n" "OPTIONS\n" " -h, --help Show this help text.\n" " -e, --ematch=EXPR Ematch expression\n" "\n" "EXAMPLE" " nl-cls-add --dev=eth0 --parent=q_root cgroup\n"); } static void parse_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_cls *cls = (struct rtnl_cls *) tc; struct rtnl_ematch_tree *tree; for (;;) { int c, optidx = 0; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "ematch", 1, 0, 'e' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "he:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); exit(0); case 'e': tree = nl_cli_cls_parse_ematch(cls, optarg); rtnl_cgroup_set_ematch(cls, tree); break; } } } static struct nl_cli_tc_module cgroup_module = { .tm_name = "cgroup", .tm_type = RTNL_TC_TYPE_CLS, .tm_parse_argv = parse_argv, }; static void __init cgroup_init(void) { nl_cli_tc_register(&cgroup_module); } static void __exit cgroup_exit(void) { nl_cli_tc_unregister(&cgroup_module); } libnl-3.2.29/lib/cli/cls/basic.c0000644000175000017500000000415413023014600013144 00000000000000/* * lib/cli/cls/basic.c basic classifier module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ #include #include #include #include static void print_usage(void) { printf( "Usage: nl-cls-add [...] basic [OPTIONS]...\n" "\n" "OPTIONS\n" " -h, --help Show this help text.\n" " -t, --target=ID Target class to send matching packets to\n" " -e, --ematch=EXPR Ematch expression\n" "\n" "EXAMPLE" " # Create a \"catch-all\" classifier, attached to \"q_root\", classyfing\n" " # all not yet classified packets to class \"c_default\"\n" " nl-cls-add --dev=eth0 --parent=q_root basic --target=c_default\n"); } static void parse_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_cls *cls = (struct rtnl_cls *) tc; struct rtnl_ematch_tree *tree; uint32_t target; int err; for (;;) { int c, optidx = 0; enum { ARG_TARGET = 257, ARG_DEFAULT = 258, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "target", 1, 0, 't' }, { "ematch", 1, 0, 'e' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "ht:e:", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); exit(0); case 't': if ((err = rtnl_tc_str2handle(optarg, &target)) < 0) nl_cli_fatal(err, "Unable to parse target \"%s\":", optarg, nl_geterror(err)); rtnl_basic_set_target(cls, target); break; case 'e': tree = nl_cli_cls_parse_ematch(cls, optarg); rtnl_basic_set_ematch(cls, tree); break; } } } static struct nl_cli_tc_module basic_module = { .tm_name = "basic", .tm_type = RTNL_TC_TYPE_CLS, .tm_parse_argv = parse_argv, }; static void __init basic_init(void) { nl_cli_tc_register(&basic_module); } static void __exit basic_exit(void) { nl_cli_tc_unregister(&basic_module); } libnl-3.2.29/lib/cli/qdisc/0000755000175000017500000000000013031473756012341 500000000000000libnl-3.2.29/lib/cli/qdisc/hfsc.c0000644000175000017500000001201613023014600013324 00000000000000/* * lib/cli/qdisc/hfsc.c HFSC module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Cong Wang */ #include #include #include static void print_qdisc_usage(void) { printf( "Usage: nl-qdisc-add [...] hfsc [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --default=ID Default class for unclassified traffic.\n" "\n" "EXAMPLE" " # Create hfsc root qdisc 1: and direct unclassified traffic to class 1:10\n" " nl-qdisc-add --dev=eth1 --parent=root --handle=1: hfsc --default=10\n"); } static void hfsc_parse_qdisc_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; for (;;) { int c, optidx = 0; enum { ARG_DEFAULT = 257, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "default", 1, 0, ARG_DEFAULT }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hv", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_qdisc_usage(); return; case ARG_DEFAULT: rtnl_qdisc_hfsc_set_defcls(qdisc, nl_cli_parse_u32(optarg)); break; } } } static void print_class_usage(void) { printf( "Usage: nl-class-add [...] hfsc [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --ls=SC Link-sharing service curve\n" " --rt=SC Real-time service curve\n" " --sc=SC Specifiy both of the above\n" " --ul=SC Upper limit\n" " where SC := [ [ m1 bits ] d usec ] m2 bits\n" "\n" "EXAMPLE" " # Attach class 1:1 to hfsc qdisc 1: and use rt and ls curve\n" " nl-class-add --dev=eth1 --parent=1: --classid=1:1 hfsc --sc=m1:250,d:8,m2:100\n"); } static int hfsc_get_sc(char *optarg, struct tc_service_curve *sc) { unsigned int m1 = 0, d = 0, m2 = 0; char *tmp = strdup(optarg); char *p, *endptr; char *pp = tmp; if (!tmp) return -ENOMEM; p = strstr(pp, "m1:"); if (p) { char *q; p += 3; if (*p == 0) goto err; q = strchr(p, ','); if (!q) goto err; *q = 0; m1 = strtoul(p, &endptr, 10); if (endptr == p) goto err; pp = q + 1; } p = strstr(pp, "d:"); if (p) { char *q; p += 2; if (*p == 0) goto err; q = strchr(p, ','); if (!q) goto err; *q = 0; d = strtoul(p, &endptr, 10); if (endptr == p) goto err; pp = q + 1; } p = strstr(pp, "m2:"); if (p) { p += 3; if (*p == 0) goto err; m2 = strtoul(p, &endptr, 10); if (endptr == p) goto err; } else goto err; free(tmp); sc->m1 = m1; sc->d = d; sc->m2 = m2; return 0; err: free(tmp); return -EINVAL; } static void hfsc_parse_class_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_class *class = (struct rtnl_class *) tc; int arg_ok = 0, ret = -EINVAL; for (;;) { int c, optidx = 0; enum { ARG_RT = 257, ARG_LS = 258, ARG_SC, ARG_UL, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "rt", 1, 0, ARG_RT }, { "ls", 1, 0, ARG_LS }, { "sc", 1, 0, ARG_SC }, { "ul", 1, 0, ARG_UL }, { 0, 0, 0, 0 } }; struct tc_service_curve tsc; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_class_usage(); return; case ARG_RT: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_rsc(class, &tsc); arg_ok++; break; case ARG_LS: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_fsc(class, &tsc); arg_ok++; break; case ARG_SC: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_rsc(class, &tsc); rtnl_class_hfsc_set_fsc(class, &tsc); arg_ok++; break; case ARG_UL: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_usc(class, &tsc); arg_ok++; break; } } if (!arg_ok) nl_cli_fatal(ret, "Invalid arguments"); } static struct nl_cli_tc_module hfsc_qdisc_module = { .tm_name = "hfsc", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = hfsc_parse_qdisc_argv, }; static struct nl_cli_tc_module hfsc_class_module = { .tm_name = "hfsc", .tm_type = RTNL_TC_TYPE_CLASS, .tm_parse_argv = hfsc_parse_class_argv, }; static void __init hfsc_init(void) { nl_cli_tc_register(&hfsc_qdisc_module); nl_cli_tc_register(&hfsc_class_module); } static void __exit hfsc_exit(void) { nl_cli_tc_unregister(&hfsc_class_module); nl_cli_tc_unregister(&hfsc_qdisc_module); } libnl-3.2.29/lib/cli/qdisc/htb.c0000644000175000017500000001133513023014600013161 00000000000000/* * src/lib/htb.c HTB module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ #include #include #include static void print_qdisc_usage(void) { printf( "Usage: nl-qdisc-add [...] htb [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --r2q=DIV Rate to quantum divisor (default: 10)\n" " --default=ID Default class for unclassified traffic.\n" "\n" "EXAMPLE" " # Create htb root qdisc 1: and direct unclassified traffic to class 1:10\n" " nl-qdisc-add --dev=eth1 --parent=root --handle=1: htb --default=10\n"); } static void htb_parse_qdisc_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; for (;;) { int c, optidx = 0; enum { ARG_R2Q = 257, ARG_DEFAULT = 258, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "r2q", 1, 0, ARG_R2Q }, { "default", 1, 0, ARG_DEFAULT }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hv", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_qdisc_usage(); return; case ARG_R2Q: rtnl_htb_set_rate2quantum(qdisc, nl_cli_parse_u32(optarg)); break; case ARG_DEFAULT: rtnl_htb_set_defcls(qdisc, nl_cli_parse_u32(optarg)); break; } } } static void print_class_usage(void) { printf( "Usage: nl-class-add [...] htb [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --rate=RATE Rate limit.\n" " --ceil=RATE Rate limit while borrowing (default: equal to --rate).\n" " --prio=PRIO Priority, lower is served first (default: 0).\n" " --quantum=SIZE Amount of bytes to serve at once (default: rate/r2q).\n" " --burst=SIZE Max charge size of rate burst buffer (default: auto).\n" " --cburst=SIZE Max charge size of ceil rate burst buffer (default: auto)\n" "\n" "EXAMPLE" " # Attach class 1:1 to htb qdisc 1: and rate limit it to 20mbit\n" " nl-class-add --dev=eth1 --parent=1: --classid=1:1 htb --rate=20mbit\n"); } static void htb_parse_class_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_class *class = (struct rtnl_class *) tc; long rate; for (;;) { int c, optidx = 0; enum { ARG_RATE = 257, ARG_QUANTUM = 258, ARG_CEIL, ARG_PRIO, ARG_BURST, ARG_CBURST, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "rate", 1, 0, ARG_RATE }, { "quantum", 1, 0, ARG_QUANTUM }, { "ceil", 1, 0, ARG_CEIL }, { "prio", 1, 0, ARG_PRIO }, { "burst", 1, 0, ARG_BURST }, { "cburst", 1, 0, ARG_CBURST }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_class_usage(); return; case ARG_RATE: rate = nl_size2int(optarg); if (rate < 0) { nl_cli_fatal(rate, "Unable to parse htb rate " "\"%s\": Invalid format.", optarg); } rtnl_htb_set_rate(class, rate); break; case ARG_CEIL: rate = nl_size2int(optarg); if (rate < 0) { nl_cli_fatal(rate, "Unable to parse htb ceil rate " "\"%s\": Invalid format.", optarg); } rtnl_htb_set_ceil(class, rate); break; case ARG_PRIO: rtnl_htb_set_prio(class, nl_cli_parse_u32(optarg)); break; case ARG_QUANTUM: rate = nl_size2int(optarg); if (rate < 0) { nl_cli_fatal(rate, "Unable to parse quantum " "\"%s\": Invalid format.", optarg); } rtnl_htb_set_quantum(class, rate); break; case ARG_BURST: rate = nl_size2int(optarg); if (rate < 0) { nl_cli_fatal(rate, "Unable to parse burst " "\"%s\": Invalid format.", optarg); } rtnl_htb_set_rbuffer(class, rate); break; case ARG_CBURST: rate = nl_size2int(optarg); if (rate < 0) { nl_cli_fatal(rate, "Unable to parse cburst " "\"%s\": Invalid format.", optarg); } rtnl_htb_set_cbuffer(class, rate); break; } } } static struct nl_cli_tc_module htb_qdisc_module = { .tm_name = "htb", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = htb_parse_qdisc_argv, }; static struct nl_cli_tc_module htb_class_module = { .tm_name = "htb", .tm_type = RTNL_TC_TYPE_CLASS, .tm_parse_argv = htb_parse_class_argv, }; static void __init htb_init(void) { nl_cli_tc_register(&htb_qdisc_module); nl_cli_tc_register(&htb_class_module); } static void __exit htb_exit(void) { nl_cli_tc_unregister(&htb_class_module); nl_cli_tc_unregister(&htb_qdisc_module); } libnl-3.2.29/lib/cli/qdisc/blackhole.c0000644000175000017500000000251413023014600014327 00000000000000/* * src/lib/blackhole.c Blackhole module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ #include #include static void print_usage(void) { printf( "Usage: nl-qdisc-add [...] blackhole [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" "\n" "EXAMPLE" " # Drop all outgoing packets on eth1\n" " nl-qdisc-add --dev=eth1 --parent=root blackhole\n"); } static void blackhole_parse_argv(struct rtnl_tc *tc, int argc, char **argv) { for (;;) { int c, optidx = 0; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); return; } } } static struct nl_cli_tc_module blackhole_module = { .tm_name = "blackhole", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = blackhole_parse_argv, }; static void __init blackhole_init(void) { nl_cli_tc_register(&blackhole_module); } static void __exit blackhole_exit(void) { nl_cli_tc_unregister(&blackhole_module); } libnl-3.2.29/lib/cli/qdisc/fq_codel.c0000644000175000017500000000522113023014600014155 00000000000000/* * lib/cli/qdisc/fq_codel.c fq_codel module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ #include #include #include static void print_usage(void) { printf( "Usage: nl-qdisc-add [...] fq_codel [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --limit=LIMIT Maximum queue length in number of bytes.\n" " --quantum=SIZE Amount of bytes to serve at once.\n" " --flows=N Number of flows.\n" " --interval=N The interval in usec.\n" " --target=N The minimum delay in usec.\n" "\n" "EXAMPLE" " # Attach fq_codel with a 4096 packets limit to eth1\n" " nl-qdisc-add --dev=eth1 --parent=root fq_codel --limit=4096\n"); } static void fq_codel_parse_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; int limit, flows; uint32_t quantum, target, interval; for (;;) { int c, optidx = 0; enum { ARG_LIMIT = 257, ARG_QUANTUM = 258, ARG_FLOWS, ARG_INTERVAL, ARG_TARGET, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "limit", 1, 0, ARG_LIMIT }, { "quantum", 1, 0, ARG_QUANTUM }, { "flows", 1, 0, ARG_FLOWS}, { "interval", 1, 0, ARG_INTERVAL}, { "target", 1, 0, ARG_TARGET}, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); return; case ARG_LIMIT: limit = nl_cli_parse_u32(optarg); rtnl_qdisc_fq_codel_set_limit(qdisc, limit); break; case ARG_QUANTUM: quantum = nl_cli_parse_u32(optarg); rtnl_qdisc_fq_codel_set_quantum(qdisc, quantum); break; case ARG_FLOWS: flows = nl_cli_parse_u32(optarg); rtnl_qdisc_fq_codel_set_flows(qdisc, flows); break; case ARG_INTERVAL: interval = nl_cli_parse_u32(optarg); rtnl_qdisc_fq_codel_set_interval(qdisc, interval); break; case ARG_TARGET: target = nl_cli_parse_u32(optarg); rtnl_qdisc_fq_codel_set_target(qdisc, target); break; } } } static struct nl_cli_tc_module fq_codel_module = { .tm_name = "fq_codel", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = fq_codel_parse_argv, }; static void __init fq_codel_init(void) { nl_cli_tc_register(&fq_codel_module); } static void __exit fq_codel_exit(void) { nl_cli_tc_unregister(&fq_codel_module); } libnl-3.2.29/lib/cli/qdisc/plug.c0000644000175000017500000000650713023014600013360 00000000000000 /* * src/lib/cli/qdisc/plug.c plug module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Shriram Rajagopalan */ #include #include #include static void print_usage(void) { printf( "Usage: nl-qdisc-add [...] plug [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --limit Maximum queue length in bytes.\n" " --buffer create a new buffer(plug) and queue incoming traffic into it.\n" " --release-one release traffic from previous buffer.\n" " --release-indefinite stop buffering and release all (buffered and new) packets.\n" "\n" "EXAMPLE" " # Attach plug qdisc with 32KB queue size to ifb0\n" " nl-qdisc-add --dev=ifb0 --parent=root plug --limit=32768\n" " # Plug network traffic arriving at ifb0\n" " nl-qdisc-add --dev=ifb0 --parent=root --update plug --buffer\n" " # Unplug traffic arriving at ifb0 indefinitely\n" " nl-qdisc-add --dev=ifb0 --parent=root --update plug --release-indefinite\n\n" " # If operating in output buffering mode:\n" " # at time t=t0, create a new output buffer b0 to hold network output\n" " nl-qdisc-add --dev=ifb0 --parent=root --update plug --buffer\n\n" " # at time t=t1, take a checkpoint c0, create a new output buffer b1\n" " nl-qdisc-add --dev=ifb0 --parent=root --update plug --buffer\n" " # at time t=t1+r, after c0 is committed, release b0\n" " nl-qdisc-add --dev=ifb0 --parent=root --update plug --release-one\n\n" " # at time t=t2, take a checkpoint c1, create a new output buffer b2\n" " nl-qdisc-add --dev=ifb0 --parent=root --update plug --buffer\n" " # at time t=t2+r, after c1 is committed, release b1\n" " nl-qdisc-add --dev=ifb0 --parent=root --update plug --release-one\n"); } static void plug_parse_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; for (;;) { int c, optidx = 0; enum { ARG_LIMIT = 257, ARG_BUFFER = 258, ARG_RELEASE_ONE = 259, ARG_RELEASE_INDEFINITE = 260, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "limit", 1, 0, ARG_LIMIT }, { "buffer", 0, 0, ARG_BUFFER }, { "release-one", 0, 0, ARG_RELEASE_ONE }, { "release-indefinite", 0, 0, ARG_RELEASE_INDEFINITE }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); return; case ARG_LIMIT: rtnl_qdisc_plug_set_limit(qdisc, nl_cli_parse_u32(optarg)); break; case ARG_BUFFER: rtnl_qdisc_plug_buffer(qdisc); break; case ARG_RELEASE_ONE: rtnl_qdisc_plug_release_one(qdisc); break; case ARG_RELEASE_INDEFINITE: rtnl_qdisc_plug_release_indefinite(qdisc); break; } } } static struct nl_cli_tc_module plug_module = { .tm_name = "plug", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = plug_parse_argv, }; static void __init plug_init(void) { nl_cli_tc_register(&plug_module); } static void __exit plug_exit(void) { nl_cli_tc_unregister(&plug_module); } libnl-3.2.29/lib/cli/qdisc/pfifo.c0000644000175000017500000000317213023014600013507 00000000000000 /* * src/lib/pfifo.c pfifo module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ #include #include #include static void print_usage(void) { printf( "Usage: nl-qdisc-add [...] pfifo [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --limit=LIMIT Maximum queue length in number of packets.\n" "\n" "EXAMPLE" " # Attach pfifo with a 32 packet limit to eth1\n" " nl-qdisc-add --dev=eth1 --parent=root pfifo --limit=32\n"); } static void pfifo_parse_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; for (;;) { int c, optidx = 0; enum { ARG_LIMIT = 257, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "limit", 1, 0, ARG_LIMIT }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); return; case ARG_LIMIT: rtnl_qdisc_fifo_set_limit(qdisc, nl_cli_parse_u32(optarg)); break; } } } static struct nl_cli_tc_module pfifo_module = { .tm_name = "pfifo", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = pfifo_parse_argv, }; static void __init pfifo_init(void) { nl_cli_tc_register(&pfifo_module); } static void __exit pfifo_exit(void) { nl_cli_tc_unregister(&pfifo_module); } libnl-3.2.29/lib/cli/qdisc/ingress.c0000644000175000017500000000244313023014600014056 00000000000000 /* * src/lib/ingress.c ingress module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ #include #include static void print_usage(void) { printf( "Usage: nl-qdisc-add [...] ingress\n" "\n" "OPTIONS\n" " --help Show this help text.\n" "\n" "EXAMPLE" " # Attach ingress to eth1\n" " nl-qdisc-add --dev=eth1 --parent=root ingress\n"); } static void ingress_parse_argv(struct rtnl_tc *tc, int argc, char **argv) { for (;;) { int c, optidx = 0; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); return; } } } static struct nl_cli_tc_module ingress_module = { .tm_name = "ingress", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = ingress_parse_argv, }; static void __init ingress_init(void) { nl_cli_tc_register(&ingress_module); } static void __exit ingress_exit(void) { nl_cli_tc_unregister(&ingress_module); } libnl-3.2.29/lib/cli/qdisc/bfifo.c0000644000175000017500000000341413023014600013470 00000000000000/* * src/lib/bfifo.c bfifo module for CLI lib * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2011 Thomas Graf */ #include #include #include static void print_usage(void) { printf( "Usage: nl-qdisc-add [...] bfifo [OPTIONS]...\n" "\n" "OPTIONS\n" " --help Show this help text.\n" " --limit=LIMIT Maximum queue length in number of bytes.\n" "\n" "EXAMPLE" " # Attach bfifo with a 4KB bytes limit to eth1\n" " nl-qdisc-add --dev=eth1 --parent=root bfifo --limit=4096\n"); } static void bfifo_parse_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; int limit; for (;;) { int c, optidx = 0; enum { ARG_LIMIT = 257, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "limit", 1, 0, ARG_LIMIT }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_usage(); return; case ARG_LIMIT: limit = nl_size2int(optarg); if (limit < 0) { nl_cli_fatal(limit, "Unable to parse bfifo limit " "\"%s\": Invalid format.", optarg); } rtnl_qdisc_fifo_set_limit(qdisc, limit); break; } } } static struct nl_cli_tc_module bfifo_module = { .tm_name = "bfifo", .tm_type = RTNL_TC_TYPE_QDISC, .tm_parse_argv = bfifo_parse_argv, }; static void __init bfifo_init(void) { nl_cli_tc_register(&bfifo_module); } static void __exit bfifo_exit(void) { nl_cli_tc_unregister(&bfifo_module); } libnl-3.2.29/lib/fib_lookup/0000755000175000017500000000000013031473756012620 500000000000000libnl-3.2.29/lib/fib_lookup/lookup.c0000644000175000017500000001752013023014600014176 00000000000000/* * lib/fib_lookup/lookup.c FIB Lookup * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup rtnl * @defgroup fib_lookup FIB Lookup * @brief * @{ */ #include #include #include #include #include #include #include #include #include #include /** @cond SKIP */ static struct nl_cache_ops fib_lookup_ops; static struct nl_object_ops result_obj_ops; /* not exported so far */ struct fib_result_nl { uint32_t fl_addr; /* To be looked up*/ uint32_t fl_fwmark; unsigned char fl_tos; unsigned char fl_scope; unsigned char tb_id_in; unsigned char tb_id; /* Results */ unsigned char prefixlen; unsigned char nh_sel; unsigned char type; unsigned char scope; int err; }; /** @endcond */ static void result_free_data(struct nl_object *obj) { struct flnl_result *res = nl_object_priv(obj); if (res && res->fr_req) nl_object_put(OBJ_CAST(res->fr_req)); } static int result_clone(struct nl_object *_dst, struct nl_object *_src) { struct flnl_result *dst = nl_object_priv(_dst); struct flnl_result *src = nl_object_priv(_src); if (src->fr_req) if (!(dst->fr_req = (struct flnl_request *) nl_object_clone(OBJ_CAST(src->fr_req)))) return -NLE_NOMEM; return 0; } static int result_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct flnl_result *res; struct fib_result_nl *fr; struct nl_addr *addr; int err = -NLE_INVAL; res = flnl_result_alloc(); if (!res) goto errout; res->ce_msgtype = n->nlmsg_type; res->fr_req = flnl_request_alloc(); if (!res->fr_req) goto errout; fr = nlmsg_data(n); addr = nl_addr_build(AF_INET, &fr->fl_addr, 4); if (!addr) goto errout; err = flnl_request_set_addr(res->fr_req, addr); nl_addr_put(addr); if (err < 0) goto errout; flnl_request_set_fwmark(res->fr_req, fr->fl_fwmark); flnl_request_set_tos(res->fr_req, fr->fl_tos); flnl_request_set_scope(res->fr_req, fr->fl_scope); flnl_request_set_table(res->fr_req, fr->tb_id_in); res->fr_table_id = fr->tb_id; res->fr_prefixlen = fr->prefixlen; res->fr_nh_sel = fr->nh_sel; res->fr_type = fr->type; res->fr_scope = fr->scope; res->fr_error = fr->err; err = pp->pp_cb((struct nl_object *) res, pp); if (err < 0) goto errout; /* REAL HACK, fib_lookup doesn't support ACK nor does it * send a DONE message, enforce end of message stream * after just the first message */ err = NL_STOP; errout: flnl_result_put(res); return err; } static void result_dump_line(struct nl_object *obj, struct nl_dump_params *p) { struct flnl_result *res = (struct flnl_result *) obj; char buf[256]; nl_dump_line(p, "table %s prefixlen %u next-hop-selector %u\n", rtnl_route_table2str(res->fr_table_id, buf, sizeof(buf)), res->fr_prefixlen, res->fr_nh_sel); nl_dump_line(p, "type %s ", nl_rtntype2str(res->fr_type, buf, sizeof(buf))); nl_dump(p, "scope %s error %s (%d)\n", rtnl_scope2str(res->fr_scope, buf, sizeof(buf)), nl_strerror_l(-res->fr_error), res->fr_error); } static void result_dump_details(struct nl_object *obj, struct nl_dump_params *p) { result_dump_line(obj, p); } static uint64_t result_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { return 0; } /** * @name Allocation/Freeing * @{ */ struct flnl_result *flnl_result_alloc(void) { return (struct flnl_result *) nl_object_alloc(&result_obj_ops); } void flnl_result_put(struct flnl_result *res) { nl_object_put((struct nl_object *) res); } /** @} */ /** * @name Cache Management * @{ */ /** * Allocate lookup result cache. * * Allocates a new lookup result cache and initializes it properly. * * @note Free the memory after usage using nl_cache_destroy_and_free(). * @return Newly allocated cache or NULL if an error occured. */ struct nl_cache *flnl_result_alloc_cache(void) { return nl_cache_alloc(&fib_lookup_ops); } /** @} */ /** * @name Lookup * @{ */ /** * Builds a netlink request message to do a lookup * @arg req Requested match. * @arg flags additional netlink message flags * @arg result Result pointer * * Builds a new netlink message requesting a change of link attributes. * The netlink message header isn't fully equipped with all relevant * fields and must be sent out via nl_send_auto_complete() or * supplemented as needed. * \a old must point to a link currently configured in the kernel * and \a tmpl must contain the attributes to be changed set via * \c rtnl_link_set_* functions. * * @return 0 on success or a negative error code. */ int flnl_lookup_build_request(struct flnl_request *req, int flags, struct nl_msg **result) { struct nl_msg *msg; struct nl_addr *addr; uint64_t fwmark; int tos, scope, table; struct fib_result_nl fr = {0}; fwmark = flnl_request_get_fwmark(req); tos = flnl_request_get_tos(req); scope = flnl_request_get_scope(req); table = flnl_request_get_table(req); fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0; fr.fl_tos = tos >= 0 ? tos : 0; fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE; fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC; addr = flnl_request_get_addr(req); if (!addr) return -NLE_MISSING_ATTR; fr.fl_addr = *(uint32_t *) nl_addr_get_binary_addr(addr); msg = nlmsg_alloc_simple(0, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &fr, sizeof(fr), NLMSG_ALIGNTO) < 0) goto errout; *result = msg; return 0; errout: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * Perform FIB Lookup * @arg sk Netlink socket. * @arg req Lookup request object. * @arg cache Cache for result. * * Builds a netlink message to request a FIB lookup, waits for the * reply and adds the result to the specified cache. * * @return 0 on success or a negative error code. */ int flnl_lookup(struct nl_sock *sk, struct flnl_request *req, struct nl_cache *cache) { struct nl_msg *msg; int err; if ((err = flnl_lookup_build_request(req, 0, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_cache_pickup_checkdup(sk, cache); } /** @} */ /** * @name Attribute Access * @{ */ int flnl_result_get_table_id(struct flnl_result *res) { return res->fr_table_id; } int flnl_result_get_prefixlen(struct flnl_result *res) { return res->fr_prefixlen; } int flnl_result_get_nexthop_sel(struct flnl_result *res) { return res->fr_nh_sel; } int flnl_result_get_type(struct flnl_result *res) { return res->fr_type; } int flnl_result_get_scope(struct flnl_result *res) { return res->fr_scope; } int flnl_result_get_error(struct flnl_result *res) { return res->fr_error; } /** @} */ static struct nl_object_ops result_obj_ops = { .oo_name = "fib_lookup/result", .oo_size = sizeof(struct flnl_result), .oo_free_data = result_free_data, .oo_clone = result_clone, .oo_dump = { [NL_DUMP_LINE] = result_dump_line, [NL_DUMP_DETAILS] = result_dump_details, }, .oo_compare = result_compare, }; static struct nl_cache_ops fib_lookup_ops = { .co_name = "fib_lookup/fib_lookup", .co_hdrsize = sizeof(struct fib_result_nl), .co_msgtypes = { { 0, NL_ACT_UNSPEC, "any" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_FIB_LOOKUP, .co_msg_parser = result_msg_parser, .co_obj_ops = &result_obj_ops, }; static void __init fib_lookup_init(void) { nl_cache_mngt_register(&fib_lookup_ops); } static void __exit fib_lookup_exit(void) { nl_cache_mngt_unregister(&fib_lookup_ops); } /** @} */ libnl-3.2.29/lib/fib_lookup/request.c0000644000175000017500000000751213023014600014355 00000000000000/* * lib/fib_lookup/request.c FIB Lookup Request * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup fib_lookup * @defgroup flreq Request * @brief * @{ */ #include #include #include #include #include #include static struct nl_object_ops request_obj_ops; /** @cond SKIP */ #define REQUEST_ATTR_ADDR 0x01 #define REQUEST_ATTR_FWMARK 0x02 #define REQUEST_ATTR_TOS 0x04 #define REQUEST_ATTR_SCOPE 0x08 #define REQUEST_ATTR_TABLE 0x10 /** @endcond */ static void request_free_data(struct nl_object *obj) { struct flnl_request *req = REQUEST_CAST(obj); if (req) nl_addr_put(req->lr_addr); } static int request_clone(struct nl_object *_dst, struct nl_object *_src) { struct flnl_request *dst = nl_object_priv(_dst); struct flnl_request *src = nl_object_priv(_src); if (src->lr_addr) if (!(dst->lr_addr = nl_addr_clone(src->lr_addr))) return -NLE_NOMEM; return 0; } static uint64_t request_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct flnl_request *a = (struct flnl_request *) _a; struct flnl_request *b = (struct flnl_request *) _b; uint64_t diff = 0; #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR) diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark); diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos); diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope); diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table); diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr)); #undef REQ_DIFF return diff; } /** * @name Lookup Request Creation/Deletion * @{ */ struct flnl_request *flnl_request_alloc(void) { return REQUEST_CAST(nl_object_alloc(&request_obj_ops)); } /** @} */ /** * @name Attributes * @{ */ void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark) { req->lr_fwmark = fwmark; req->ce_mask |= REQUEST_ATTR_FWMARK; } uint64_t flnl_request_get_fwmark(struct flnl_request *req) { if (req->ce_mask & REQUEST_ATTR_FWMARK) return req->lr_fwmark; else return UINT_LEAST64_MAX; } void flnl_request_set_tos(struct flnl_request *req, int tos) { req->lr_tos = tos; req->ce_mask |= REQUEST_ATTR_TOS; } int flnl_request_get_tos(struct flnl_request *req) { if (req->ce_mask & REQUEST_ATTR_TOS) return req->lr_tos; else return -1; } void flnl_request_set_scope(struct flnl_request *req, int scope) { req->lr_scope = scope; req->ce_mask |= REQUEST_ATTR_SCOPE; } int flnl_request_get_scope(struct flnl_request *req) { if (req->ce_mask & REQUEST_ATTR_SCOPE) return req->lr_scope; else return -1; } void flnl_request_set_table(struct flnl_request *req, int table) { req->lr_table = table; req->ce_mask |= REQUEST_ATTR_TABLE; } int flnl_request_get_table(struct flnl_request *req) { if (req->ce_mask & REQUEST_ATTR_TABLE) return req->lr_table; else return -1; } int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr) { if (addr->a_family != AF_INET) return -NLE_AF_NOSUPPORT; if (req->lr_addr) nl_addr_put(req->lr_addr); nl_addr_get(addr); req->lr_addr = addr; req->ce_mask |= REQUEST_ATTR_ADDR; return 0; } struct nl_addr *flnl_request_get_addr(struct flnl_request *req) { if (req->ce_mask & REQUEST_ATTR_ADDR) return req->lr_addr; else return NULL; } /** @} */ static struct nl_object_ops request_obj_ops = { .oo_name = "fib_lookup/request", .oo_size = sizeof(struct flnl_request), .oo_free_data = request_free_data, .oo_clone = request_clone, .oo_compare = request_compare, .oo_id_attrs = ~0, }; /** @} */ libnl-3.2.29/lib/cache_mngt.c0000644000175000017500000002363313023014600012626 00000000000000/* * lib/cache_mngt.c Cache Management * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup core * @defgroup cache_mngt Caching System * * Related sections in the development guide: * - @core_doc{core_cache, Caching System} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include static struct nl_cache_ops *cache_ops; static NL_RW_LOCK(cache_ops_lock); /** * @name Cache Operations Sets * @{ */ static struct nl_cache_ops *__nl_cache_ops_lookup(const char *name) { struct nl_cache_ops *ops; for (ops = cache_ops; ops; ops = ops->co_next) if (!strcmp(ops->co_name, name)) return ops; return NULL; } /** * Increment reference counter * @arg ops Cache operations */ void nl_cache_ops_get(struct nl_cache_ops *ops) { ops->co_refcnt++; } /** * Decrement reference counter * @arg ops Cache operations */ void nl_cache_ops_put(struct nl_cache_ops *ops) { ops->co_refcnt--; } /** * Lookup cache operations by name * @arg name name of the cache type * * @attention This function is not safe, it does not increment the reference * counter. Please use nl_cache_ops_lookup_safe(). * * @return The cache operations or NULL if not found. */ struct nl_cache_ops *nl_cache_ops_lookup(const char *name) { struct nl_cache_ops *ops; nl_read_lock(&cache_ops_lock); ops = __nl_cache_ops_lookup(name); nl_read_unlock(&cache_ops_lock); return ops; } /** * Lookup cache operations by name * @arg name name of the cache type * * @note The reference counter of the returned cache operation is incremented * and must be decremented after use with nl_cache_ops_put(). * * @return The cache operations or NULL if not found. */ struct nl_cache_ops *nl_cache_ops_lookup_safe(const char *name) { struct nl_cache_ops *ops; nl_write_lock(&cache_ops_lock); if ((ops = __nl_cache_ops_lookup(name))) nl_cache_ops_get(ops); nl_write_unlock(&cache_ops_lock); return ops; } static struct nl_cache_ops *__cache_ops_associate(int protocol, int msgtype) { int i; struct nl_cache_ops *ops; for (ops = cache_ops; ops; ops = ops->co_next) { if (ops->co_protocol != protocol) continue; for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) if (ops->co_msgtypes[i].mt_id == msgtype) return ops; } return NULL; } /** * Associate protocol and message type to cache operations * @arg protocol netlink protocol * @arg msgtype netlink message type * * @attention This function is not safe, it does not increment the reference * counter. Please use nl_cache_ops_associate_safe(). * * @see nl_cache_ops_associate_safe() * * @return The cache operations or NULL if no match found. */ struct nl_cache_ops *nl_cache_ops_associate(int protocol, int msgtype) { struct nl_cache_ops *ops; nl_read_lock(&cache_ops_lock); ops = __cache_ops_associate(protocol, msgtype); nl_read_unlock(&cache_ops_lock); return ops; } /** * Associate protocol and message type to cache operations * @arg protocol netlink protocol * @arg msgtype netlink message type * * Searches the registered cache operations for a matching protocol * and message type. * * @note The reference counter of the returned cache operation is incremented * and must be decremented after use with nl_cache_ops_put(). * * @return The cache operations or NULL if no no match was found. */ struct nl_cache_ops *nl_cache_ops_associate_safe(int protocol, int msgtype) { struct nl_cache_ops *ops; nl_write_lock(&cache_ops_lock); if ((ops = __cache_ops_associate(protocol, msgtype))) nl_cache_ops_get(ops); nl_write_unlock(&cache_ops_lock); return ops; } /** * Lookup message type cache association * @arg ops cache operations * @arg msgtype netlink message type * * Searches for a matching message type association ing the specified * cache operations. * * @attention The guranteed lifetime of the returned message type is bound * to the lifetime of the underlying cache operations. * * @return A message type association or NULL. */ struct nl_msgtype *nl_msgtype_lookup(struct nl_cache_ops *ops, int msgtype) { int i; for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) if (ops->co_msgtypes[i].mt_id == msgtype) return &ops->co_msgtypes[i]; return NULL; } /* Must hold cache_ops_lock */ static struct nl_cache_ops *cache_ops_lookup_for_obj(struct nl_object_ops *obj_ops) { struct nl_cache_ops *ops; for (ops = cache_ops; ops; ops = ops->co_next) if (ops->co_obj_ops == obj_ops) return ops; return NULL; } /** * Call a function for each registered cache operation * @arg cb Callback function to be called * @arg arg User specific argument. */ void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *arg) { struct nl_cache_ops *ops; nl_read_lock(&cache_ops_lock); for (ops = cache_ops; ops; ops = ops->co_next) cb(ops, arg); nl_read_unlock(&cache_ops_lock); } /** * Set default flags for caches of this type * @arg ops Cache ops * @arg flags Flags to set * * The cache operation flags will be derived to all caches allocates * based on this set of cache operations. */ void nl_cache_ops_set_flags(struct nl_cache_ops *ops, unsigned int flags) { nl_write_lock(&cache_ops_lock); ops->co_flags |= flags; nl_write_unlock(&cache_ops_lock); } /** * Register a set of cache operations * @arg ops cache operations * * Called by users of caches to announce the avaibility of * a certain cache type. * * @return 0 on success or a negative error code. */ int nl_cache_mngt_register(struct nl_cache_ops *ops) { if (!ops->co_name || !ops->co_obj_ops) return -NLE_INVAL; /* oo_keygen() also needs oo_compare() */ BUG_ON (ops->co_obj_ops->oo_keygen && !ops->co_obj_ops->oo_compare); nl_write_lock(&cache_ops_lock); if (__nl_cache_ops_lookup(ops->co_name)) { nl_write_unlock(&cache_ops_lock); return -NLE_EXIST; } ops->co_refcnt = 0; ops->co_next = cache_ops; cache_ops = ops; nl_write_unlock(&cache_ops_lock); NL_DBG(1, "Registered cache operations %s\n", ops->co_name); return 0; } /** * Unregister a set of cache operations * @arg ops cache operations * * Called by users of caches to announce a set of * cache operations is no longer available. The * specified cache operations must have been registered * previously using nl_cache_mngt_register() * * @return 0 on success or a negative error code */ int nl_cache_mngt_unregister(struct nl_cache_ops *ops) { struct nl_cache_ops *t, **tp; int err = 0; nl_write_lock(&cache_ops_lock); if (ops->co_refcnt > 0) { err = -NLE_BUSY; goto errout; } for (tp = &cache_ops; (t=*tp) != NULL; tp = &t->co_next) if (t == ops) break; if (!t) { err = -NLE_NOCACHE; goto errout; } NL_DBG(1, "Unregistered cache operations %s\n", ops->co_name); *tp = t->co_next; errout: nl_write_unlock(&cache_ops_lock); return err; } /** @} */ /** * @name Global Cache Provisioning/Requiring * @{ */ /** * Provide a cache for global use * @arg cache cache to provide * * Offers the specified cache to be used by other modules. * Only one cache per type may be shared at a time, * a previsouly provided caches will be overwritten. */ void nl_cache_mngt_provide(struct nl_cache *cache) { struct nl_cache_ops *ops; nl_write_lock(&cache_ops_lock); ops = cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops); if (!ops) BUG(); else { nl_cache_get(cache); /* * Hold a reference to the cache operations to ensure the * ops don't go away while we use it to store the cache pointer. */ if (!ops->co_major_cache) nl_cache_ops_get(ops); ops->co_major_cache = cache; } nl_write_unlock(&cache_ops_lock); } /** * Unprovide a cache for global use * @arg cache cache to unprovide * * Cancels the offer to use a cache globally. The * cache will no longer be returned via lookups but * may still be in use. */ void nl_cache_mngt_unprovide(struct nl_cache *cache) { struct nl_cache_ops *ops; nl_write_lock(&cache_ops_lock); ops = cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops); if (!ops) BUG(); else if (ops->co_major_cache == cache) { nl_cache_free(ops->co_major_cache); nl_cache_ops_put(ops); ops->co_major_cache = NULL; } nl_write_unlock(&cache_ops_lock); } struct nl_cache *__nl_cache_mngt_require(const char *name) { struct nl_cache_ops *ops; struct nl_cache *cache = NULL; ops = nl_cache_ops_lookup_safe(name); if (ops) { cache = ops->co_major_cache; nl_cache_ops_put(ops); } return cache; } /** * Return cache previously provided via nl_cache_mngt_provide() * @arg name Name of cache to lookup * * @attention This function is not safe, it does not increment the reference * counter. Please use nl_cache_mngt_require_safe(). * * @see nl_cache_mngt_require_safe() * * @return Pointer to cache or NULL if none registered */ struct nl_cache *nl_cache_mngt_require(const char *name) { struct nl_cache *cache; if (!(cache = __nl_cache_mngt_require(name))) NL_DBG(1, "Application BUG: Your application must " "call nl_cache_mngt_provide() and\nprovide a valid " "%s cache to be used for internal lookups.\nSee the " " API documentation for more details.\n", name); return cache; } /** * Return cache previously provided via nl_cache_mngt_provide() * @arg name Name of cache to lookup * * @note The reference counter of the returned cache is incremented * and must be decremented after use with nl_cache_put(). * * @return Pointer to cache or NULL if none registered */ struct nl_cache *nl_cache_mngt_require_safe(const char *name) { struct nl_cache *cache; if ((cache = nl_cache_mngt_require(name))) nl_cache_get(cache); return cache; } /** @} */ /** @} */ libnl-3.2.29/lib/hash.c0000644000175000017500000004161713023014600011463 00000000000000/* * This code was taken from http://ccodearchive.net/info/hash.html * The original file was modified to remove unwanted code * and some changes to fit the current build environment */ /* ------------------------------------------------------------------------------- lookup3.c, by Bob Jenkins, May 2006, Public Domain. These are functions for producing 32-bit hashes for hash table lookup. hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() are externally useful functions. Routines to test the hash are included if SELF_TEST is defined. You can use this free for any purpose. It's in the public domain. It has no warranty. You probably want to use hashlittle(). hashlittle() and hashbig() hash byte arrays. hashlittle() is is faster than hashbig() on little-endian machines. Intel and AMD are little-endian machines. On second thought, you probably want hashlittle2(), which is identical to hashlittle() except it returns two 32-bit hashes for the price of one. You could implement hashbig2() if you wanted but I haven't bothered here. If you want to find a hash of, say, exactly 7 integers, do a = i1; b = i2; c = i3; mix(a,b,c); a += i4; b += i5; c += i6; mix(a,b,c); a += i7; final(a,b,c); then use c as the hash value. If you have a variable length array of 4-byte integers to hash, use hash_word(). If you have a byte array (like a character string), use hashlittle(). If you have several byte arrays, or a mix of things, see the comments above hashlittle(). Why is this so big? I read 12 bytes at a time into 3 4-byte integers, then mix those integers. This is fast (you can do a lot more thorough mixing with 12*3 instructions on 3 integers than you can with 3 instructions on 1 byte), but shoehorning those bytes into integers efficiently is messy. ------------------------------------------------------------------------------- */ #include #if HAVE_LITTLE_ENDIAN #define HASH_LITTLE_ENDIAN 1 #define HASH_BIG_ENDIAN 0 #elif HAVE_BIG_ENDIAN #define HASH_LITTLE_ENDIAN 0 #define HASH_BIG_ENDIAN 1 #else #error Unknown endian #endif #define hashsize(n) ((uint32_t)1<<(n)) #define hashmask(n) (hashsize(n)-1) #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) /* ------------------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. This is reversible, so any information in (a,b,c) before mix() is still in (a,b,c) after mix(). If four pairs of (a,b,c) inputs are run through mix(), or through mix() in reverse, there are at least 32 bits of the output that are sometimes the same for one pair and different for another pair. This was tested for: * pairs that differed by one bit, by two bits, in any combination of top bits of (a,b,c), or in any combination of bottom bits of (a,b,c). * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly produced by subtraction) look like a single 1-bit difference. * the base values were pseudorandom, all zero but one bit set, or all zero plus a counter that starts at zero. Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that satisfy this are 4 6 8 16 19 4 9 15 3 18 27 15 14 9 3 7 17 3 Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing for "differ" defined as + with a one-bit base and a two-bit delta. I used http://burtleburtle.net/bob/hash/avalanche.html to choose the operations, constants, and arrangements of the variables. This does not achieve avalanche. There are input bits of (a,b,c) that fail to affect some output bits of (a,b,c), especially of a. The most thoroughly mixed value is c, but it doesn't really even achieve avalanche in c. This allows some parallelism. Read-after-writes are good at doubling the number of bits affected, so the goal of mixing pulls in the opposite direction as the goal of parallelism. I did what I could. Rotates seem to cost as much as shifts on every machine I could lay my hands on, and rotates are much kinder to the top and bottom bits, so I used rotates. ------------------------------------------------------------------------------- */ #define mix(a,b,c) \ { \ a -= c; a ^= rot(c, 4); c += b; \ b -= a; b ^= rot(a, 6); a += c; \ c -= b; c ^= rot(b, 8); b += a; \ a -= c; a ^= rot(c,16); c += b; \ b -= a; b ^= rot(a,19); a += c; \ c -= b; c ^= rot(b, 4); b += a; \ } /* ------------------------------------------------------------------------------- final -- final mixing of 3 32-bit values (a,b,c) into c Pairs of (a,b,c) values differing in only a few bits will usually produce values of c that look totally different. This was tested for * pairs that differed by one bit, by two bits, in any combination of top bits of (a,b,c), or in any combination of bottom bits of (a,b,c). * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly produced by subtraction) look like a single 1-bit difference. * the base values were pseudorandom, all zero but one bit set, or all zero plus a counter that starts at zero. These constants passed: 14 11 25 16 4 14 24 12 14 25 16 4 14 24 and these came close: 4 8 15 26 3 22 24 10 8 15 26 3 22 24 11 8 15 26 3 22 24 ------------------------------------------------------------------------------- */ #define final(a,b,c) \ { \ c ^= b; c -= rot(b,14); \ a ^= c; a -= rot(c,11); \ b ^= a; b -= rot(a,25); \ c ^= b; c -= rot(b,16); \ a ^= c; a -= rot(c,4); \ b ^= a; b -= rot(a,14); \ c ^= b; c -= rot(b,24); \ } /* ------------------------------------------------------------------------------- hashlittle() -- hash a variable-length key into a 32-bit value k : the key (the unaligned variable-length array of bytes) length : the length of the key, counting by bytes val2 : IN: can be any 4-byte value OUT: second 32 bit hash. Returns a 32-bit value. Every bit of the key affects every bit of the return value. Two keys differing by one or two bits will have totally different hash values. Note that the return value is better mixed than val2, so use that first. The best hash table sizes are powers of 2. There is no need to do mod a prime (mod is sooo slow!). If you need less than 32 bits, use a bitmask. For example, if you need only 10 bits, do h = (h & hashmask(10)); In which case, the hash table should have hashsize(10) elements. If you are hashing n strings (uint8_t **)k, do it like this: for (i=0, h=0; i 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ /* * "k[2]&0xffffff" actually reads beyond the end of the string, but * then masks off the part it's not allowed to read. Because the * string is aligned, the masked-off tail is in the same word as the * rest of the string. Every machine with memory protection I've seen * does it on word boundaries, so is OK with this. But VALGRIND will * still catch it and complain. The masking trick does make the hash * noticably faster for short strings (like English words). * * Not on my testing with gcc 4.5 on an intel i5 CPU, at least --RR. */ #if 0 switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=k[1]&0xffffff; a+=k[0]; break; case 6 : b+=k[1]&0xffff; a+=k[0]; break; case 5 : b+=k[1]&0xff; a+=k[0]; break; case 4 : a+=k[0]; break; case 3 : a+=k[0]&0xffffff; break; case 2 : a+=k[0]&0xffff; break; case 1 : a+=k[0]&0xff; break; case 0 : return c; /* zero length strings require no mixing */ } #else /* make valgrind happy */ k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ case 9 : c+=k8[8]; /* fall through */ case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ case 5 : b+=k8[4]; /* fall through */ case 4 : a+=k[0]; break; case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ case 1 : a+=k8[0]; break; case 0 : return c; } #endif /* !valgrind */ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ const uint8_t *k8; /*--------------- all but last block: aligned reads and different mixing */ while (length > 12) { a += k[0] + (((uint32_t)k[1])<<16); b += k[2] + (((uint32_t)k[3])<<16); c += k[4] + (((uint32_t)k[5])<<16); mix(a,b,c); length -= 12; k += 6; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[4]+(((uint32_t)k[5])<<16); b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ case 10: c+=k[4]; b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 9 : c+=k8[8]; /* fall through */ case 8 : b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ case 6 : b+=k[2]; a+=k[0]+(((uint32_t)k[1])<<16); break; case 5 : b+=k8[4]; /* fall through */ case 4 : a+=k[0]+(((uint32_t)k[1])<<16); break; case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ case 2 : a+=k[0]; break; case 1 : a+=k8[0]; break; case 0 : return c; /* zero length requires no mixing */ } } else { /* need to read the key one byte at a time */ const uint8_t *k = (const uint8_t *)key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; a += ((uint32_t)k[1])<<8; a += ((uint32_t)k[2])<<16; a += ((uint32_t)k[3])<<24; b += k[4]; b += ((uint32_t)k[5])<<8; b += ((uint32_t)k[6])<<16; b += ((uint32_t)k[7])<<24; c += k[8]; c += ((uint32_t)k[9])<<8; c += ((uint32_t)k[10])<<16; c += ((uint32_t)k[11])<<24; mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) /* all the case statements fall through */ { case 12: c+=((uint32_t)k[11])<<24; case 11: c+=((uint32_t)k[10])<<16; case 10: c+=((uint32_t)k[9])<<8; case 9 : c+=k[8]; case 8 : b+=((uint32_t)k[7])<<24; case 7 : b+=((uint32_t)k[6])<<16; case 6 : b+=((uint32_t)k[5])<<8; case 5 : b+=k[4]; case 4 : a+=((uint32_t)k[3])<<24; case 3 : a+=((uint32_t)k[2])<<16; case 2 : a+=((uint32_t)k[1])<<8; case 1 : a+=k[0]; break; case 0 : return c; } } final(a,b,c); *val2 = b; return c; } /* * hashbig(): * This is the same as hash_word() on big-endian machines. It is different * from hashlittle() on all machines. hashbig() takes advantage of * big-endian byte ordering. */ static uint32_t hashbig( const void *key, size_t length, uint32_t *val2) { uint32_t a,b,c; union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ /* Set up the internal state */ a = b = c = 0xdeadbeef + ((uint32_t)length) + *val2; u.ptr = key; if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ const uint8_t *k8; /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ /* * "k[2]<<8" actually reads beyond the end of the string, but * then shifts out the part it's not allowed to read. Because the * string is aligned, the illegal read is in the same word as the * rest of the string. Every machine with memory protection I've seen * does it on word boundaries, so is OK with this. But VALGRIND will * still catch it and complain. The masking trick does make the hash * noticably faster for short strings (like English words). * * Not on my testing with gcc 4.5 on an intel i5 CPU, at least --RR. */ #if 0 switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; case 5 : b+=k[1]&0xff000000; a+=k[0]; break; case 4 : a+=k[0]; break; case 3 : a+=k[0]&0xffffff00; break; case 2 : a+=k[0]&0xffff0000; break; case 1 : a+=k[0]&0xff000000; break; case 0 : return c; /* zero length strings require no mixing */ } #else /* make valgrind happy */ k8 = (const uint8_t *)k; switch(length) /* all the case statements fall through */ { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ case 4 : a+=k[0]; break; case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ case 1 : a+=((uint32_t)k8[0])<<24; break; case 0 : return c; } #endif /* !VALGRIND */ } else { /* need to read the key one byte at a time */ const uint8_t *k = (const uint8_t *)key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ while (length > 12) { a += ((uint32_t)k[0])<<24; a += ((uint32_t)k[1])<<16; a += ((uint32_t)k[2])<<8; a += ((uint32_t)k[3]); b += ((uint32_t)k[4])<<24; b += ((uint32_t)k[5])<<16; b += ((uint32_t)k[6])<<8; b += ((uint32_t)k[7]); c += ((uint32_t)k[8])<<24; c += ((uint32_t)k[9])<<16; c += ((uint32_t)k[10])<<8; c += ((uint32_t)k[11]); mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) /* all the case statements fall through */ { case 12: c+=k[11]; case 11: c+=((uint32_t)k[10])<<8; case 10: c+=((uint32_t)k[9])<<16; case 9 : c+=((uint32_t)k[8])<<24; case 8 : b+=k[7]; case 7 : b+=((uint32_t)k[6])<<8; case 6 : b+=((uint32_t)k[5])<<16; case 5 : b+=((uint32_t)k[4])<<24; case 4 : a+=k[3]; case 3 : a+=((uint32_t)k[2])<<8; case 2 : a+=((uint32_t)k[1])<<16; case 1 : a+=((uint32_t)k[0])<<24; break; case 0 : return c; } } final(a,b,c); *val2 = b; return c; } uint32_t nl_hash_any(const void *key, size_t length, uint32_t base) { if (HASH_BIG_ENDIAN) return hashbig(key, length, &base); else return hashlittle(key, length, &base); } libnl-3.2.29/lib/data.c0000644000175000017500000000760113023014600011444 00000000000000/* * lib/data.c Abstract Data * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup core_types * @defgroup data Abstract Data * * Abstract data type representing a binary data blob. * * Related sections in the development guide: * - @core_doc{_abstract_data, Abstract Data} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include /** * @name General * @{ */ /** * Allocate a new abstract data object. * @arg buf Data buffer containing the actual data. * @arg size Size of data buffer. * * Allocates a new abstract data and copies the specified data * buffer into the new handle. * * @return Newly allocated data handle or NULL */ struct nl_data *nl_data_alloc(const void *buf, size_t size) { struct nl_data *data; data = calloc(1, sizeof(*data)); if (!data) goto errout; data->d_data = calloc(1, size); if (!data->d_data) { free(data); goto errout; } data->d_size = size; if (buf) memcpy(data->d_data, buf, size); return data; errout: return NULL; } /** * Allocate abstract data object based on netlink attribute. * @arg nla Netlink attribute of unspecific type. * * Allocates a new abstract data and copies the payload of the * attribute to the abstract data object. * * @see nla_data_alloc * @return Newly allocated data handle or NULL */ struct nl_data *nl_data_alloc_attr(const struct nlattr *nla) { return nl_data_alloc(nla_data(nla), nla_len(nla)); } /** * Clone an abstract data object. * @arg src Abstract data object * * @return Cloned object or NULL */ struct nl_data *nl_data_clone(const struct nl_data *src) { return nl_data_alloc(src->d_data, src->d_size); } /** * Append data to an abstract data object. * @arg data Abstract data object. * @arg buf Data buffer containing the data to be appended. * @arg size Size of data to be apppended. * * Reallocates an abstract data and copies the specified data * buffer into the new handle. * * @return 0 on success or a negative error code */ int nl_data_append(struct nl_data *data, const void *buf, size_t size) { if (size > 0) { data->d_data = realloc(data->d_data, data->d_size + size); if (!data->d_data) return -NLE_NOMEM; if (buf) memcpy(data->d_data + data->d_size, buf, size); else memset(data->d_data + data->d_size, 0, size); data->d_size += size; } return 0; } /** * Free an abstract data object. * @arg data Abstract data object. */ void nl_data_free(struct nl_data *data) { if (data) free(data->d_data); free(data); } /** @} */ /** * @name Attribute Access * @{ */ /** * Get data buffer of abstract data object. * @arg data Abstract data object. * @return Data buffer or NULL if empty. */ void *nl_data_get(const struct nl_data *data) { if (data->d_size > 0) return (void*)data->d_data; return NULL; } /** * Get size of data buffer of abstract data object. * @arg data Abstract data object. * @return Size of data buffer. */ size_t nl_data_get_size(const struct nl_data *data) { return data->d_size; } /** @} */ /** * @name Misc * @{ */ /** * Compare two abstract data objects. * @arg a Abstract data object. * @arg b Another abstract data object. * @return An integer less than, equal to, or greater than zero if * a is found, respectively, to be less than, to match, or * be greater than b. */ int nl_data_cmp(const struct nl_data *a, const struct nl_data *b) { const void *a_ = nl_data_get(a); const void *b_ = nl_data_get(b); if (a_ && b_) return memcmp(a_, b_, nl_data_get_size(a)); else return -1; } /** @} */ /** @} */ libnl-3.2.29/lib/netfilter/0000755000175000017500000000000013031473756012463 500000000000000libnl-3.2.29/lib/netfilter/log_msg_obj.c0000644000175000017500000002517413023014600015015 00000000000000/* * lib/netfilter/log_msg_obj.c Netfilter Log Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #include #include #include #include /** @cond SKIP */ #define LOG_MSG_ATTR_FAMILY (1UL << 0) #define LOG_MSG_ATTR_HWPROTO (1UL << 1) #define LOG_MSG_ATTR_HOOK (1UL << 2) #define LOG_MSG_ATTR_MARK (1UL << 3) #define LOG_MSG_ATTR_TIMESTAMP (1UL << 4) #define LOG_MSG_ATTR_INDEV (1UL << 5) #define LOG_MSG_ATTR_OUTDEV (1UL << 6) #define LOG_MSG_ATTR_PHYSINDEV (1UL << 7) #define LOG_MSG_ATTR_PHYSOUTDEV (1UL << 8) #define LOG_MSG_ATTR_HWADDR (1UL << 9) #define LOG_MSG_ATTR_PAYLOAD (1UL << 10) #define LOG_MSG_ATTR_PREFIX (1UL << 11) #define LOG_MSG_ATTR_UID (1UL << 12) #define LOG_MSG_ATTR_GID (1UL << 13) #define LOG_MSG_ATTR_SEQ (1UL << 14) #define LOG_MSG_ATTR_SEQ_GLOBAL (1UL << 15) /** @endcond */ static void log_msg_free_data(struct nl_object *c) { struct nfnl_log_msg *msg = (struct nfnl_log_msg *) c; if (msg == NULL) return; free(msg->log_msg_payload); free(msg->log_msg_prefix); } static int log_msg_clone(struct nl_object *_dst, struct nl_object *_src) { struct nfnl_log_msg *dst = (struct nfnl_log_msg *) _dst; struct nfnl_log_msg *src = (struct nfnl_log_msg *) _src; int err; if (src->log_msg_payload) { err = nfnl_log_msg_set_payload(dst, src->log_msg_payload, src->log_msg_payload_len); if (err < 0) goto errout; } if (src->log_msg_prefix) { err = nfnl_log_msg_set_prefix(dst, src->log_msg_prefix); if (err < 0) goto errout; } return 0; errout: return err; } static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_log_msg *msg = (struct nfnl_log_msg *) a; struct nl_cache *link_cache; char buf[64]; link_cache = nl_cache_mngt_require_safe("route/link"); nl_new_line(p); if (msg->ce_mask & LOG_MSG_ATTR_PREFIX) nl_dump(p, "%s", msg->log_msg_prefix); if (msg->ce_mask & LOG_MSG_ATTR_INDEV) { if (link_cache) nl_dump(p, "IN=%s ", rtnl_link_i2name(link_cache, msg->log_msg_indev, buf, sizeof(buf))); else nl_dump(p, "IN=%d ", msg->log_msg_indev); } if (msg->ce_mask & LOG_MSG_ATTR_PHYSINDEV) { if (link_cache) nl_dump(p, "PHYSIN=%s ", rtnl_link_i2name(link_cache, msg->log_msg_physindev, buf, sizeof(buf))); else nl_dump(p, "IN=%d ", msg->log_msg_physindev); } if (msg->ce_mask & LOG_MSG_ATTR_OUTDEV) { if (link_cache) nl_dump(p, "OUT=%s ", rtnl_link_i2name(link_cache, msg->log_msg_outdev, buf, sizeof(buf))); else nl_dump(p, "OUT=%d ", msg->log_msg_outdev); } if (msg->ce_mask & LOG_MSG_ATTR_PHYSOUTDEV) { if (link_cache) nl_dump(p, "PHYSOUT=%s ", rtnl_link_i2name(link_cache, msg->log_msg_physoutdev, buf, sizeof(buf))); else nl_dump(p, "PHYSOUT=%d ", msg->log_msg_physoutdev); } if (msg->ce_mask & LOG_MSG_ATTR_HWADDR) { int i; nl_dump(p, "MAC"); for (i = 0; i < msg->log_msg_hwaddr_len; i++) nl_dump(p, "%c%02x", i?':':'=', msg->log_msg_hwaddr[i]); nl_dump(p, " "); } /* FIXME: parse the payload to get iptables LOG compatible format */ if (msg->ce_mask & LOG_MSG_ATTR_FAMILY) nl_dump(p, "FAMILY=%s ", nl_af2str(msg->log_msg_family, buf, sizeof(buf))); if (msg->ce_mask & LOG_MSG_ATTR_HWPROTO) nl_dump(p, "HWPROTO=%s ", nl_ether_proto2str(ntohs(msg->log_msg_hwproto), buf, sizeof(buf))); if (msg->ce_mask & LOG_MSG_ATTR_HOOK) nl_dump(p, "HOOK=%s ", nfnl_inet_hook2str(msg->log_msg_hook, buf, sizeof(buf))); if (msg->ce_mask & LOG_MSG_ATTR_MARK) nl_dump(p, "MARK=%u ", msg->log_msg_mark); if (msg->ce_mask & LOG_MSG_ATTR_PAYLOAD) nl_dump(p, "PAYLOADLEN=%d ", msg->log_msg_payload_len); if (msg->ce_mask & LOG_MSG_ATTR_UID) nl_dump(p, "UID=%u ", msg->log_msg_uid); if (msg->ce_mask & LOG_MSG_ATTR_GID) nl_dump(p, "GID=%u ", msg->log_msg_gid); if (msg->ce_mask & LOG_MSG_ATTR_SEQ) nl_dump(p, "SEQ=%d ", msg->log_msg_seq); if (msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL) nl_dump(p, "SEQGLOBAL=%d ", msg->log_msg_seq_global); nl_dump(p, "\n"); if (link_cache) nl_cache_put(link_cache); } /** * @name Allocation/Freeing * @{ */ struct nfnl_log_msg *nfnl_log_msg_alloc(void) { return (struct nfnl_log_msg *) nl_object_alloc(&log_msg_obj_ops); } void nfnl_log_msg_get(struct nfnl_log_msg *msg) { nl_object_get((struct nl_object *) msg); } void nfnl_log_msg_put(struct nfnl_log_msg *msg) { nl_object_put((struct nl_object *) msg); } /** @} */ /** * @name Attributes * @{ */ void nfnl_log_msg_set_family(struct nfnl_log_msg *msg, uint8_t family) { msg->log_msg_family = family; msg->ce_mask |= LOG_MSG_ATTR_FAMILY; } uint8_t nfnl_log_msg_get_family(const struct nfnl_log_msg *msg) { if (msg->ce_mask & LOG_MSG_ATTR_FAMILY) return msg->log_msg_family; else return AF_UNSPEC; } void nfnl_log_msg_set_hwproto(struct nfnl_log_msg *msg, uint16_t hwproto) { msg->log_msg_hwproto = hwproto; msg->ce_mask |= LOG_MSG_ATTR_HWPROTO; } int nfnl_log_msg_test_hwproto(const struct nfnl_log_msg *msg) { return !!(msg->ce_mask & LOG_MSG_ATTR_HWPROTO); } uint16_t nfnl_log_msg_get_hwproto(const struct nfnl_log_msg *msg) { return msg->log_msg_hwproto; } void nfnl_log_msg_set_hook(struct nfnl_log_msg *msg, uint8_t hook) { msg->log_msg_hook = hook; msg->ce_mask |= LOG_MSG_ATTR_HOOK; } int nfnl_log_msg_test_hook(const struct nfnl_log_msg *msg) { return !!(msg->ce_mask & LOG_MSG_ATTR_HOOK); } uint8_t nfnl_log_msg_get_hook(const struct nfnl_log_msg *msg) { return msg->log_msg_hook; } void nfnl_log_msg_set_mark(struct nfnl_log_msg *msg, uint32_t mark) { msg->log_msg_mark = mark; msg->ce_mask |= LOG_MSG_ATTR_MARK; } int nfnl_log_msg_test_mark(const struct nfnl_log_msg *msg) { return !!(msg->ce_mask & LOG_MSG_ATTR_MARK); } uint32_t nfnl_log_msg_get_mark(const struct nfnl_log_msg *msg) { return msg->log_msg_mark; } void nfnl_log_msg_set_timestamp(struct nfnl_log_msg *msg, struct timeval *tv) { msg->log_msg_timestamp.tv_sec = tv->tv_sec; msg->log_msg_timestamp.tv_usec = tv->tv_usec; msg->ce_mask |= LOG_MSG_ATTR_TIMESTAMP; } const struct timeval *nfnl_log_msg_get_timestamp(const struct nfnl_log_msg *msg) { if (!(msg->ce_mask & LOG_MSG_ATTR_TIMESTAMP)) return NULL; return &msg->log_msg_timestamp; } void nfnl_log_msg_set_indev(struct nfnl_log_msg *msg, uint32_t indev) { msg->log_msg_indev = indev; msg->ce_mask |= LOG_MSG_ATTR_INDEV; } uint32_t nfnl_log_msg_get_indev(const struct nfnl_log_msg *msg) { return msg->log_msg_indev; } void nfnl_log_msg_set_outdev(struct nfnl_log_msg *msg, uint32_t outdev) { msg->log_msg_outdev = outdev; msg->ce_mask |= LOG_MSG_ATTR_OUTDEV; } uint32_t nfnl_log_msg_get_outdev(const struct nfnl_log_msg *msg) { return msg->log_msg_outdev; } void nfnl_log_msg_set_physindev(struct nfnl_log_msg *msg, uint32_t physindev) { msg->log_msg_physindev = physindev; msg->ce_mask |= LOG_MSG_ATTR_PHYSINDEV; } uint32_t nfnl_log_msg_get_physindev(const struct nfnl_log_msg *msg) { return msg->log_msg_physindev; } void nfnl_log_msg_set_physoutdev(struct nfnl_log_msg *msg, uint32_t physoutdev) { msg->log_msg_physoutdev = physoutdev; msg->ce_mask |= LOG_MSG_ATTR_PHYSOUTDEV; } uint32_t nfnl_log_msg_get_physoutdev(const struct nfnl_log_msg *msg) { return msg->log_msg_physoutdev; } void nfnl_log_msg_set_hwaddr(struct nfnl_log_msg *msg, uint8_t *hwaddr, int len) { if (len > sizeof(msg->log_msg_hwaddr)) len = sizeof(msg->log_msg_hwaddr); msg->log_msg_hwaddr_len = len; memcpy(msg->log_msg_hwaddr, hwaddr, len); msg->ce_mask |= LOG_MSG_ATTR_HWADDR; } const uint8_t *nfnl_log_msg_get_hwaddr(const struct nfnl_log_msg *msg, int *len) { if (!(msg->ce_mask & LOG_MSG_ATTR_HWADDR)) { *len = 0; return NULL; } *len = msg->log_msg_hwaddr_len; return msg->log_msg_hwaddr; } int nfnl_log_msg_set_payload(struct nfnl_log_msg *msg, uint8_t *payload, int len) { free(msg->log_msg_payload); msg->log_msg_payload = malloc(len); if (!msg->log_msg_payload) return -NLE_NOMEM; memcpy(msg->log_msg_payload, payload, len); msg->log_msg_payload_len = len; msg->ce_mask |= LOG_MSG_ATTR_PAYLOAD; return 0; } const void *nfnl_log_msg_get_payload(const struct nfnl_log_msg *msg, int *len) { if (!(msg->ce_mask & LOG_MSG_ATTR_PAYLOAD)) { *len = 0; return NULL; } *len = msg->log_msg_payload_len; return msg->log_msg_payload; } int nfnl_log_msg_set_prefix(struct nfnl_log_msg *msg, void *prefix) { free(msg->log_msg_prefix); msg->log_msg_prefix = strdup(prefix); if (!msg->log_msg_prefix) return -NLE_NOMEM; msg->ce_mask |= LOG_MSG_ATTR_PREFIX; return 0; } const char *nfnl_log_msg_get_prefix(const struct nfnl_log_msg *msg) { return msg->log_msg_prefix; } void nfnl_log_msg_set_uid(struct nfnl_log_msg *msg, uint32_t uid) { msg->log_msg_uid = uid; msg->ce_mask |= LOG_MSG_ATTR_UID; } int nfnl_log_msg_test_uid(const struct nfnl_log_msg *msg) { return !!(msg->ce_mask & LOG_MSG_ATTR_UID); } uint32_t nfnl_log_msg_get_uid(const struct nfnl_log_msg *msg) { return msg->log_msg_uid; } void nfnl_log_msg_set_gid(struct nfnl_log_msg *msg, uint32_t gid) { msg->log_msg_gid = gid; msg->ce_mask |= LOG_MSG_ATTR_GID; } int nfnl_log_msg_test_gid(const struct nfnl_log_msg *msg) { return !!(msg->ce_mask & LOG_MSG_ATTR_GID); } uint32_t nfnl_log_msg_get_gid(const struct nfnl_log_msg *msg) { return msg->log_msg_gid; } void nfnl_log_msg_set_seq(struct nfnl_log_msg *msg, uint32_t seq) { msg->log_msg_seq = seq; msg->ce_mask |= LOG_MSG_ATTR_SEQ; } int nfnl_log_msg_test_seq(const struct nfnl_log_msg *msg) { return !!(msg->ce_mask & LOG_MSG_ATTR_SEQ); } uint32_t nfnl_log_msg_get_seq(const struct nfnl_log_msg *msg) { return msg->log_msg_seq; } void nfnl_log_msg_set_seq_global(struct nfnl_log_msg *msg, uint32_t seq_global) { msg->log_msg_seq_global = seq_global; msg->ce_mask |= LOG_MSG_ATTR_SEQ_GLOBAL; } int nfnl_log_msg_test_seq_global(const struct nfnl_log_msg *msg) { return !!(msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL); } uint32_t nfnl_log_msg_get_seq_global(const struct nfnl_log_msg *msg) { return msg->log_msg_seq_global; } /** @} */ struct nl_object_ops log_msg_obj_ops = { .oo_name = "netfilter/log_msg", .oo_size = sizeof(struct nfnl_log_msg), .oo_free_data = log_msg_free_data, .oo_clone = log_msg_clone, .oo_dump = { [NL_DUMP_LINE] = log_msg_dump, [NL_DUMP_DETAILS] = log_msg_dump, [NL_DUMP_STATS] = log_msg_dump, }, }; /** @} */ libnl-3.2.29/lib/netfilter/ct.c0000644000175000017500000004063213023014600013136 00000000000000/* * lib/netfilter/ct.c Conntrack * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c= 2008 Patrick McHardy */ /** * @ingroup nfnl * @defgroup ct Conntrack * @brief * @{ */ #include #include #include #include #include #include #include #include static struct nl_cache_ops nfnl_ct_ops; static struct nla_policy ct_policy[CTA_MAX+1] = { [CTA_TUPLE_ORIG] = { .type = NLA_NESTED }, [CTA_TUPLE_REPLY] = { .type = NLA_NESTED }, [CTA_STATUS] = { .type = NLA_U32 }, [CTA_PROTOINFO] = { .type = NLA_NESTED }, //[CTA_HELP] //[CTA_NAT_SRC] [CTA_TIMEOUT] = { .type = NLA_U32 }, [CTA_MARK] = { .type = NLA_U32 }, [CTA_COUNTERS_ORIG] = { .type = NLA_NESTED }, [CTA_COUNTERS_REPLY] = { .type = NLA_NESTED }, [CTA_USE] = { .type = NLA_U32 }, [CTA_ID] = { .type = NLA_U32 }, [CTA_ZONE] = { .type = NLA_U16 }, //[CTA_NAT_DST] }; static struct nla_policy ct_tuple_policy[CTA_TUPLE_MAX+1] = { [CTA_TUPLE_IP] = { .type = NLA_NESTED }, [CTA_TUPLE_PROTO] = { .type = NLA_NESTED }, }; static struct nla_policy ct_ip_policy[CTA_IP_MAX+1] = { [CTA_IP_V4_SRC] = { .type = NLA_U32 }, [CTA_IP_V4_DST] = { .type = NLA_U32 }, [CTA_IP_V6_SRC] = { .minlen = 16 }, [CTA_IP_V6_DST] = { .minlen = 16 }, }; static struct nla_policy ct_proto_policy[CTA_PROTO_MAX+1] = { [CTA_PROTO_NUM] = { .type = NLA_U8 }, [CTA_PROTO_SRC_PORT] = { .type = NLA_U16 }, [CTA_PROTO_DST_PORT] = { .type = NLA_U16 }, [CTA_PROTO_ICMP_ID] = { .type = NLA_U16 }, [CTA_PROTO_ICMP_TYPE] = { .type = NLA_U8 }, [CTA_PROTO_ICMP_CODE] = { .type = NLA_U8 }, [CTA_PROTO_ICMPV6_ID] = { .type = NLA_U16 }, [CTA_PROTO_ICMPV6_TYPE] = { .type = NLA_U8 }, [CTA_PROTO_ICMPV6_CODE] = { .type = NLA_U8 }, }; static struct nla_policy ct_protoinfo_policy[CTA_PROTOINFO_MAX+1] = { [CTA_PROTOINFO_TCP] = { .type = NLA_NESTED }, }; static struct nla_policy ct_protoinfo_tcp_policy[CTA_PROTOINFO_TCP_MAX+1] = { [CTA_PROTOINFO_TCP_STATE] = { .type = NLA_U8 }, [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 }, [CTA_PROTOINFO_TCP_WSCALE_REPLY] = { .type = NLA_U8 }, [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .minlen = 2 }, [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .minlen = 2 }, }; static struct nla_policy ct_counters_policy[CTA_COUNTERS_MAX+1] = { [CTA_COUNTERS_PACKETS] = { .type = NLA_U64 }, [CTA_COUNTERS_BYTES] = { .type = NLA_U64 }, [CTA_COUNTERS32_PACKETS]= { .type = NLA_U32 }, [CTA_COUNTERS32_BYTES] = { .type = NLA_U32 }, }; static struct nla_policy ct_timestamp_policy[CTA_TIMESTAMP_MAX + 1] = { [CTA_TIMESTAMP_START] = { .type = NLA_U64 }, [CTA_TIMESTAMP_STOP] = { .type = NLA_U64 }, }; static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) { struct nlattr *tb[CTA_IP_MAX+1]; struct nl_addr *addr; int err; err = nla_parse_nested(tb, CTA_IP_MAX, attr, ct_ip_policy); if (err < 0) goto errout; if (tb[CTA_IP_V4_SRC]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V4_SRC], AF_INET); if (addr == NULL) goto errout_enomem; err = nfnl_ct_set_src(ct, repl, addr); nl_addr_put(addr); if (err < 0) goto errout; } if (tb[CTA_IP_V4_DST]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V4_DST], AF_INET); if (addr == NULL) goto errout_enomem; err = nfnl_ct_set_dst(ct, repl, addr); nl_addr_put(addr); if (err < 0) goto errout; } if (tb[CTA_IP_V6_SRC]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V6_SRC], AF_INET6); if (addr == NULL) goto errout_enomem; err = nfnl_ct_set_src(ct, repl, addr); nl_addr_put(addr); if (err < 0) goto errout; } if (tb[CTA_IP_V6_DST]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V6_DST], AF_INET6); if (addr == NULL) goto errout_enomem; err = nfnl_ct_set_dst(ct, repl, addr); nl_addr_put(addr); if (err < 0) goto errout; } return 0; errout_enomem: err = -NLE_NOMEM; errout: return err; } static int ct_parse_proto(struct nfnl_ct *ct, int repl, struct nlattr *attr) { struct nlattr *tb[CTA_PROTO_MAX+1]; int err; err = nla_parse_nested(tb, CTA_PROTO_MAX, attr, ct_proto_policy); if (err < 0) return err; if (!repl && tb[CTA_PROTO_NUM]) nfnl_ct_set_proto(ct, nla_get_u8(tb[CTA_PROTO_NUM])); if (tb[CTA_PROTO_SRC_PORT]) nfnl_ct_set_src_port(ct, repl, ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT]))); if (tb[CTA_PROTO_DST_PORT]) nfnl_ct_set_dst_port(ct, repl, ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT]))); if (ct->ct_family == AF_INET) { if (tb[CTA_PROTO_ICMP_ID]) nfnl_ct_set_icmp_id(ct, repl, ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID]))); if (tb[CTA_PROTO_ICMP_TYPE]) nfnl_ct_set_icmp_type(ct, repl, nla_get_u8(tb[CTA_PROTO_ICMP_TYPE])); if (tb[CTA_PROTO_ICMP_CODE]) nfnl_ct_set_icmp_code(ct, repl, nla_get_u8(tb[CTA_PROTO_ICMP_CODE])); } else if (ct->ct_family == AF_INET6) { if (tb[CTA_PROTO_ICMPV6_ID]) nfnl_ct_set_icmp_id(ct, repl, ntohs(nla_get_u16(tb[CTA_PROTO_ICMPV6_ID]))); if (tb[CTA_PROTO_ICMPV6_TYPE]) nfnl_ct_set_icmp_type(ct, repl, nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE])); if (tb[CTA_PROTO_ICMPV6_CODE]) nfnl_ct_set_icmp_code(ct, repl, nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE])); } return 0; } static int ct_parse_tuple(struct nfnl_ct *ct, int repl, struct nlattr *attr) { struct nlattr *tb[CTA_TUPLE_MAX+1]; int err; err = nla_parse_nested(tb, CTA_TUPLE_MAX, attr, ct_tuple_policy); if (err < 0) return err; if (tb[CTA_TUPLE_IP]) { err = ct_parse_ip(ct, repl, tb[CTA_TUPLE_IP]); if (err < 0) return err; } if (tb[CTA_TUPLE_PROTO]) { err = ct_parse_proto(ct, repl, tb[CTA_TUPLE_PROTO]); if (err < 0) return err; } return 0; } static int ct_parse_protoinfo_tcp(struct nfnl_ct *ct, struct nlattr *attr) { struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1]; int err; err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, ct_protoinfo_tcp_policy); if (err < 0) return err; if (tb[CTA_PROTOINFO_TCP_STATE]) nfnl_ct_set_tcp_state(ct, nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE])); return 0; } static int ct_parse_protoinfo(struct nfnl_ct *ct, struct nlattr *attr) { struct nlattr *tb[CTA_PROTOINFO_MAX+1]; int err; err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, ct_protoinfo_policy); if (err < 0) return err; if (tb[CTA_PROTOINFO_TCP]) { err = ct_parse_protoinfo_tcp(ct, tb[CTA_PROTOINFO_TCP]); if (err < 0) return err; } return 0; } static int ct_parse_counters(struct nfnl_ct *ct, int repl, struct nlattr *attr) { struct nlattr *tb[CTA_COUNTERS_MAX+1]; int err; err = nla_parse_nested(tb, CTA_COUNTERS_MAX, attr, ct_counters_policy); if (err < 0) return err; if (tb[CTA_COUNTERS_PACKETS]) nfnl_ct_set_packets(ct, repl, ntohll(nla_get_u64(tb[CTA_COUNTERS_PACKETS]))); if (tb[CTA_COUNTERS32_PACKETS]) nfnl_ct_set_packets(ct, repl, ntohl(nla_get_u32(tb[CTA_COUNTERS32_PACKETS]))); if (tb[CTA_COUNTERS_BYTES]) nfnl_ct_set_bytes(ct, repl, ntohll(nla_get_u64(tb[CTA_COUNTERS_BYTES]))); if (tb[CTA_COUNTERS32_BYTES]) nfnl_ct_set_bytes(ct, repl, ntohl(nla_get_u32(tb[CTA_COUNTERS32_BYTES]))); return 0; } int nfnlmsg_ct_group(struct nlmsghdr *nlh) { switch (nfnlmsg_subtype(nlh)) { case IPCTNL_MSG_CT_NEW: if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL)) return NFNLGRP_CONNTRACK_NEW; else return NFNLGRP_CONNTRACK_UPDATE; case IPCTNL_MSG_CT_DELETE: return NFNLGRP_CONNTRACK_DESTROY; default: return NFNLGRP_NONE; } } static int ct_parse_timestamp(struct nfnl_ct *ct, struct nlattr *attr) { struct nlattr *tb[CTA_TIMESTAMP_MAX + 1]; int err; err = nla_parse_nested(tb, CTA_TIMESTAMP_MAX, attr, ct_timestamp_policy); if (err < 0) return err; if (tb[CTA_TIMESTAMP_START] && tb[CTA_TIMESTAMP_STOP]) nfnl_ct_set_timestamp(ct, ntohll(nla_get_u64(tb[CTA_TIMESTAMP_START])), ntohll(nla_get_u64(tb[CTA_TIMESTAMP_STOP]))); return 0; } int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result) { struct nfnl_ct *ct; struct nlattr *tb[CTA_MAX+1]; int err; ct = nfnl_ct_alloc(); if (!ct) return -NLE_NOMEM; ct->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX, ct_policy); if (err < 0) goto errout; nfnl_ct_set_family(ct, nfnlmsg_family(nlh)); if (tb[CTA_TUPLE_ORIG]) { err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]); if (err < 0) goto errout; } if (tb[CTA_TUPLE_REPLY]) { err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]); if (err < 0) goto errout; } if (tb[CTA_PROTOINFO]) { err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]); if (err < 0) goto errout; } if (tb[CTA_STATUS]) nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS]))); if (tb[CTA_TIMEOUT]) nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT]))); if (tb[CTA_MARK]) nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK]))); if (tb[CTA_USE]) nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE]))); if (tb[CTA_ID]) nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID]))); if (tb[CTA_ZONE]) nfnl_ct_set_zone(ct, ntohs(nla_get_u16(tb[CTA_ZONE]))); if (tb[CTA_COUNTERS_ORIG]) { err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]); if (err < 0) goto errout; } if (tb[CTA_COUNTERS_REPLY]) { err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]); if (err < 0) goto errout; } if (tb[CTA_TIMESTAMP]) { err = ct_parse_timestamp(ct, tb[CTA_TIMESTAMP]); if (err < 0) goto errout; } *result = ct; return 0; errout: nfnl_ct_put(ct); return err; } static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct nfnl_ct *ct; int err; if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0) return err; err = pp->pp_cb((struct nl_object *) ct, pp); nfnl_ct_put(ct); return err; } /** * Send nfnl ct dump request * @arg sk Netlink socket. * * @return 0 on success or a negative error code. Due to a bug, this function * returns the number of bytes sent. Treat any non-negative number as success. */ int nfnl_ct_dump_request(struct nl_sock *sk) { return nfnl_send_simple(sk, NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET, NLM_F_DUMP, AF_UNSPEC, 0); } static int ct_request_update(struct nl_cache *cache, struct nl_sock *sk) { return nfnl_ct_dump_request(sk); } static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct, int repl) { struct nlattr *tuple, *ip, *proto; struct nl_addr *addr; int family; family = nfnl_ct_get_family(ct); tuple = nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG); if (!tuple) goto nla_put_failure; ip = nla_nest_start(msg, CTA_TUPLE_IP); if (!ip) goto nla_put_failure; addr = nfnl_ct_get_src(ct, repl); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC, addr); addr = nfnl_ct_get_dst(ct, repl); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST, addr); nla_nest_end(msg, ip); proto = nla_nest_start(msg, CTA_TUPLE_PROTO); if (!proto) goto nla_put_failure; if (nfnl_ct_test_proto(ct)) NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_ct_get_proto(ct)); if (nfnl_ct_test_src_port(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT, htons(nfnl_ct_get_src_port(ct, repl))); if (nfnl_ct_test_dst_port(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_DST_PORT, htons(nfnl_ct_get_dst_port(ct, repl))); if (family == AF_INET) { if (nfnl_ct_test_icmp_id(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID, htons(nfnl_ct_get_icmp_id(ct, repl))); if (nfnl_ct_test_icmp_type(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE, nfnl_ct_get_icmp_type(ct, repl)); if (nfnl_ct_test_icmp_code(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE, nfnl_ct_get_icmp_code(ct, repl)); } else if (family == AF_INET6) { if (nfnl_ct_test_icmp_id(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_ICMPV6_ID, htons(nfnl_ct_get_icmp_id(ct, repl))); if (nfnl_ct_test_icmp_type(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMPV6_TYPE, nfnl_ct_get_icmp_type(ct, repl)); if (nfnl_ct_test_icmp_code(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMPV6_CODE, nfnl_ct_get_icmp_code(ct, repl)); } nla_nest_end(msg, proto); nla_nest_end(msg, tuple); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; int err; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags, nfnl_ct_get_family(ct), 0); if (msg == NULL) return -NLE_NOMEM; if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0) goto err_out; /* REPLY tuple is optional, dont add unless at least src/dst specified */ if ( nfnl_ct_get_src(ct, 1) && nfnl_ct_get_dst(ct, 1) ) if ((err = nfnl_ct_build_tuple(msg, ct, 1)) < 0) goto err_out; if (nfnl_ct_test_status(ct)) NLA_PUT_U32(msg, CTA_STATUS, htonl(nfnl_ct_get_status(ct))); if (nfnl_ct_test_timeout(ct)) NLA_PUT_U32(msg, CTA_TIMEOUT, htonl(nfnl_ct_get_timeout(ct))); if (nfnl_ct_test_mark(ct)) NLA_PUT_U32(msg, CTA_MARK, htonl(nfnl_ct_get_mark(ct))); if (nfnl_ct_test_id(ct)) NLA_PUT_U32(msg, CTA_ID, htonl(nfnl_ct_get_id(ct))); if (nfnl_ct_test_zone(ct)) NLA_PUT_U16(msg, CTA_ZONE, htons(nfnl_ct_get_zone(ct))); *result = msg; return 0; nla_put_failure: err_out: nlmsg_free(msg); return err; } int nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags, struct nl_msg **result) { return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result); } int nfnl_ct_add(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } int nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags, struct nl_msg **result) { return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result); } int nfnl_ct_del(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } int nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags, struct nl_msg **result) { return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result); } int nfnl_ct_query(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** * @name Cache Management * @{ */ /** * Build a conntrack cache holding all conntrack currently in the kernel * @arg sk Netlink socket. * @arg result Pointer to store resulting cache. * * Allocates a new cache, initializes it properly and updates it to * contain all conntracks currently in the kernel. * * @return 0 on success or a negative error code. */ int nfnl_ct_alloc_cache(struct nl_sock *sk, struct nl_cache **result) { return nl_cache_alloc_and_fill(&nfnl_ct_ops, sk, result); } /** @} */ /** * @name Conntrack Addition * @{ */ /** @} */ static struct nl_af_group ct_groups[] = { { AF_UNSPEC, NFNLGRP_CONNTRACK_NEW }, { AF_UNSPEC, NFNLGRP_CONNTRACK_UPDATE }, { AF_UNSPEC, NFNLGRP_CONNTRACK_DESTROY }, { END_OF_GROUP_LIST }, }; #define NFNLMSG_CT_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_CTNETLINK, (type)) static struct nl_cache_ops nfnl_ct_ops = { .co_name = "netfilter/ct", .co_hdrsize = NFNL_HDRLEN, .co_msgtypes = { { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_NEW), NL_ACT_NEW, "new" }, { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_GET), NL_ACT_GET, "get" }, { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_DELETE), NL_ACT_DEL, "del" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_NETFILTER, .co_groups = ct_groups, .co_request_update = ct_request_update, .co_msg_parser = ct_msg_parser, .co_obj_ops = &ct_obj_ops, }; static void __init ct_init(void) { nl_cache_mngt_register(&nfnl_ct_ops); } static void __exit ct_exit(void) { nl_cache_mngt_unregister(&nfnl_ct_ops); } /** @} */ libnl-3.2.29/lib/netfilter/queue_msg.c0000644000175000017500000001645213023014600014525 00000000000000/* * lib/netfilter/queue_msg.c Netfilter Queue Messages * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy * Copyright (c) 2010 Karl Hiramoto */ /** * @ingroup nfnl * @defgroup queue Queue * @brief * @{ */ #include #include #include #include #include #include #include static struct nl_cache_ops nfnl_queue_msg_ops; static struct nla_policy queue_policy[NFQA_MAX+1] = { [NFQA_PACKET_HDR] = { .minlen = sizeof(struct nfqnl_msg_packet_hdr), }, [NFQA_VERDICT_HDR] = { .minlen = sizeof(struct nfqnl_msg_verdict_hdr), }, [NFQA_MARK] = { .type = NLA_U32 }, [NFQA_TIMESTAMP] = { .minlen = sizeof(struct nfqnl_msg_packet_timestamp), }, [NFQA_IFINDEX_INDEV] = { .type = NLA_U32 }, [NFQA_IFINDEX_OUTDEV] = { .type = NLA_U32 }, [NFQA_IFINDEX_PHYSINDEV] = { .type = NLA_U32 }, [NFQA_IFINDEX_PHYSOUTDEV] = { .type = NLA_U32 }, [NFQA_HWADDR] = { .minlen = sizeof(struct nfqnl_msg_packet_hw), }, }; int nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh, struct nfnl_queue_msg **result) { struct nfnl_queue_msg *msg; struct nlattr *tb[NFQA_MAX+1]; struct nlattr *attr; int err; msg = nfnl_queue_msg_alloc(); if (!msg) return -NLE_NOMEM; msg->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFQA_MAX, queue_policy); if (err < 0) goto errout; nfnl_queue_msg_set_group(msg, nfnlmsg_res_id(nlh)); nfnl_queue_msg_set_family(msg, nfnlmsg_family(nlh)); attr = tb[NFQA_PACKET_HDR]; if (attr) { struct nfqnl_msg_packet_hdr *hdr = nla_data(attr); nfnl_queue_msg_set_packetid(msg, ntohl(hdr->packet_id)); if (hdr->hw_protocol) nfnl_queue_msg_set_hwproto(msg, hdr->hw_protocol); nfnl_queue_msg_set_hook(msg, hdr->hook); } attr = tb[NFQA_MARK]; if (attr) nfnl_queue_msg_set_mark(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_TIMESTAMP]; if (attr) { struct nfqnl_msg_packet_timestamp *timestamp = nla_data(attr); struct timeval tv; tv.tv_sec = ntohll(timestamp->sec); tv.tv_usec = ntohll(timestamp->usec); nfnl_queue_msg_set_timestamp(msg, &tv); } attr = tb[NFQA_IFINDEX_INDEV]; if (attr) nfnl_queue_msg_set_indev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_IFINDEX_OUTDEV]; if (attr) nfnl_queue_msg_set_outdev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_IFINDEX_PHYSINDEV]; if (attr) nfnl_queue_msg_set_physindev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_IFINDEX_PHYSOUTDEV]; if (attr) nfnl_queue_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_HWADDR]; if (attr) { struct nfqnl_msg_packet_hw *hw = nla_data(attr); nfnl_queue_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen)); } attr = tb[NFQA_PAYLOAD]; if (attr) { err = nfnl_queue_msg_set_payload(msg, nla_data(attr), nla_len(attr)); if (err < 0) goto errout; } *result = msg; return 0; errout: nfnl_queue_msg_put(msg); return err; } static int queue_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct nfnl_queue_msg *msg; int err; if ((err = nfnlmsg_queue_msg_parse(nlh, &msg)) < 0) return err; err = pp->pp_cb((struct nl_object *) msg, pp); nfnl_queue_msg_put(msg); return err; } /** @} */ static struct nl_msg * __nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *msg, uint8_t type) { struct nl_msg *nlmsg; struct nfqnl_msg_verdict_hdr verdict; nlmsg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, type, 0, nfnl_queue_msg_get_family(msg), nfnl_queue_msg_get_group(msg)); if (nlmsg == NULL) return NULL; verdict.id = htonl(nfnl_queue_msg_get_packetid(msg)); verdict.verdict = htonl(nfnl_queue_msg_get_verdict(msg)); if (nla_put(nlmsg, NFQA_VERDICT_HDR, sizeof(verdict), &verdict) < 0) goto nla_put_failure; if (nfnl_queue_msg_test_mark(msg) && nla_put_u32(nlmsg, NFQA_MARK, ntohl(nfnl_queue_msg_get_mark(msg))) < 0) goto nla_put_failure; return nlmsg; nla_put_failure: nlmsg_free(nlmsg); return NULL; } struct nl_msg * nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *msg) { return __nfnl_queue_msg_build_verdict(msg, NFQNL_MSG_VERDICT); } struct nl_msg * nfnl_queue_msg_build_verdict_batch(const struct nfnl_queue_msg *msg) { return __nfnl_queue_msg_build_verdict(msg, NFQNL_MSG_VERDICT_BATCH); } /** * Send a message verdict/mark * @arg nlh netlink messsage header * @arg msg queue msg * @return 0 on OK or error code */ int nfnl_queue_msg_send_verdict(struct nl_sock *nlh, const struct nfnl_queue_msg *msg) { struct nl_msg *nlmsg; int err; nlmsg = nfnl_queue_msg_build_verdict(msg); if (nlmsg == NULL) return -NLE_NOMEM; err = nl_send_auto_complete(nlh, nlmsg); nlmsg_free(nlmsg); if (err < 0) return err; return wait_for_ack(nlh); } /** * Send a message batched verdict/mark * @arg nlh netlink messsage header * @arg msg queue msg * @return 0 on OK or error code */ int nfnl_queue_msg_send_verdict_batch(struct nl_sock *nlh, const struct nfnl_queue_msg *msg) { struct nl_msg *nlmsg; int err; nlmsg = nfnl_queue_msg_build_verdict_batch(msg); if (nlmsg == NULL) return -NLE_NOMEM; err = nl_send_auto_complete(nlh, nlmsg); nlmsg_free(nlmsg); if (err < 0) return err; return wait_for_ack(nlh); } /** * Send a message verdict including the payload * @arg nlh netlink messsage header * @arg msg queue msg * @arg payload_data packet payload data * @arg payload_len payload length * @return 0 on OK or error code */ int nfnl_queue_msg_send_verdict_payload(struct nl_sock *nlh, const struct nfnl_queue_msg *msg, const void *payload_data, unsigned payload_len) { struct nl_msg *nlmsg; int err; struct iovec iov[3]; struct nlattr nla; nlmsg = nfnl_queue_msg_build_verdict(msg); if (nlmsg == NULL) return -NLE_NOMEM; memset(iov, 0, sizeof(iov)); iov[0].iov_base = (void *) nlmsg_hdr(nlmsg); iov[0].iov_len = nlmsg_hdr(nlmsg)->nlmsg_len; nla.nla_type = NFQA_PAYLOAD; nla.nla_len = payload_len + sizeof(nla); nlmsg_hdr(nlmsg)->nlmsg_len += nla.nla_len; iov[1].iov_base = (void *) &nla; iov[1].iov_len = sizeof(nla); iov[2].iov_base = (void *) payload_data; iov[2].iov_len = NLA_ALIGN(payload_len); nl_complete_msg(nlh, nlmsg); err = nl_send_iovec(nlh, nlmsg, iov, 3); nlmsg_free(nlmsg); if (err < 0) return err; return wait_for_ack(nlh); } #define NFNLMSG_QUEUE_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_QUEUE, (type)) static struct nl_cache_ops nfnl_queue_msg_ops = { .co_name = "netfilter/queue_msg", .co_hdrsize = NFNL_HDRLEN, .co_msgtypes = { { NFNLMSG_QUEUE_TYPE(NFQNL_MSG_PACKET), NL_ACT_NEW, "new" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_NETFILTER, .co_msg_parser = queue_msg_parser, .co_obj_ops = &queue_msg_obj_ops, }; static void __init nfnl_msg_queue_init(void) { nl_cache_mngt_register(&nfnl_queue_msg_ops); } static void __exit nfnl_queue_msg_exit(void) { nl_cache_mngt_unregister(&nfnl_queue_msg_ops); } /** @} */ libnl-3.2.29/lib/netfilter/log_obj.c0000644000175000017500000001576513023014600014154 00000000000000/* * lib/netfilter/log_obj.c Netfilter Log Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2008 Patrick McHardy */ #include #include #include /** @cond SKIP */ #define LOG_ATTR_GROUP (1UL << 0) #define LOG_ATTR_COPY_MODE (1UL << 1) #define LOG_ATTR_COPY_RANGE (1UL << 3) #define LOG_ATTR_FLUSH_TIMEOUT (1UL << 4) #define LOG_ATTR_ALLOC_SIZE (1UL << 5) #define LOG_ATTR_QUEUE_THRESHOLD (1UL << 6) /** @endcond */ static void nfnl_log_dump(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_log *log = (struct nfnl_log *) a; char buf[64]; nl_new_line(p); if (log->ce_mask & LOG_ATTR_GROUP) nl_dump(p, "group=%u ", log->log_group); if (log->ce_mask & LOG_ATTR_COPY_MODE) nl_dump(p, "copy_mode=%s ", nfnl_log_copy_mode2str(log->log_copy_mode, buf, sizeof(buf))); if (log->ce_mask & LOG_ATTR_COPY_RANGE) nl_dump(p, "copy_range=%u ", log->log_copy_range); if (log->ce_mask & LOG_ATTR_FLUSH_TIMEOUT) nl_dump(p, "flush_timeout=%u ", log->log_flush_timeout); if (log->ce_mask & LOG_ATTR_ALLOC_SIZE) nl_dump(p, "alloc_size=%u ", log->log_alloc_size); if (log->ce_mask & LOG_ATTR_QUEUE_THRESHOLD) nl_dump(p, "queue_threshold=%u ", log->log_queue_threshold); nl_dump(p, "\n"); } static const struct trans_tbl copy_modes[] = { __ADD(NFNL_LOG_COPY_NONE, none), __ADD(NFNL_LOG_COPY_META, meta), __ADD(NFNL_LOG_COPY_PACKET, packet), }; char *nfnl_log_copy_mode2str(enum nfnl_log_copy_mode copy_mode, char *buf, size_t len) { return __type2str(copy_mode, buf, len, copy_modes, ARRAY_SIZE(copy_modes)); } int nfnl_log_str2copy_mode(const char *name) { return __str2type(name, copy_modes, ARRAY_SIZE(copy_modes)); } /** * @name Allocation/Freeing * @{ */ struct nfnl_log *nfnl_log_alloc(void) { return (struct nfnl_log *) nl_object_alloc(&log_obj_ops); } void nfnl_log_get(struct nfnl_log *log) { nl_object_get((struct nl_object *) log); } void nfnl_log_put(struct nfnl_log *log) { nl_object_put((struct nl_object *) log); } /** @} */ /** * @name Attributes * @{ */ void nfnl_log_set_group(struct nfnl_log *log, uint16_t group) { log->log_group = group; log->ce_mask |= LOG_ATTR_GROUP; } int nfnl_log_test_group(const struct nfnl_log *log) { return !!(log->ce_mask & LOG_ATTR_GROUP); } uint16_t nfnl_log_get_group(const struct nfnl_log *log) { return log->log_group; } void nfnl_log_set_copy_mode(struct nfnl_log *log, enum nfnl_log_copy_mode mode) { log->log_copy_mode = mode; log->ce_mask |= LOG_ATTR_COPY_MODE; } int nfnl_log_test_copy_mode(const struct nfnl_log *log) { return !!(log->ce_mask & LOG_ATTR_COPY_MODE); } enum nfnl_log_copy_mode nfnl_log_get_copy_mode(const struct nfnl_log *log) { return log->log_copy_mode; } void nfnl_log_set_copy_range(struct nfnl_log *log, uint32_t copy_range) { log->log_copy_range = copy_range; log->ce_mask |= LOG_ATTR_COPY_RANGE; } int nfnl_log_test_copy_range(const struct nfnl_log *log) { return !!(log->ce_mask & LOG_ATTR_COPY_RANGE); } uint32_t nfnl_log_get_copy_range(const struct nfnl_log *log) { return log->log_copy_range; } void nfnl_log_set_flush_timeout(struct nfnl_log *log, uint32_t timeout) { log->log_flush_timeout = timeout; log->ce_mask |= LOG_ATTR_FLUSH_TIMEOUT; } int nfnl_log_test_flush_timeout(const struct nfnl_log *log) { return !!(log->ce_mask & LOG_ATTR_FLUSH_TIMEOUT); } uint32_t nfnl_log_get_flush_timeout(const struct nfnl_log *log) { return log->log_flush_timeout; } void nfnl_log_set_alloc_size(struct nfnl_log *log, uint32_t alloc_size) { log->log_alloc_size = alloc_size; log->ce_mask |= LOG_ATTR_ALLOC_SIZE; } int nfnl_log_test_alloc_size(const struct nfnl_log *log) { return !!(log->ce_mask & LOG_ATTR_ALLOC_SIZE); } uint32_t nfnl_log_get_alloc_size(const struct nfnl_log *log) { return log->log_alloc_size; } void nfnl_log_set_queue_threshold(struct nfnl_log *log, uint32_t threshold) { log->log_queue_threshold = threshold; log->ce_mask |= LOG_ATTR_QUEUE_THRESHOLD; } int nfnl_log_test_queue_threshold(const struct nfnl_log *log) { return !!(log->ce_mask & LOG_ATTR_QUEUE_THRESHOLD); } uint32_t nfnl_log_get_queue_threshold(const struct nfnl_log *log) { return log->log_queue_threshold; } /* We don't actually use the flags for anything yet since the * nfnetlog_log interface truly sucks - it only contains the * flag value, but not mask, so we would have to make assumptions * about the supported flags. */ void nfnl_log_set_flags(struct nfnl_log *log, unsigned int flags) { log->log_flags |= flags; log->log_flag_mask |= flags; } void nfnl_log_unset_flags(struct nfnl_log *log, unsigned int flags) { log->log_flags &= ~flags; log->log_flag_mask |= flags; } static const struct trans_tbl log_flags[] = { __ADD(NFNL_LOG_FLAG_SEQ, seq), __ADD(NFNL_LOG_FLAG_SEQ_GLOBAL, seq_global), }; char *nfnl_log_flags2str(unsigned int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, log_flags, ARRAY_SIZE(log_flags)); } unsigned int nfnl_log_str2flags(const char *name) { return __str2flags(name, log_flags, ARRAY_SIZE(log_flags)); } static uint64_t nfnl_log_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct nfnl_log *a = (struct nfnl_log *) _a; struct nfnl_log *b = (struct nfnl_log *) _b; uint64_t diff = 0; #define NFNL_LOG_DIFF(ATTR, EXPR) \ ATTR_DIFF(attrs, LOG_ATTR_##ATTR, a, b, EXPR) #define NFNL_LOG_DIFF_VAL(ATTR, FIELD) \ NFNL_LOG_DIFF(ATTR, a->FIELD != b->FIELD) diff |= NFNL_LOG_DIFF_VAL(GROUP, log_group); diff |= NFNL_LOG_DIFF_VAL(COPY_MODE, log_copy_mode); diff |= NFNL_LOG_DIFF_VAL(COPY_RANGE, log_copy_range); diff |= NFNL_LOG_DIFF_VAL(FLUSH_TIMEOUT, log_flush_timeout); diff |= NFNL_LOG_DIFF_VAL(ALLOC_SIZE, log_alloc_size); diff |= NFNL_LOG_DIFF_VAL(QUEUE_THRESHOLD, log_queue_threshold); #undef NFNL_LOG_DIFF #undef NFNL_LOG_DIFF_VAL return diff; } static const struct trans_tbl nfnl_log_attrs[] = { __ADD(LOG_ATTR_GROUP, group), __ADD(LOG_ATTR_COPY_MODE, copy_mode), __ADD(LOG_ATTR_COPY_RANGE, copy_range), __ADD(LOG_ATTR_FLUSH_TIMEOUT, flush_timeout), __ADD(LOG_ATTR_ALLOC_SIZE, alloc_size), __ADD(LOG_ATTR_QUEUE_THRESHOLD, queue_threshold), }; static char *nfnl_log_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, nfnl_log_attrs, ARRAY_SIZE(nfnl_log_attrs)); } /** @} */ struct nl_object_ops log_obj_ops = { .oo_name = "netfilter/log", .oo_size = sizeof(struct nfnl_log), .oo_dump = { [NL_DUMP_LINE] = nfnl_log_dump, [NL_DUMP_DETAILS] = nfnl_log_dump, [NL_DUMP_STATS] = nfnl_log_dump, }, .oo_compare = nfnl_log_compare, .oo_attrs2str = nfnl_log_attrs2str, .oo_id_attrs = LOG_ATTR_GROUP, }; /** @} */ libnl-3.2.29/lib/netfilter/log_msg.c0000644000175000017500000001127313023014600014156 00000000000000/* * lib/netfilter/log_msg.c Netfilter Log Message * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2008 Patrick McHardy */ /** * @ingroup nfnl * @defgroup log Log * @brief * @{ */ #include #include #include #include #include #include #include static struct nla_policy log_msg_policy[NFULA_MAX+1] = { [NFULA_PACKET_HDR] = { .minlen = sizeof(struct nfulnl_msg_packet_hdr) }, [NFULA_MARK] = { .type = NLA_U32 }, [NFULA_TIMESTAMP] = { .minlen = sizeof(struct nfulnl_msg_packet_timestamp) }, [NFULA_IFINDEX_INDEV] = { .type = NLA_U32 }, [NFULA_IFINDEX_OUTDEV] = { .type = NLA_U32 }, [NFULA_IFINDEX_PHYSINDEV] = { .type = NLA_U32 }, [NFULA_IFINDEX_PHYSOUTDEV] = { .type = NLA_U32 }, [NFULA_HWADDR] = { .minlen = sizeof(struct nfulnl_msg_packet_hw) }, //[NFULA_PAYLOAD] [NFULA_PREFIX] = { .type = NLA_STRING, }, [NFULA_UID] = { .type = NLA_U32 }, [NFULA_GID] = { .type = NLA_U32 }, [NFULA_SEQ] = { .type = NLA_U32 }, [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 }, }; int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result) { struct nfnl_log_msg *msg; struct nlattr *tb[NFULA_MAX+1]; struct nlattr *attr; int err; msg = nfnl_log_msg_alloc(); if (!msg) return -NLE_NOMEM; msg->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX, log_msg_policy); if (err < 0) goto errout; nfnl_log_msg_set_family(msg, nfnlmsg_family(nlh)); attr = tb[NFULA_PACKET_HDR]; if (attr) { struct nfulnl_msg_packet_hdr *hdr = nla_data(attr); if (hdr->hw_protocol) nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol); nfnl_log_msg_set_hook(msg, hdr->hook); } attr = tb[NFULA_MARK]; if (attr) nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_TIMESTAMP]; if (attr) { struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr); struct timeval tv; tv.tv_sec = ntohll(timestamp->sec); tv.tv_usec = ntohll(timestamp->usec); nfnl_log_msg_set_timestamp(msg, &tv); } attr = tb[NFULA_IFINDEX_INDEV]; if (attr) nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_IFINDEX_OUTDEV]; if (attr) nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_IFINDEX_PHYSINDEV]; if (attr) nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_IFINDEX_PHYSOUTDEV]; if (attr) nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_HWADDR]; if (attr) { struct nfulnl_msg_packet_hw *hw = nla_data(attr); nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen)); } attr = tb[NFULA_PAYLOAD]; if (attr) { err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr)); if (err < 0) goto errout; } attr = tb[NFULA_PREFIX]; if (attr) { err = nfnl_log_msg_set_prefix(msg, nla_data(attr)); if (err < 0) goto errout; } attr = tb[NFULA_UID]; if (attr) nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_GID]; if (attr) nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_SEQ]; if (attr) nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr))); attr = tb[NFULA_SEQ_GLOBAL]; if (attr) nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr))); *result = msg; return 0; errout: nfnl_log_msg_put(msg); return err; } static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct nfnl_log_msg *msg; int err; if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0) return err; err = pp->pp_cb((struct nl_object *) msg, pp); nfnl_log_msg_put(msg); return err; } /** @} */ #define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type)) static struct nl_cache_ops nfnl_log_msg_ops = { .co_name = "netfilter/log_msg", .co_hdrsize = NFNL_HDRLEN, .co_msgtypes = { { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_NETFILTER, .co_msg_parser = log_msg_parser, .co_obj_ops = &log_msg_obj_ops, }; static void __init log_msg_init(void) { nl_cache_mngt_register(&nfnl_log_msg_ops); } static void __exit log_msg_exit(void) { nl_cache_mngt_unregister(&nfnl_log_msg_ops); } /** @} */ libnl-3.2.29/lib/netfilter/netfilter.c0000644000175000017500000000277713023014600014534 00000000000000/* * lib/netfilter/netfilter.c Netfilter Generic Functions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008 Patrick McHardy */ #include #include #include static const struct trans_tbl nfnl_verdicts[] = { __ADD(NF_DROP, NF_DROP), __ADD(NF_ACCEPT, NF_ACCEPT), __ADD(NF_STOLEN, NF_STOLEN), __ADD(NF_QUEUE, NF_QUEUE), __ADD(NF_REPEAT, NF_REPEAT), __ADD(NF_STOP, NF_STOP), }; char *nfnl_verdict2str(unsigned int verdict, char *buf, size_t len) { return __type2str(verdict, buf, len, nfnl_verdicts, ARRAY_SIZE(nfnl_verdicts)); } unsigned int nfnl_str2verdict(const char *name) { return __str2type(name, nfnl_verdicts, ARRAY_SIZE(nfnl_verdicts)); } static const struct trans_tbl nfnl_inet_hooks[] = { __ADD(NF_INET_PRE_ROUTING, NF_INET_PREROUTING), __ADD(NF_INET_LOCAL_IN, NF_INET_LOCAL_IN), __ADD(NF_INET_FORWARD, NF_INET_FORWARD), __ADD(NF_INET_LOCAL_OUT, NF_INET_LOCAL_OUT), __ADD(NF_INET_POST_ROUTING, NF_INET_POST_ROUTING), }; char *nfnl_inet_hook2str(unsigned int hook, char *buf, size_t len) { return __type2str(hook, buf, len, nfnl_inet_hooks, ARRAY_SIZE(nfnl_inet_hooks)); } unsigned int nfnl_str2inet_hook(const char *name) { return __str2type(name, nfnl_inet_hooks, ARRAY_SIZE(nfnl_inet_hooks)); } libnl-3.2.29/lib/netfilter/exp_obj.c0000644000175000017500000005401113023014600014152 00000000000000/* * lib/netfilter/exp_obj.c Conntrack Expectation Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2012 Rich Fought */ #include #include #include #include #include #include #include #include // The 32-bit attribute mask in the common object header isn't // big enough to handle all attributes of an expectation. So // we'll for sure specify optional attributes + parent attributes // that are required for valid object comparison. Comparison of // these parent attributes will include nested attributes. /** @cond SKIP */ #define EXP_ATTR_FAMILY (1UL << 0) // 8-bit #define EXP_ATTR_TIMEOUT (1UL << 1) // 32-bit #define EXP_ATTR_ID (1UL << 2) // 32-bit #define EXP_ATTR_HELPER_NAME (1UL << 3) // string #define EXP_ATTR_ZONE (1UL << 4) // 16-bit #define EXP_ATTR_FLAGS (1UL << 5) // 32-bit #define EXP_ATTR_CLASS (1UL << 6) // 32-bit #define EXP_ATTR_FN (1UL << 7) // String // Tuples #define EXP_ATTR_EXPECT_IP_SRC (1UL << 8) #define EXP_ATTR_EXPECT_IP_DST (1UL << 9) #define EXP_ATTR_EXPECT_L4PROTO_NUM (1UL << 10) #define EXP_ATTR_EXPECT_L4PROTO_PORTS (1UL << 11) #define EXP_ATTR_EXPECT_L4PROTO_ICMP (1UL << 12) #define EXP_ATTR_MASTER_IP_SRC (1UL << 13) #define EXP_ATTR_MASTER_IP_DST (1UL << 14) #define EXP_ATTR_MASTER_L4PROTO_NUM (1UL << 15) #define EXP_ATTR_MASTER_L4PROTO_PORTS (1UL << 16) #define EXP_ATTR_MASTER_L4PROTO_ICMP (1UL << 17) #define EXP_ATTR_MASK_IP_SRC (1UL << 18) #define EXP_ATTR_MASK_IP_DST (1UL << 19) #define EXP_ATTR_MASK_L4PROTO_NUM (1UL << 20) #define EXP_ATTR_MASK_L4PROTO_PORTS (1UL << 21) #define EXP_ATTR_MASK_L4PROTO_ICMP (1UL << 22) #define EXP_ATTR_NAT_IP_SRC (1UL << 23) #define EXP_ATTR_NAT_IP_DST (1UL << 24) #define EXP_ATTR_NAT_L4PROTO_NUM (1UL << 25) #define EXP_ATTR_NAT_L4PROTO_PORTS (1UL << 26) #define EXP_ATTR_NAT_L4PROTO_ICMP (1UL << 27) #define EXP_ATTR_NAT_DIR (1UL << 28) /** @endcond */ static void exp_free_data(struct nl_object *c) { struct nfnl_exp *exp = (struct nfnl_exp *) c; if (exp == NULL) return; nl_addr_put(exp->exp_expect.src); nl_addr_put(exp->exp_expect.dst); nl_addr_put(exp->exp_master.src); nl_addr_put(exp->exp_master.dst); nl_addr_put(exp->exp_mask.src); nl_addr_put(exp->exp_mask.dst); nl_addr_put(exp->exp_nat.src); nl_addr_put(exp->exp_nat.dst); free(exp->exp_fn); free(exp->exp_helper_name); } static int exp_clone(struct nl_object *_dst, struct nl_object *_src) { struct nfnl_exp *dst = (struct nfnl_exp *) _dst; struct nfnl_exp *src = (struct nfnl_exp *) _src; struct nl_addr *addr; // Expectation if (src->exp_expect.src) { addr = nl_addr_clone(src->exp_expect.src); if (!addr) return -NLE_NOMEM; dst->exp_expect.src = addr; } if (src->exp_expect.dst) { addr = nl_addr_clone(src->exp_expect.dst); if (!addr) return -NLE_NOMEM; dst->exp_expect.dst = addr; } // Master CT if (src->exp_master.src) { addr = nl_addr_clone(src->exp_master.src); if (!addr) return -NLE_NOMEM; dst->exp_master.src = addr; } if (src->exp_master.dst) { addr = nl_addr_clone(src->exp_master.dst); if (!addr) return -NLE_NOMEM; dst->exp_master.dst = addr; } // Mask if (src->exp_mask.src) { addr = nl_addr_clone(src->exp_mask.src); if (!addr) return -NLE_NOMEM; dst->exp_mask.src = addr; } if (src->exp_mask.dst) { addr = nl_addr_clone(src->exp_mask.dst); if (!addr) return -NLE_NOMEM; dst->exp_mask.dst = addr; } // NAT if (src->exp_nat.src) { addr = nl_addr_clone(src->exp_nat.src); if (!addr) return -NLE_NOMEM; dst->exp_nat.src = addr; } if (src->exp_nat.dst) { addr = nl_addr_clone(src->exp_nat.dst); if (!addr) return -NLE_NOMEM; dst->exp_nat.dst = addr; } if (src->exp_fn) dst->exp_fn = strdup(src->exp_fn); if (src->exp_helper_name) dst->exp_helper_name = strdup(src->exp_helper_name); return 0; } static void dump_addr(struct nl_dump_params *p, struct nl_addr *addr, int port) { char buf[64]; if (addr) nl_dump(p, "%s", nl_addr2str(addr, buf, sizeof(buf))); if (port) nl_dump(p, ":%u ", port); else if (addr) nl_dump(p, " "); } static void dump_icmp(struct nl_dump_params *p, struct nfnl_exp *exp, int tuple) { if (nfnl_exp_test_icmp(exp, tuple)) { nl_dump(p, "icmp type %d ", nfnl_exp_get_icmp_type(exp, tuple)); nl_dump(p, "code %d ", nfnl_exp_get_icmp_code(exp, tuple)); nl_dump(p, "id %d ", nfnl_exp_get_icmp_id(exp, tuple)); } } static void exp_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p) { struct nl_addr *tuple_src, *tuple_dst; int tuple_sport, tuple_dport; int i = 0; char buf[64]; for (i = NFNL_EXP_TUPLE_EXPECT; i < NFNL_EXP_TUPLE_MAX; i++) { tuple_src = NULL; tuple_dst = NULL; tuple_sport = 0; tuple_dport = 0; // Test needed for NAT case if (nfnl_exp_test_src(exp, i)) tuple_src = nfnl_exp_get_src(exp, i); if (nfnl_exp_test_dst(exp, i)) tuple_dst = nfnl_exp_get_dst(exp, i); // Don't have tests for individual ports/types/codes/ids, if (nfnl_exp_test_l4protonum(exp, i)) { nl_dump(p, "%s ", nl_ip_proto2str(nfnl_exp_get_l4protonum(exp, i), buf, sizeof(buf))); } if (nfnl_exp_test_ports(exp, i)) { tuple_sport = nfnl_exp_get_src_port(exp, i); tuple_dport = nfnl_exp_get_dst_port(exp, i); } dump_addr(p, tuple_src, tuple_sport); dump_addr(p, tuple_dst, tuple_dport); dump_icmp(p, exp, 0); } if (nfnl_exp_test_nat_dir(exp)) nl_dump(p, "nat dir %s ", exp->exp_nat_dir); } /* FIXME Compatible with /proc/net/nf_conntrack */ static void exp_dump_line(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_exp *exp = (struct nfnl_exp *) a; nl_new_line(p); exp_dump_tuples(exp, p); nl_dump(p, "\n"); } static void exp_dump_details(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_exp *exp = (struct nfnl_exp *) a; char buf[64]; int fp = 0; exp_dump_line(a, p); nl_dump(p, " id 0x%x ", exp->exp_id); nl_dump_line(p, "family %s ", nl_af2str(exp->exp_family, buf, sizeof(buf))); if (nfnl_exp_test_timeout(exp)) { uint64_t timeout_ms = nfnl_exp_get_timeout(exp) * 1000UL; nl_dump(p, "timeout %s ", nl_msec2str(timeout_ms, buf, sizeof(buf))); } if (nfnl_exp_test_helper_name(exp)) nl_dump(p, "helper %s ", exp->exp_helper_name); if (nfnl_exp_test_fn(exp)) nl_dump(p, "fn %s ", exp->exp_fn); if (nfnl_exp_test_class(exp)) nl_dump(p, "class %u ", nfnl_exp_get_class(exp)); if (nfnl_exp_test_zone(exp)) nl_dump(p, "zone %u ", nfnl_exp_get_zone(exp)); if (nfnl_exp_test_flags(exp)) nl_dump(p, "<"); #define PRINT_FLAG(str) \ { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); } if (exp->exp_flags & NF_CT_EXPECT_PERMANENT) PRINT_FLAG("PERMANENT"); if (exp->exp_flags & NF_CT_EXPECT_INACTIVE) PRINT_FLAG("INACTIVE"); if (exp->exp_flags & NF_CT_EXPECT_USERSPACE) PRINT_FLAG("USERSPACE"); #undef PRINT_FLAG if (nfnl_exp_test_flags(exp)) nl_dump(p, ">"); nl_dump(p, "\n"); } static int exp_cmp_l4proto_ports (union nfnl_exp_protodata *a, union nfnl_exp_protodata *b) { // Must return 0 for match, 1 for mismatch int d = 0; d = ( (a->port.src != b->port.src) || (a->port.dst != b->port.dst) ); return d; } static int exp_cmp_l4proto_icmp (union nfnl_exp_protodata *a, union nfnl_exp_protodata *b) { // Must return 0 for match, 1 for mismatch int d = 0; d = ( (a->icmp.code != b->icmp.code) || (a->icmp.type != b->icmp.type) || (a->icmp.id != b->icmp.id) ); return d; } static uint64_t exp_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct nfnl_exp *a = (struct nfnl_exp *) _a; struct nfnl_exp *b = (struct nfnl_exp *) _b; uint64_t diff = 0; #define EXP_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, EXP_ATTR_##ATTR, a, b, EXPR) #define EXP_DIFF_VAL(ATTR, FIELD) EXP_DIFF(ATTR, a->FIELD != b->FIELD) #define EXP_DIFF_STRING(ATTR, FIELD) EXP_DIFF(ATTR, (strcmp(a->FIELD, b->FIELD) != 0)) #define EXP_DIFF_ADDR(ATTR, FIELD) \ ((flags & LOOSE_COMPARISON) \ ? EXP_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \ : EXP_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD))) #define EXP_DIFF_L4PROTO_PORTS(ATTR, FIELD) \ EXP_DIFF(ATTR, exp_cmp_l4proto_ports(&(a->FIELD), &(b->FIELD))) #define EXP_DIFF_L4PROTO_ICMP(ATTR, FIELD) \ EXP_DIFF(ATTR, exp_cmp_l4proto_icmp(&(a->FIELD), &(b->FIELD))) diff |= EXP_DIFF_VAL(FAMILY, exp_family); diff |= EXP_DIFF_VAL(TIMEOUT, exp_timeout); diff |= EXP_DIFF_VAL(ID, exp_id); diff |= EXP_DIFF_VAL(ZONE, exp_zone); diff |= EXP_DIFF_VAL(CLASS, exp_class); diff |= EXP_DIFF_VAL(FLAGS, exp_flags); diff |= EXP_DIFF_VAL(NAT_DIR, exp_nat_dir); diff |= EXP_DIFF_STRING(FN, exp_fn); diff |= EXP_DIFF_STRING(HELPER_NAME, exp_helper_name); diff |= EXP_DIFF_ADDR(EXPECT_IP_SRC, exp_expect.src); diff |= EXP_DIFF_ADDR(EXPECT_IP_DST, exp_expect.dst); diff |= EXP_DIFF_VAL(EXPECT_L4PROTO_NUM, exp_expect.proto.l4protonum); diff |= EXP_DIFF_L4PROTO_PORTS(EXPECT_L4PROTO_PORTS, exp_expect.proto.l4protodata); diff |= EXP_DIFF_L4PROTO_ICMP(EXPECT_L4PROTO_ICMP, exp_expect.proto.l4protodata); diff |= EXP_DIFF_ADDR(MASTER_IP_SRC, exp_master.src); diff |= EXP_DIFF_ADDR(MASTER_IP_DST, exp_master.dst); diff |= EXP_DIFF_VAL(MASTER_L4PROTO_NUM, exp_master.proto.l4protonum); diff |= EXP_DIFF_L4PROTO_PORTS(MASTER_L4PROTO_PORTS, exp_master.proto.l4protodata); diff |= EXP_DIFF_L4PROTO_ICMP(MASTER_L4PROTO_ICMP, exp_master.proto.l4protodata); diff |= EXP_DIFF_ADDR(MASK_IP_SRC, exp_mask.src); diff |= EXP_DIFF_ADDR(MASK_IP_DST, exp_mask.dst); diff |= EXP_DIFF_VAL(MASK_L4PROTO_NUM, exp_mask.proto.l4protonum); diff |= EXP_DIFF_L4PROTO_PORTS(MASK_L4PROTO_PORTS, exp_mask.proto.l4protodata); diff |= EXP_DIFF_L4PROTO_ICMP(MASK_L4PROTO_ICMP, exp_mask.proto.l4protodata); diff |= EXP_DIFF_ADDR(NAT_IP_SRC, exp_nat.src); diff |= EXP_DIFF_ADDR(NAT_IP_DST, exp_nat.dst); diff |= EXP_DIFF_VAL(NAT_L4PROTO_NUM, exp_nat.proto.l4protonum); diff |= EXP_DIFF_L4PROTO_PORTS(NAT_L4PROTO_PORTS, exp_nat.proto.l4protodata); diff |= EXP_DIFF_L4PROTO_ICMP(NAT_L4PROTO_ICMP, exp_nat.proto.l4protodata); #undef EXP_DIFF #undef EXP_DIFF_VAL #undef EXP_DIFF_STRING #undef EXP_DIFF_ADDR #undef EXP_DIFF_L4PROTO_PORTS #undef EXP_DIFF_L4PROTO_ICMP return diff; } // CLI arguments? static const struct trans_tbl exp_attrs[] = { __ADD(EXP_ATTR_FAMILY, family), __ADD(EXP_ATTR_TIMEOUT, timeout), __ADD(EXP_ATTR_ID, id), __ADD(EXP_ATTR_HELPER_NAME, helpername), __ADD(EXP_ATTR_ZONE, zone), __ADD(EXP_ATTR_CLASS, class), __ADD(EXP_ATTR_FLAGS, flags), __ADD(EXP_ATTR_FN, function), __ADD(EXP_ATTR_EXPECT_IP_SRC, expectipsrc), __ADD(EXP_ATTR_EXPECT_IP_DST, expectipdst), __ADD(EXP_ATTR_EXPECT_L4PROTO_NUM, expectprotonum), __ADD(EXP_ATTR_EXPECT_L4PROTO_PORTS, expectports), __ADD(EXP_ATTR_EXPECT_L4PROTO_ICMP, expecticmp), __ADD(EXP_ATTR_MASTER_IP_SRC, masteripsrc), __ADD(EXP_ATTR_MASTER_IP_DST, masteripdst), __ADD(EXP_ATTR_MASTER_L4PROTO_NUM, masterprotonum), __ADD(EXP_ATTR_MASTER_L4PROTO_PORTS, masterports), __ADD(EXP_ATTR_MASTER_L4PROTO_ICMP, mastericmp), __ADD(EXP_ATTR_MASK_IP_SRC, maskipsrc), __ADD(EXP_ATTR_MASK_IP_DST, maskipdst), __ADD(EXP_ATTR_MASK_L4PROTO_NUM, maskprotonum), __ADD(EXP_ATTR_MASK_L4PROTO_PORTS, maskports), __ADD(EXP_ATTR_MASK_L4PROTO_ICMP, maskicmp), __ADD(EXP_ATTR_NAT_IP_SRC, natipsrc), __ADD(EXP_ATTR_NAT_IP_DST, natipdst), __ADD(EXP_ATTR_NAT_L4PROTO_NUM, natprotonum), __ADD(EXP_ATTR_NAT_L4PROTO_PORTS, natports), __ADD(EXP_ATTR_NAT_L4PROTO_ICMP, naticmp), __ADD(EXP_ATTR_NAT_DIR, natdir), }; static char *exp_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, exp_attrs, ARRAY_SIZE(exp_attrs)); } /** * @name Allocation/Freeing * @{ */ struct nfnl_exp *nfnl_exp_alloc(void) { return (struct nfnl_exp *) nl_object_alloc(&exp_obj_ops); } void nfnl_exp_get(struct nfnl_exp *exp) { nl_object_get((struct nl_object *) exp); } void nfnl_exp_put(struct nfnl_exp *exp) { nl_object_put((struct nl_object *) exp); } /** @} */ /** * @name Attributes * @{ */ void nfnl_exp_set_family(struct nfnl_exp *exp, uint8_t family) { exp->exp_family = family; exp->ce_mask |= EXP_ATTR_FAMILY; } uint8_t nfnl_exp_get_family(const struct nfnl_exp *exp) { if (exp->ce_mask & EXP_ATTR_FAMILY) return exp->exp_family; else return AF_UNSPEC; } void nfnl_exp_set_flags(struct nfnl_exp *exp, uint32_t flags) { exp->exp_flags |= flags; exp->ce_mask |= EXP_ATTR_FLAGS; } int nfnl_exp_test_flags(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_FLAGS); } void nfnl_exp_unset_flags(struct nfnl_exp *exp, uint32_t flags) { exp->exp_flags &= ~flags; exp->ce_mask |= EXP_ATTR_FLAGS; } uint32_t nfnl_exp_get_flags(const struct nfnl_exp *exp) { return exp->exp_flags; } static const struct trans_tbl flag_table[] = { __ADD(IPS_EXPECTED, expected), __ADD(IPS_SEEN_REPLY, seen_reply), __ADD(IPS_ASSURED, assured), }; char * nfnl_exp_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, flag_table, ARRAY_SIZE(flag_table)); } int nfnl_exp_str2flags(const char *name) { return __str2flags(name, flag_table, ARRAY_SIZE(flag_table)); } void nfnl_exp_set_timeout(struct nfnl_exp *exp, uint32_t timeout) { exp->exp_timeout = timeout; exp->ce_mask |= EXP_ATTR_TIMEOUT; } int nfnl_exp_test_timeout(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_TIMEOUT); } uint32_t nfnl_exp_get_timeout(const struct nfnl_exp *exp) { return exp->exp_timeout; } void nfnl_exp_set_id(struct nfnl_exp *exp, uint32_t id) { exp->exp_id = id; exp->ce_mask |= EXP_ATTR_ID; } int nfnl_exp_test_id(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_ID); } uint32_t nfnl_exp_get_id(const struct nfnl_exp *exp) { return exp->exp_id; } int nfnl_exp_set_helper_name(struct nfnl_exp *exp, void *name) { free(exp->exp_helper_name); exp->exp_helper_name = strdup(name); if (!exp->exp_helper_name) return -NLE_NOMEM; exp->ce_mask |= EXP_ATTR_HELPER_NAME; return 0; } int nfnl_exp_test_helper_name(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_HELPER_NAME); } const char * nfnl_exp_get_helper_name(const struct nfnl_exp *exp) { return exp->exp_helper_name; } void nfnl_exp_set_zone(struct nfnl_exp *exp, uint16_t zone) { exp->exp_zone = zone; exp->ce_mask |= EXP_ATTR_ZONE; } int nfnl_exp_test_zone(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_ZONE); } uint16_t nfnl_exp_get_zone(const struct nfnl_exp *exp) { return exp->exp_zone; } void nfnl_exp_set_class(struct nfnl_exp *exp, uint32_t class) { exp->exp_class = class; exp->ce_mask |= EXP_ATTR_CLASS; } int nfnl_exp_test_class(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_CLASS); } uint32_t nfnl_exp_get_class(const struct nfnl_exp *exp) { return exp->exp_class; } int nfnl_exp_set_fn(struct nfnl_exp *exp, void *fn) { free(exp->exp_fn); exp->exp_fn = strdup(fn); if (!exp->exp_fn) return -NLE_NOMEM; exp->ce_mask |= EXP_ATTR_FN; return 0; } int nfnl_exp_test_fn(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_FN); } const char * nfnl_exp_get_fn(const struct nfnl_exp *exp) { return exp->exp_fn; } void nfnl_exp_set_nat_dir(struct nfnl_exp *exp, uint8_t nat_dir) { exp->exp_nat_dir = nat_dir; exp->ce_mask |= EXP_ATTR_NAT_DIR; } int nfnl_exp_test_nat_dir(const struct nfnl_exp *exp) { return !!(exp->ce_mask & EXP_ATTR_NAT_DIR); } uint8_t nfnl_exp_get_nat_dir(const struct nfnl_exp *exp) { return exp->exp_nat_dir; } #define EXP_GET_TUPLE(e, t) \ (t == NFNL_EXP_TUPLE_MASTER) ? \ &(e->exp_master) : \ (t == NFNL_EXP_TUPLE_MASK) ? \ &(e->exp_mask) : \ (t == NFNL_EXP_TUPLE_NAT) ? \ &(e->exp_nat) : &(exp->exp_expect) static int exp_get_src_attr(int tuple) { int attr = 0; switch (tuple) { case NFNL_EXP_TUPLE_MASTER: attr = EXP_ATTR_MASTER_IP_SRC; break; case NFNL_EXP_TUPLE_MASK: attr = EXP_ATTR_MASK_IP_SRC; break; case NFNL_EXP_TUPLE_NAT: attr = EXP_ATTR_NAT_IP_SRC; break; case NFNL_EXP_TUPLE_EXPECT: default : attr = EXP_ATTR_EXPECT_IP_SRC; } return attr; } static int exp_get_dst_attr(int tuple) { int attr = 0; switch (tuple) { case NFNL_EXP_TUPLE_MASTER: attr = EXP_ATTR_MASTER_IP_DST; break; case NFNL_EXP_TUPLE_MASK: attr = EXP_ATTR_MASK_IP_DST; break; case NFNL_EXP_TUPLE_NAT: attr = EXP_ATTR_NAT_IP_DST; break; case NFNL_EXP_TUPLE_EXPECT: default : attr = EXP_ATTR_EXPECT_IP_DST; } return attr; } static int exp_set_addr(struct nfnl_exp *exp, struct nl_addr *addr, int attr, struct nl_addr ** exp_addr) { if (exp->ce_mask & EXP_ATTR_FAMILY) { if (addr->a_family != exp->exp_family) return -NLE_AF_MISMATCH; } else nfnl_exp_set_family(exp, addr->a_family); if (*exp_addr) nl_addr_put(*exp_addr); nl_addr_get(addr); *exp_addr = addr; exp->ce_mask |= attr; return 0; } int nfnl_exp_set_src(struct nfnl_exp *exp, int tuple, struct nl_addr *addr) { struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return exp_set_addr(exp, addr, exp_get_src_attr(tuple), &dir->src); } int nfnl_exp_set_dst(struct nfnl_exp *exp, int tuple, struct nl_addr *addr) { struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return exp_set_addr(exp, addr, exp_get_dst_attr(tuple), &dir->dst); } int nfnl_exp_test_src(const struct nfnl_exp *exp, int tuple) { return !!(exp->ce_mask & exp_get_src_attr(tuple)); } int nfnl_exp_test_dst(const struct nfnl_exp *exp, int tuple) { return !!(exp->ce_mask & exp_get_dst_attr(tuple)); } struct nl_addr *nfnl_exp_get_src(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); if (!(exp->ce_mask & exp_get_src_attr(tuple))) return NULL; return dir->src; } struct nl_addr *nfnl_exp_get_dst(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); if (!(exp->ce_mask & exp_get_dst_attr(tuple))) return NULL; return dir->dst; } static int exp_get_l4protonum_attr(int tuple) { int attr = 0; switch (tuple) { case NFNL_EXP_TUPLE_MASTER: attr = EXP_ATTR_MASTER_L4PROTO_NUM; break; case NFNL_EXP_TUPLE_MASK: attr = EXP_ATTR_MASK_L4PROTO_NUM; break; case NFNL_EXP_TUPLE_NAT: attr = EXP_ATTR_NAT_L4PROTO_NUM; break; case NFNL_EXP_TUPLE_EXPECT: default : attr = EXP_ATTR_EXPECT_L4PROTO_NUM; } return attr; } void nfnl_exp_set_l4protonum(struct nfnl_exp *exp, int tuple, uint8_t l4protonum) { struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); dir->proto.l4protonum = l4protonum; exp->ce_mask |= exp_get_l4protonum_attr(tuple); } int nfnl_exp_test_l4protonum(const struct nfnl_exp *exp, int tuple) { return !!(exp->ce_mask & exp_get_l4protonum_attr(tuple)); } uint8_t nfnl_exp_get_l4protonum(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return dir->proto.l4protonum; } static int exp_get_l4ports_attr(int tuple) { int attr = 0; switch (tuple) { case NFNL_EXP_TUPLE_MASTER: attr = EXP_ATTR_MASTER_L4PROTO_PORTS; break; case NFNL_EXP_TUPLE_MASK: attr = EXP_ATTR_MASK_L4PROTO_PORTS; break; case NFNL_EXP_TUPLE_NAT: attr = EXP_ATTR_NAT_L4PROTO_PORTS; break; case NFNL_EXP_TUPLE_EXPECT: default : attr = EXP_ATTR_EXPECT_L4PROTO_PORTS; } return attr; } void nfnl_exp_set_ports(struct nfnl_exp *exp, int tuple, uint16_t srcport, uint16_t dstport) { struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); dir->proto.l4protodata.port.src = srcport; dir->proto.l4protodata.port.dst = dstport; exp->ce_mask |= exp_get_l4ports_attr(tuple); } int nfnl_exp_test_ports(const struct nfnl_exp *exp, int tuple) { return !!(exp->ce_mask & exp_get_l4ports_attr(tuple)); } uint16_t nfnl_exp_get_src_port(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return dir->proto.l4protodata.port.src; } uint16_t nfnl_exp_get_dst_port(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return dir->proto.l4protodata.port.dst; } static int exp_get_l4icmp_attr(int tuple) { int attr = 0; switch (tuple) { case NFNL_EXP_TUPLE_MASTER: attr = EXP_ATTR_MASTER_L4PROTO_ICMP; break; case NFNL_EXP_TUPLE_MASK: attr = EXP_ATTR_MASK_L4PROTO_ICMP; break; case NFNL_EXP_TUPLE_NAT: attr = EXP_ATTR_NAT_L4PROTO_ICMP; break; case NFNL_EXP_TUPLE_EXPECT: default : attr = EXP_ATTR_EXPECT_L4PROTO_ICMP; } return attr; } void nfnl_exp_set_icmp(struct nfnl_exp *exp, int tuple, uint16_t id, uint8_t type, uint8_t code) { struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); dir->proto.l4protodata.icmp.id = id; dir->proto.l4protodata.icmp.type = type; dir->proto.l4protodata.icmp.code = code; exp->ce_mask |= exp_get_l4icmp_attr(tuple); } int nfnl_exp_test_icmp(const struct nfnl_exp *exp, int tuple) { int attr = exp_get_l4icmp_attr(tuple); return !!(exp->ce_mask & attr); } uint16_t nfnl_exp_get_icmp_id(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return dir->proto.l4protodata.icmp.id; } uint8_t nfnl_exp_get_icmp_type(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return dir->proto.l4protodata.icmp.type; } uint8_t nfnl_exp_get_icmp_code(const struct nfnl_exp *exp, int tuple) { const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple); return dir->proto.l4protodata.icmp.code; } /** @} */ struct nl_object_ops exp_obj_ops = { .oo_name = "netfilter/exp", .oo_size = sizeof(struct nfnl_exp), .oo_free_data = exp_free_data, .oo_clone = exp_clone, .oo_dump = { [NL_DUMP_LINE] = exp_dump_line, [NL_DUMP_DETAILS] = exp_dump_details, }, .oo_compare = exp_compare, .oo_attrs2str = exp_attrs2str, }; /** @} */ libnl-3.2.29/lib/netfilter/queue_obj.c0000644000175000017500000001202013023014600014474 00000000000000/* * lib/netfilter/queue_obj.c Netfilter Queue * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy */ /** * @ingroup nfnl * @defgroup queue Queue * @brief * @{ */ #include #include #include /** @cond SKIP */ #define QUEUE_ATTR_GROUP (1UL << 0) #define QUEUE_ATTR_MAXLEN (1UL << 1) #define QUEUE_ATTR_COPY_MODE (1UL << 2) #define QUEUE_ATTR_COPY_RANGE (1UL << 3) /** @endcond */ static void nfnl_queue_dump(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_queue *queue = (struct nfnl_queue *) a; char buf[64]; nl_new_line(p); if (queue->ce_mask & QUEUE_ATTR_GROUP) nl_dump(p, "group=%u ", queue->queue_group); if (queue->ce_mask & QUEUE_ATTR_MAXLEN) nl_dump(p, "maxlen=%u ", queue->queue_maxlen); if (queue->ce_mask & QUEUE_ATTR_COPY_MODE) nl_dump(p, "copy_mode=%s ", nfnl_queue_copy_mode2str(queue->queue_copy_mode, buf, sizeof(buf))); if (queue->ce_mask & QUEUE_ATTR_COPY_RANGE) nl_dump(p, "copy_range=%u ", queue->queue_copy_range); nl_dump(p, "\n"); } static const struct trans_tbl copy_modes[] = { __ADD(NFNL_QUEUE_COPY_NONE, none), __ADD(NFNL_QUEUE_COPY_META, meta), __ADD(NFNL_QUEUE_COPY_PACKET, packet), }; char *nfnl_queue_copy_mode2str(enum nfnl_queue_copy_mode copy_mode, char *buf, size_t len) { return __type2str(copy_mode, buf, len, copy_modes, ARRAY_SIZE(copy_modes)); } int nfnl_queue_str2copy_mode(const char *name) { return __str2type(name, copy_modes, ARRAY_SIZE(copy_modes)); } /** * @name Allocation/Freeing * @{ */ struct nfnl_queue *nfnl_queue_alloc(void) { return (struct nfnl_queue *) nl_object_alloc(&queue_obj_ops); } void nfnl_queue_get(struct nfnl_queue *queue) { nl_object_get((struct nl_object *) queue); } void nfnl_queue_put(struct nfnl_queue *queue) { nl_object_put((struct nl_object *) queue); } /** @} */ /** * @name Attributes * @{ */ void nfnl_queue_set_group(struct nfnl_queue *queue, uint16_t group) { queue->queue_group = group; queue->ce_mask |= QUEUE_ATTR_GROUP; } int nfnl_queue_test_group(const struct nfnl_queue *queue) { return !!(queue->ce_mask & QUEUE_ATTR_GROUP); } uint16_t nfnl_queue_get_group(const struct nfnl_queue *queue) { return queue->queue_group; } void nfnl_queue_set_maxlen(struct nfnl_queue *queue, uint32_t maxlen) { queue->queue_maxlen = maxlen; queue->ce_mask |= QUEUE_ATTR_MAXLEN; } int nfnl_queue_test_maxlen(const struct nfnl_queue *queue) { return !!(queue->ce_mask & QUEUE_ATTR_MAXLEN); } uint32_t nfnl_queue_get_maxlen(const struct nfnl_queue *queue) { return queue->queue_maxlen; } void nfnl_queue_set_copy_mode(struct nfnl_queue *queue, enum nfnl_queue_copy_mode mode) { queue->queue_copy_mode = mode; queue->ce_mask |= QUEUE_ATTR_COPY_MODE; } int nfnl_queue_test_copy_mode(const struct nfnl_queue *queue) { return !!(queue->ce_mask & QUEUE_ATTR_COPY_MODE); } enum nfnl_queue_copy_mode nfnl_queue_get_copy_mode(const struct nfnl_queue *queue) { return queue->queue_copy_mode; } void nfnl_queue_set_copy_range(struct nfnl_queue *queue, uint32_t copy_range) { queue->queue_copy_range = copy_range; queue->ce_mask |= QUEUE_ATTR_COPY_RANGE; } int nfnl_queue_test_copy_range(const struct nfnl_queue *queue) { return !!(queue->ce_mask & QUEUE_ATTR_COPY_RANGE); } uint32_t nfnl_queue_get_copy_range(const struct nfnl_queue *queue) { return queue->queue_copy_range; } static uint64_t nfnl_queue_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct nfnl_queue *a = (struct nfnl_queue *) _a; struct nfnl_queue *b = (struct nfnl_queue *) _b; uint64_t diff = 0; #define NFNL_QUEUE_DIFF(ATTR, EXPR) \ ATTR_DIFF(attrs, QUEUE_ATTR_##ATTR, a, b, EXPR) #define NFNL_QUEUE_DIFF_VAL(ATTR, FIELD) \ NFNL_QUEUE_DIFF(ATTR, a->FIELD != b->FIELD) diff |= NFNL_QUEUE_DIFF_VAL(GROUP, queue_group); diff |= NFNL_QUEUE_DIFF_VAL(MAXLEN, queue_maxlen); diff |= NFNL_QUEUE_DIFF_VAL(COPY_MODE, queue_copy_mode); diff |= NFNL_QUEUE_DIFF_VAL(COPY_RANGE, queue_copy_range); #undef NFNL_QUEUE_DIFF #undef NFNL_QUEUE_DIFF_VAL return diff; } static const struct trans_tbl nfnl_queue_attrs[] = { __ADD(QUEUE_ATTR_GROUP, group), __ADD(QUEUE_ATTR_MAXLEN, maxlen), __ADD(QUEUE_ATTR_COPY_MODE, copy_mode), __ADD(QUEUE_ATTR_COPY_RANGE, copy_range), }; static char *nfnl_queue_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, nfnl_queue_attrs, ARRAY_SIZE(nfnl_queue_attrs)); } /** @} */ struct nl_object_ops queue_obj_ops = { .oo_name = "netfilter/queue", .oo_size = sizeof(struct nfnl_queue), .oo_dump = { [NL_DUMP_LINE] = nfnl_queue_dump, [NL_DUMP_DETAILS] = nfnl_queue_dump, [NL_DUMP_STATS] = nfnl_queue_dump, }, .oo_compare = nfnl_queue_compare, .oo_attrs2str = nfnl_queue_attrs2str, .oo_id_attrs = QUEUE_ATTR_GROUP, }; /** @} */ libnl-3.2.29/lib/netfilter/nfnl.c0000644000175000017500000001343413023014600013465 00000000000000/* * lib/netfilter/nfnl.c Netfilter Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ /** * @defgroup nfnl Netfilter Library (libnl-nf) * * @par Message Format * @code * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) ---> * +----------------------------+- - -+- - - - - - - - - - -+- - -+ * | Header | Pad | Payload | Pad | * | struct nlmsghdr | | | | * +----------------------------+- - -+- - - - - - - - - - -+- - -+ * @endcode * @code * <-------- NFNL_HDRLEN ---------> * +--------------------------+- - -+------------+ * | Netfilter Netlink Header | Pad | Attributes | * | struct nfgenmsg | | | * +--------------------------+- - -+------------+ * nfnlmsg_attrdata(nfg, hdrlen)-----^ * @endcode * * @par 1) Creating a new netfilter netlink message * @code * struct nl_msg *msg; * * // Create a new empty netlink message * msg = nlmsg_alloc(); * * // Append the netlink and netfilter netlink message header * hdr = nfnlmsg_put(msg, PID, SEQ, SUBSYS, TYPE, NLM_F_ECHO, * FAMILY, RES_ID); * * // Append the attributes. * nla_put_u32(msg, 1, 0x10); * * // Message is ready to be sent. * nl_send_auto_complete(sk, msg); * * // All done? Free the message. * nlmsg_free(msg); * @endcode * * @par 2) Sending of trivial messages * @code * // For trivial messages not requiring any subsys specific header or * // attributes, nfnl_send_simple() may be used to send messages directly. * nfnl_send_simple(sk, SUBSYS, TYPE, 0, FAMILY, RES_ID); * @endcode * @{ */ #include #include #include /** * @name Socket Creating * @{ */ /** * Create and connect netfilter netlink socket. * @arg sk Netlink socket. * * Creates a NETLINK_NETFILTER netlink socket, binds the socket and * issues a connection attempt. * * @see nl_connect() * * @return 0 on success or a negative error code. */ int nfnl_connect(struct nl_sock *sk) { return nl_connect(sk, NETLINK_NETFILTER); } /** @} */ /** * @name Sending * @{ */ /** * Send trivial netfilter netlink message * @arg sk Netlink socket. * @arg subsys_id nfnetlink subsystem * @arg type nfnetlink message type * @arg flags message flags * @arg family nfnetlink address family * @arg res_id nfnetlink resource id * * @return 0 on success or a negative error code. Due to a bug, this function * returns the number of bytes sent. Treat any non-negative number as success. */ int nfnl_send_simple(struct nl_sock *sk, uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id) { struct nfgenmsg hdr = { .nfgen_family = family, .version = NFNETLINK_V0, .res_id = htons(res_id), }; return nl_send_simple(sk, NFNLMSG_TYPE(subsys_id, type), flags, &hdr, sizeof(hdr)); } /** @} */ /** * @name Message Parsing * @{ */ /** * Get netfilter subsystem id from message * @arg nlh netlink messsage header */ uint8_t nfnlmsg_subsys(struct nlmsghdr *nlh) { return NFNL_SUBSYS_ID(nlh->nlmsg_type); } /** * Get netfilter message type from message * @arg nlh netlink messsage header */ uint8_t nfnlmsg_subtype(struct nlmsghdr *nlh) { return NFNL_MSG_TYPE(nlh->nlmsg_type); } /** * Get netfilter family from message * @arg nlh netlink messsage header */ uint8_t nfnlmsg_family(struct nlmsghdr *nlh) { struct nfgenmsg *nfg = nlmsg_data(nlh); return nfg->nfgen_family; } /** * Get netfilter resource id from message * @arg nlh netlink messsage header */ uint16_t nfnlmsg_res_id(struct nlmsghdr *nlh) { struct nfgenmsg *nfg = nlmsg_data(nlh); return ntohs(nfg->res_id); } /** @} */ /** * @name Message Building * @{ */ static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id) { struct nfgenmsg *nfg; nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO); if (nfg == NULL) return -NLE_NOMEM; nfg->nfgen_family = family; nfg->version = NFNETLINK_V0; nfg->res_id = htons(res_id); NL_DBG(2, "msg %p: Added nfnetlink header family=%d res_id=%d\n", msg, family, res_id); return 0; } /** * Allocate a new netfilter netlink message * @arg subsys_id nfnetlink subsystem * @arg type nfnetlink message type * @arg flags message flags * @arg family nfnetlink address family * @arg res_id nfnetlink resource id * * @return Newly allocated netlink message or NULL. */ struct nl_msg *nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id) { struct nl_msg *msg; msg = nlmsg_alloc_simple(NFNLMSG_TYPE(subsys_id, type), flags); if (msg == NULL) return NULL; if (nfnlmsg_append(msg, family, res_id) < 0) goto nla_put_failure; return msg; nla_put_failure: nlmsg_free(msg); return NULL; } /** * Add netlink and netfilter netlink headers to netlink message * @arg msg netlink message * @arg pid netlink process id * @arg seq sequence number of message * @arg subsys_id nfnetlink subsystem * @arg type nfnetlink message type * @arg flags message flags * @arg family nfnetlink address family * @arg res_id nfnetlink resource id */ int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id) { struct nlmsghdr *nlh; nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags); if (nlh == NULL) return -NLE_MSGSIZE; return nfnlmsg_append(msg, family, res_id); } /** @} */ /** @} */ libnl-3.2.29/lib/netfilter/queue.c0000644000175000017500000001235513023014600013655 00000000000000/* * lib/netfilter/queue.c Netfilter Queue * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy */ /** * @ingroup nfnl * @defgroup queue Queue * @brief * @{ */ #include #include #include #include #include #include struct nl_sock *nfnl_queue_socket_alloc(void) { struct nl_sock *nlsk; nlsk = nl_socket_alloc(); if (nlsk) nl_socket_disable_auto_ack(nlsk); return nlsk; } static int send_queue_request(struct nl_sock *sk, struct nl_msg *msg) { int err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** * @name Queue Commands * @{ */ static int build_queue_cmd_request(uint8_t family, uint16_t queuenum, uint8_t command, struct nl_msg **result) { struct nl_msg *msg; struct nfqnl_msg_config_cmd cmd; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0, family, queuenum); if (msg == NULL) return -NLE_NOMEM; cmd.pf = htons(family); cmd._pad = 0; cmd.command = command; if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } int nfnl_queue_build_pf_bind(uint8_t pf, struct nl_msg **result) { return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND, result); } int nfnl_queue_pf_bind(struct nl_sock *nlh, uint8_t pf) { struct nl_msg *msg; int err; if ((err = nfnl_queue_build_pf_bind(pf, &msg)) < 0) return err; return send_queue_request(nlh, msg); } int nfnl_queue_build_pf_unbind(uint8_t pf, struct nl_msg **result) { return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND, result); } int nfnl_queue_pf_unbind(struct nl_sock *nlh, uint8_t pf) { struct nl_msg *msg; int err; if ((err = nfnl_queue_build_pf_unbind(pf, &msg)) < 0) return err; return send_queue_request(nlh, msg); } static int nfnl_queue_build_request(const struct nfnl_queue *queue, struct nl_msg **result) { struct nl_msg *msg; if (!nfnl_queue_test_group(queue)) return -NLE_MISSING_ATTR; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0, 0, nfnl_queue_get_group(queue)); if (msg == NULL) return -NLE_NOMEM; if (nfnl_queue_test_maxlen(queue) && nla_put_u32(msg, NFQA_CFG_QUEUE_MAXLEN, htonl(nfnl_queue_get_maxlen(queue))) < 0) goto nla_put_failure; /* This sucks, the nfnetlink_queue interface always expects both * parameters to be present. Needs to be done properly. */ if (nfnl_queue_test_copy_mode(queue)) { struct nfqnl_msg_config_params params; switch (nfnl_queue_get_copy_mode(queue)) { case NFNL_QUEUE_COPY_NONE: params.copy_mode = NFQNL_COPY_NONE; break; case NFNL_QUEUE_COPY_META: params.copy_mode = NFQNL_COPY_META; break; case NFNL_QUEUE_COPY_PACKET: params.copy_mode = NFQNL_COPY_PACKET; break; } params.copy_range = htonl(nfnl_queue_get_copy_range(queue)); if (nla_put(msg, NFQA_CFG_PARAMS, sizeof(params), ¶ms) < 0) goto nla_put_failure; } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } int nfnl_queue_build_create_request(const struct nfnl_queue *queue, struct nl_msg **result) { struct nfqnl_msg_config_cmd cmd; int err; if ((err = nfnl_queue_build_request(queue, result)) < 0) return err; cmd.pf = 0; cmd._pad = 0; cmd.command = NFQNL_CFG_CMD_BIND; NLA_PUT(*result, NFQA_CFG_CMD, sizeof(cmd), &cmd); return 0; nla_put_failure: nlmsg_free(*result); return -NLE_MSGSIZE; } int nfnl_queue_create(struct nl_sock *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; int err; if ((err = nfnl_queue_build_create_request(queue, &msg)) < 0) return err; return send_queue_request(nlh, msg); } int nfnl_queue_build_change_request(const struct nfnl_queue *queue, struct nl_msg **result) { return nfnl_queue_build_request(queue, result); } int nfnl_queue_change(struct nl_sock *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; int err; if ((err = nfnl_queue_build_change_request(queue, &msg)) < 0) return err; return send_queue_request(nlh, msg); } int nfnl_queue_build_delete_request(const struct nfnl_queue *queue, struct nl_msg **result) { if (!nfnl_queue_test_group(queue)) return -NLE_MISSING_ATTR; return build_queue_cmd_request(0, nfnl_queue_get_group(queue), NFQNL_CFG_CMD_UNBIND, result); } int nfnl_queue_delete(struct nl_sock *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; int err; if ((err = nfnl_queue_build_delete_request(queue, &msg)) < 0) return err; return send_queue_request(nlh, msg); } /** @} */ static struct nl_cache_ops nfnl_queue_ops = { .co_name = "netfilter/queue", .co_obj_ops = &queue_obj_ops, .co_msgtypes = { END_OF_MSGTYPES_LIST, }, }; static void __init nfnl_queue_init(void) { nl_cache_mngt_register(&nfnl_queue_ops); } static void __exit nfnl_queue_exit(void) { nl_cache_mngt_unregister(&nfnl_queue_ops); } /** @} */ libnl-3.2.29/lib/netfilter/queue_msg_obj.c0000644000175000017500000003022313023014600015347 00000000000000/* * lib/netfilter/queue_msg_obj.c Netfilter Queue Message Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy */ #include #include #include #include #include /** @cond SKIP */ #define QUEUE_MSG_ATTR_GROUP (1UL << 0) #define QUEUE_MSG_ATTR_FAMILY (1UL << 1) #define QUEUE_MSG_ATTR_PACKETID (1UL << 2) #define QUEUE_MSG_ATTR_HWPROTO (1UL << 3) #define QUEUE_MSG_ATTR_HOOK (1UL << 4) #define QUEUE_MSG_ATTR_MARK (1UL << 5) #define QUEUE_MSG_ATTR_TIMESTAMP (1UL << 6) #define QUEUE_MSG_ATTR_INDEV (1UL << 7) #define QUEUE_MSG_ATTR_OUTDEV (1UL << 8) #define QUEUE_MSG_ATTR_PHYSINDEV (1UL << 9) #define QUEUE_MSG_ATTR_PHYSOUTDEV (1UL << 10) #define QUEUE_MSG_ATTR_HWADDR (1UL << 11) #define QUEUE_MSG_ATTR_PAYLOAD (1UL << 12) #define QUEUE_MSG_ATTR_VERDICT (1UL << 13) /** @endcond */ static void nfnl_queue_msg_free_data(struct nl_object *c) { struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) c; if (msg == NULL) return; free(msg->queue_msg_payload); } static int nfnl_queue_msg_clone(struct nl_object *_dst, struct nl_object *_src) { struct nfnl_queue_msg *dst = (struct nfnl_queue_msg *) _dst; struct nfnl_queue_msg *src = (struct nfnl_queue_msg *) _src; int err; if (src->queue_msg_payload) { err = nfnl_queue_msg_set_payload(dst, src->queue_msg_payload, src->queue_msg_payload_len); if (err < 0) goto errout; } return 0; errout: return err; } static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) a; struct nl_cache *link_cache; char buf[64]; link_cache = nl_cache_mngt_require_safe("route/link"); nl_new_line(p); if (msg->ce_mask & QUEUE_MSG_ATTR_GROUP) nl_dump(p, "GROUP=%u ", msg->queue_msg_group); if (msg->ce_mask & QUEUE_MSG_ATTR_INDEV) { if (link_cache) nl_dump(p, "IN=%s ", rtnl_link_i2name(link_cache, msg->queue_msg_indev, buf, sizeof(buf))); else nl_dump(p, "IN=%d ", msg->queue_msg_indev); } if (msg->ce_mask & QUEUE_MSG_ATTR_PHYSINDEV) { if (link_cache) nl_dump(p, "PHYSIN=%s ", rtnl_link_i2name(link_cache, msg->queue_msg_physindev, buf, sizeof(buf))); else nl_dump(p, "IN=%d ", msg->queue_msg_physindev); } if (msg->ce_mask & QUEUE_MSG_ATTR_OUTDEV) { if (link_cache) nl_dump(p, "OUT=%s ", rtnl_link_i2name(link_cache, msg->queue_msg_outdev, buf, sizeof(buf))); else nl_dump(p, "OUT=%d ", msg->queue_msg_outdev); } if (msg->ce_mask & QUEUE_MSG_ATTR_PHYSOUTDEV) { if (link_cache) nl_dump(p, "PHYSOUT=%s ", rtnl_link_i2name(link_cache, msg->queue_msg_physoutdev, buf, sizeof(buf))); else nl_dump(p, "PHYSOUT=%d ", msg->queue_msg_physoutdev); } if (msg->ce_mask & QUEUE_MSG_ATTR_HWADDR) { int i; nl_dump(p, "MAC"); for (i = 0; i < msg->queue_msg_hwaddr_len; i++) nl_dump(p, "%c%02x", i?':':'=', msg->queue_msg_hwaddr[i]); nl_dump(p, " "); } if (msg->ce_mask & QUEUE_MSG_ATTR_FAMILY) nl_dump(p, "FAMILY=%s ", nl_af2str(msg->queue_msg_family, buf, sizeof(buf))); if (msg->ce_mask & QUEUE_MSG_ATTR_HWPROTO) nl_dump(p, "HWPROTO=%s ", nl_ether_proto2str(ntohs(msg->queue_msg_hwproto), buf, sizeof(buf))); if (msg->ce_mask & QUEUE_MSG_ATTR_HOOK) nl_dump(p, "HOOK=%s ", nfnl_inet_hook2str(msg->queue_msg_hook, buf, sizeof(buf))); if (msg->ce_mask & QUEUE_MSG_ATTR_MARK) nl_dump(p, "MARK=%d ", msg->queue_msg_mark); if (msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD) nl_dump(p, "PAYLOADLEN=%d ", msg->queue_msg_payload_len); if (msg->ce_mask & QUEUE_MSG_ATTR_PACKETID) nl_dump(p, "PACKETID=%u ", msg->queue_msg_packetid); if (msg->ce_mask & QUEUE_MSG_ATTR_VERDICT) nl_dump(p, "VERDICT=%s ", nfnl_verdict2str(msg->queue_msg_verdict, buf, sizeof(buf))); nl_dump(p, "\n"); if (link_cache) nl_cache_put(link_cache); } /** * @name Allocation/Freeing * @{ */ struct nfnl_queue_msg *nfnl_queue_msg_alloc(void) { return (struct nfnl_queue_msg *) nl_object_alloc(&queue_msg_obj_ops); } void nfnl_queue_msg_get(struct nfnl_queue_msg *msg) { nl_object_get((struct nl_object *) msg); } void nfnl_queue_msg_put(struct nfnl_queue_msg *msg) { nl_object_put((struct nl_object *) msg); } /** @} */ /** * @name Attributes * @{ */ void nfnl_queue_msg_set_group(struct nfnl_queue_msg *msg, uint16_t group) { msg->queue_msg_group = group; msg->ce_mask |= QUEUE_MSG_ATTR_GROUP; } int nfnl_queue_msg_test_group(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_GROUP); } uint16_t nfnl_queue_msg_get_group(const struct nfnl_queue_msg *msg) { return msg->queue_msg_group; } /** * Set the protocol family * @arg msg NF queue message * @arg family AF_XXX address family example: AF_INET, AF_UNIX, etc */ void nfnl_queue_msg_set_family(struct nfnl_queue_msg *msg, uint8_t family) { msg->queue_msg_family = family; msg->ce_mask |= QUEUE_MSG_ATTR_FAMILY; } int nfnl_queue_msg_test_family(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_FAMILY); } uint8_t nfnl_queue_msg_get_family(const struct nfnl_queue_msg *msg) { if (msg->ce_mask & QUEUE_MSG_ATTR_FAMILY) return msg->queue_msg_family; else return AF_UNSPEC; } void nfnl_queue_msg_set_packetid(struct nfnl_queue_msg *msg, uint32_t packetid) { msg->queue_msg_packetid = packetid; msg->ce_mask |= QUEUE_MSG_ATTR_PACKETID; } int nfnl_queue_msg_test_packetid(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_PACKETID); } uint32_t nfnl_queue_msg_get_packetid(const struct nfnl_queue_msg *msg) { return msg->queue_msg_packetid; } void nfnl_queue_msg_set_hwproto(struct nfnl_queue_msg *msg, uint16_t hwproto) { msg->queue_msg_hwproto = hwproto; msg->ce_mask |= QUEUE_MSG_ATTR_HWPROTO; } int nfnl_queue_msg_test_hwproto(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_HWPROTO); } uint16_t nfnl_queue_msg_get_hwproto(const struct nfnl_queue_msg *msg) { return msg->queue_msg_hwproto; } void nfnl_queue_msg_set_hook(struct nfnl_queue_msg *msg, uint8_t hook) { msg->queue_msg_hook = hook; msg->ce_mask |= QUEUE_MSG_ATTR_HOOK; } int nfnl_queue_msg_test_hook(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_HOOK); } uint8_t nfnl_queue_msg_get_hook(const struct nfnl_queue_msg *msg) { return msg->queue_msg_hook; } void nfnl_queue_msg_set_mark(struct nfnl_queue_msg *msg, uint32_t mark) { msg->queue_msg_mark = mark; msg->ce_mask |= QUEUE_MSG_ATTR_MARK; } int nfnl_queue_msg_test_mark(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_MARK); } uint32_t nfnl_queue_msg_get_mark(const struct nfnl_queue_msg *msg) { return msg->queue_msg_mark; } void nfnl_queue_msg_set_timestamp(struct nfnl_queue_msg *msg, struct timeval *tv) { msg->queue_msg_timestamp.tv_sec = tv->tv_sec; msg->queue_msg_timestamp.tv_usec = tv->tv_usec; msg->ce_mask |= QUEUE_MSG_ATTR_TIMESTAMP; } int nfnl_queue_msg_test_timestamp(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_TIMESTAMP); } const struct timeval *nfnl_queue_msg_get_timestamp(const struct nfnl_queue_msg *msg) { if (!(msg->ce_mask & QUEUE_MSG_ATTR_TIMESTAMP)) return NULL; return &msg->queue_msg_timestamp; } void nfnl_queue_msg_set_indev(struct nfnl_queue_msg *msg, uint32_t indev) { msg->queue_msg_indev = indev; msg->ce_mask |= QUEUE_MSG_ATTR_INDEV; } int nfnl_queue_msg_test_indev(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_INDEV); } uint32_t nfnl_queue_msg_get_indev(const struct nfnl_queue_msg *msg) { return msg->queue_msg_indev; } void nfnl_queue_msg_set_outdev(struct nfnl_queue_msg *msg, uint32_t outdev) { msg->queue_msg_outdev = outdev; msg->ce_mask |= QUEUE_MSG_ATTR_OUTDEV; } int nfnl_queue_msg_test_outdev(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_OUTDEV); } uint32_t nfnl_queue_msg_get_outdev(const struct nfnl_queue_msg *msg) { return msg->queue_msg_outdev; } void nfnl_queue_msg_set_physindev(struct nfnl_queue_msg *msg, uint32_t physindev) { msg->queue_msg_physindev = physindev; msg->ce_mask |= QUEUE_MSG_ATTR_PHYSINDEV; } int nfnl_queue_msg_test_physindev(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_PHYSINDEV); } uint32_t nfnl_queue_msg_get_physindev(const struct nfnl_queue_msg *msg) { return msg->queue_msg_physindev; } void nfnl_queue_msg_set_physoutdev(struct nfnl_queue_msg *msg, uint32_t physoutdev) { msg->queue_msg_physoutdev = physoutdev; msg->ce_mask |= QUEUE_MSG_ATTR_PHYSOUTDEV; } int nfnl_queue_msg_test_physoutdev(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_PHYSOUTDEV); } uint32_t nfnl_queue_msg_get_physoutdev(const struct nfnl_queue_msg *msg) { return msg->queue_msg_physoutdev; } void nfnl_queue_msg_set_hwaddr(struct nfnl_queue_msg *msg, uint8_t *hwaddr, int len) { if (len > sizeof(msg->queue_msg_hwaddr)) len = sizeof(msg->queue_msg_hwaddr); msg->queue_msg_hwaddr_len = len; memcpy(msg->queue_msg_hwaddr, hwaddr, len); msg->ce_mask |= QUEUE_MSG_ATTR_HWADDR; } int nfnl_queue_msg_test_hwaddr(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_HWADDR); } const uint8_t *nfnl_queue_msg_get_hwaddr(const struct nfnl_queue_msg *msg, int *len) { if (!(msg->ce_mask & QUEUE_MSG_ATTR_HWADDR)) { *len = 0; return NULL; } *len = msg->queue_msg_hwaddr_len; return msg->queue_msg_hwaddr; } int nfnl_queue_msg_set_payload(struct nfnl_queue_msg *msg, uint8_t *payload, int len) { void *new_payload = malloc(len); if (new_payload == NULL) return -NLE_NOMEM; memcpy(new_payload, payload, len); free(msg->queue_msg_payload); msg->queue_msg_payload = new_payload; msg->queue_msg_payload_len = len; msg->ce_mask |= QUEUE_MSG_ATTR_PAYLOAD; return 0; } int nfnl_queue_msg_test_payload(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD); } const void *nfnl_queue_msg_get_payload(const struct nfnl_queue_msg *msg, int *len) { if (!(msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD)) { *len = 0; return NULL; } *len = msg->queue_msg_payload_len; return msg->queue_msg_payload; } /** * Return the number of items matching a filter in the cache * @arg msg queue msg * @arg verdict NF_DROP, NF_ACCEPT, NF_REPEAT, etc */ void nfnl_queue_msg_set_verdict(struct nfnl_queue_msg *msg, unsigned int verdict) { msg->queue_msg_verdict = verdict; msg->ce_mask |= QUEUE_MSG_ATTR_VERDICT; } int nfnl_queue_msg_test_verdict(const struct nfnl_queue_msg *msg) { return !!(msg->ce_mask & QUEUE_MSG_ATTR_VERDICT); } unsigned int nfnl_queue_msg_get_verdict(const struct nfnl_queue_msg *msg) { return msg->queue_msg_verdict; } static const struct trans_tbl nfnl_queue_msg_attrs[] = { __ADD(QUEUE_MSG_ATTR_GROUP, group), __ADD(QUEUE_MSG_ATTR_FAMILY, family), __ADD(QUEUE_MSG_ATTR_PACKETID, packetid), __ADD(QUEUE_MSG_ATTR_HWPROTO, hwproto), __ADD(QUEUE_MSG_ATTR_HOOK, hook), __ADD(QUEUE_MSG_ATTR_MARK, mark), __ADD(QUEUE_MSG_ATTR_TIMESTAMP, timestamp), __ADD(QUEUE_MSG_ATTR_INDEV, indev), __ADD(QUEUE_MSG_ATTR_OUTDEV, outdev), __ADD(QUEUE_MSG_ATTR_PHYSINDEV, physindev), __ADD(QUEUE_MSG_ATTR_PHYSOUTDEV, physoutdev), __ADD(QUEUE_MSG_ATTR_HWADDR, hwaddr), __ADD(QUEUE_MSG_ATTR_PAYLOAD, payload), __ADD(QUEUE_MSG_ATTR_VERDICT, verdict), }; static char *nfnl_queue_msg_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, nfnl_queue_msg_attrs, ARRAY_SIZE(nfnl_queue_msg_attrs)); } /** @} */ struct nl_object_ops queue_msg_obj_ops = { .oo_name = "netfilter/queuemsg", .oo_size = sizeof(struct nfnl_queue_msg), .oo_free_data = nfnl_queue_msg_free_data, .oo_clone = nfnl_queue_msg_clone, .oo_dump = { [NL_DUMP_LINE] = nfnl_queue_msg_dump, [NL_DUMP_DETAILS] = nfnl_queue_msg_dump, [NL_DUMP_STATS] = nfnl_queue_msg_dump, }, .oo_attrs2str = nfnl_queue_msg_attrs2str, }; /** @} */ libnl-3.2.29/lib/netfilter/ct_obj.c0000644000175000017500000005267113023014600013776 00000000000000/* * lib/netfilter/ct_obj.c Conntrack Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ #include #include #include #include #include #include #include /** @cond SKIP */ #define CT_ATTR_FAMILY (1UL << 0) #define CT_ATTR_PROTO (1UL << 1) #define CT_ATTR_TCP_STATE (1UL << 2) #define CT_ATTR_STATUS (1UL << 3) #define CT_ATTR_TIMEOUT (1UL << 4) #define CT_ATTR_MARK (1UL << 5) #define CT_ATTR_USE (1UL << 6) #define CT_ATTR_ID (1UL << 7) #define CT_ATTR_ORIG_SRC (1UL << 8) #define CT_ATTR_ORIG_DST (1UL << 9) #define CT_ATTR_ORIG_SRC_PORT (1UL << 10) #define CT_ATTR_ORIG_DST_PORT (1UL << 11) #define CT_ATTR_ORIG_ICMP_ID (1UL << 12) #define CT_ATTR_ORIG_ICMP_TYPE (1UL << 13) #define CT_ATTR_ORIG_ICMP_CODE (1UL << 14) #define CT_ATTR_ORIG_PACKETS (1UL << 15) #define CT_ATTR_ORIG_BYTES (1UL << 16) #define CT_ATTR_REPL_SRC (1UL << 17) #define CT_ATTR_REPL_DST (1UL << 18) #define CT_ATTR_REPL_SRC_PORT (1UL << 19) #define CT_ATTR_REPL_DST_PORT (1UL << 20) #define CT_ATTR_REPL_ICMP_ID (1UL << 21) #define CT_ATTR_REPL_ICMP_TYPE (1UL << 22) #define CT_ATTR_REPL_ICMP_CODE (1UL << 23) #define CT_ATTR_REPL_PACKETS (1UL << 24) #define CT_ATTR_REPL_BYTES (1UL << 25) #define CT_ATTR_TIMESTAMP (1UL << 26) #define CT_ATTR_ZONE (1UL << 27) /** @endcond */ static void ct_free_data(struct nl_object *c) { struct nfnl_ct *ct = (struct nfnl_ct *) c; if (ct == NULL) return; nl_addr_put(ct->ct_orig.src); nl_addr_put(ct->ct_orig.dst); nl_addr_put(ct->ct_repl.src); nl_addr_put(ct->ct_repl.dst); } static int ct_clone(struct nl_object *_dst, struct nl_object *_src) { struct nfnl_ct *dst = (struct nfnl_ct *) _dst; struct nfnl_ct *src = (struct nfnl_ct *) _src; struct nl_addr *addr; if (src->ct_orig.src) { addr = nl_addr_clone(src->ct_orig.src); if (!addr) return -NLE_NOMEM; dst->ct_orig.src = addr; } if (src->ct_orig.dst) { addr = nl_addr_clone(src->ct_orig.dst); if (!addr) return -NLE_NOMEM; dst->ct_orig.dst = addr; } if (src->ct_repl.src) { addr = nl_addr_clone(src->ct_repl.src); if (!addr) return -NLE_NOMEM; dst->ct_repl.src = addr; } if (src->ct_repl.dst) { addr = nl_addr_clone(src->ct_repl.dst); if (!addr) return -NLE_NOMEM; dst->ct_repl.dst = addr; } return 0; } static void dump_addr(struct nl_dump_params *p, struct nl_addr *addr, int port) { char buf[64]; if (addr) nl_dump(p, "%s", nl_addr2str(addr, buf, sizeof(buf))); if (port) nl_dump(p, ":%u ", port); else if (addr) nl_dump(p, " "); } static void dump_icmp(struct nl_dump_params *p, struct nfnl_ct *ct, int reply) { if (nfnl_ct_test_icmp_type(ct, reply)) nl_dump(p, "icmp type %d ", nfnl_ct_get_icmp_type(ct, reply)); if (nfnl_ct_test_icmp_code(ct, reply)) nl_dump(p, "code %d ", nfnl_ct_get_icmp_code(ct, reply)); if (nfnl_ct_test_icmp_id(ct, reply)) nl_dump(p, "id %d ", nfnl_ct_get_icmp_id(ct, reply)); } static void ct_dump_tuples(struct nfnl_ct *ct, struct nl_dump_params *p) { struct nl_addr *orig_src, *orig_dst, *reply_src, *reply_dst; int orig_sport = 0, orig_dport = 0, reply_sport = 0, reply_dport = 0; int sync = 0; orig_src = nfnl_ct_get_src(ct, 0); orig_dst = nfnl_ct_get_dst(ct, 0); reply_src = nfnl_ct_get_src(ct, 1); reply_dst = nfnl_ct_get_dst(ct, 1); if (nfnl_ct_test_src_port(ct, 0)) orig_sport = nfnl_ct_get_src_port(ct, 0); if (nfnl_ct_test_dst_port(ct, 0)) orig_dport = nfnl_ct_get_dst_port(ct, 0); if (nfnl_ct_test_src_port(ct, 1)) reply_sport = nfnl_ct_get_src_port(ct, 1); if (nfnl_ct_test_dst_port(ct, 1)) reply_dport = nfnl_ct_get_dst_port(ct, 1); if (orig_src && orig_dst && reply_src && reply_dst && orig_sport == reply_dport && orig_dport == reply_sport && !nl_addr_cmp(orig_src, reply_dst) && !nl_addr_cmp(orig_dst, reply_src)) sync = 1; dump_addr(p, orig_src, orig_sport); nl_dump(p, sync ? "<-> " : "-> "); dump_addr(p, orig_dst, orig_dport); dump_icmp(p, ct, 0); if (!sync) { dump_addr(p, reply_src, reply_sport); nl_dump(p, "<- "); dump_addr(p, reply_dst, reply_dport); dump_icmp(p, ct, 1); } } /* Compatible with /proc/net/nf_conntrack */ static void ct_dump_line(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_ct *ct = (struct nfnl_ct *) a; char buf[64]; nl_new_line(p); if (nfnl_ct_test_proto(ct)) nl_dump(p, "%s ", nl_ip_proto2str(nfnl_ct_get_proto(ct), buf, sizeof(buf))); if (nfnl_ct_test_tcp_state(ct)) nl_dump(p, "%s ", nfnl_ct_tcp_state2str(nfnl_ct_get_tcp_state(ct), buf, sizeof(buf))); ct_dump_tuples(ct, p); if (nfnl_ct_test_mark(ct) && nfnl_ct_get_mark(ct)) nl_dump(p, "mark %u ", nfnl_ct_get_mark(ct)); if (nfnl_ct_test_zone(ct)) nl_dump(p, "zone %hu ", nfnl_ct_get_zone(ct)); if (nfnl_ct_test_timestamp(ct)) { const struct nfnl_ct_timestamp *tstamp = nfnl_ct_get_timestamp(ct); int64_t delta_time = tstamp->stop - tstamp->start; if (delta_time > 0) delta_time /= NSEC_PER_SEC; else delta_time = 0; nl_dump(p, "delta-time %llu ", delta_time); } nl_dump(p, "\n"); } static void ct_dump_details(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_ct *ct = (struct nfnl_ct *) a; char buf[64]; int fp = 0; ct_dump_line(a, p); nl_dump(p, " id 0x%x ", ct->ct_id); nl_dump_line(p, "family %s ", nl_af2str(ct->ct_family, buf, sizeof(buf))); if (nfnl_ct_test_use(ct)) nl_dump(p, "refcnt %u ", nfnl_ct_get_use(ct)); if (nfnl_ct_test_timeout(ct)) { uint64_t timeout_ms = nfnl_ct_get_timeout(ct) * 1000UL; nl_dump(p, "timeout %s ", nl_msec2str(timeout_ms, buf, sizeof(buf))); } if (ct->ct_status) nl_dump(p, "<"); #define PRINT_FLAG(str) \ { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); } if (ct->ct_status & IPS_EXPECTED) PRINT_FLAG("EXPECTED"); if (!(ct->ct_status & IPS_SEEN_REPLY)) PRINT_FLAG("NOREPLY"); if (ct->ct_status & IPS_ASSURED) PRINT_FLAG("ASSURED"); if (!(ct->ct_status & IPS_CONFIRMED)) PRINT_FLAG("NOTSENT"); if (ct->ct_status & IPS_SRC_NAT) PRINT_FLAG("SNAT"); if (ct->ct_status & IPS_DST_NAT) PRINT_FLAG("DNAT"); if (ct->ct_status & IPS_SEQ_ADJUST) PRINT_FLAG("SEQADJUST"); if (!(ct->ct_status & IPS_SRC_NAT_DONE)) PRINT_FLAG("SNAT_INIT"); if (!(ct->ct_status & IPS_DST_NAT_DONE)) PRINT_FLAG("DNAT_INIT"); if (ct->ct_status & IPS_DYING) PRINT_FLAG("DYING"); if (ct->ct_status & IPS_FIXED_TIMEOUT) PRINT_FLAG("FIXED_TIMEOUT"); #undef PRINT_FLAG if (ct->ct_status) nl_dump(p, ">"); nl_dump(p, "\n"); } static void ct_dump_stats(struct nl_object *a, struct nl_dump_params *p) { struct nfnl_ct *ct = (struct nfnl_ct *) a; double res; char *unit; uint64_t packets; const char * const names[] = {"rx", "tx"}; int i; ct_dump_details(a, p); if (!nfnl_ct_test_bytes(ct, 0) || !nfnl_ct_test_packets(ct, 0) || !nfnl_ct_test_bytes(ct, 1) || !nfnl_ct_test_packets(ct, 1)) { nl_dump_line(p, " Statistics are not available.\n"); nl_dump_line(p, " Please set sysctl net.netfilter.nf_conntrack_acct=1\n"); nl_dump_line(p, " (Require kernel 2.6.27)\n"); return; } nl_dump_line(p, " # packets volume\n"); for (i=0; i<=1; i++) { res = nl_cancel_down_bytes(nfnl_ct_get_bytes(ct, i), &unit); packets = nfnl_ct_get_packets(ct, i); nl_dump_line(p, " %s %10" PRIu64 " %7.2f %s\n", names[i], packets, res, unit); } } static uint64_t ct_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct nfnl_ct *a = (struct nfnl_ct *) _a; struct nfnl_ct *b = (struct nfnl_ct *) _b; uint64_t diff = 0; #define CT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, CT_ATTR_##ATTR, a, b, EXPR) #define CT_DIFF_VAL(ATTR, FIELD) CT_DIFF(ATTR, a->FIELD != b->FIELD) #define CT_DIFF_ADDR(ATTR, FIELD) \ ((flags & LOOSE_COMPARISON) \ ? CT_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \ : CT_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD))) diff |= CT_DIFF_VAL(FAMILY, ct_family); diff |= CT_DIFF_VAL(PROTO, ct_proto); diff |= CT_DIFF_VAL(TCP_STATE, ct_protoinfo.tcp.state); diff |= CT_DIFF_VAL(TIMEOUT, ct_timeout); diff |= CT_DIFF_VAL(MARK, ct_mark); diff |= CT_DIFF_VAL(USE, ct_use); diff |= CT_DIFF_VAL(ID, ct_id); diff |= CT_DIFF_ADDR(ORIG_SRC, ct_orig.src); diff |= CT_DIFF_ADDR(ORIG_DST, ct_orig.dst); diff |= CT_DIFF_VAL(ORIG_SRC_PORT, ct_orig.proto.port.src); diff |= CT_DIFF_VAL(ORIG_DST_PORT, ct_orig.proto.port.dst); diff |= CT_DIFF_VAL(ORIG_ICMP_ID, ct_orig.proto.icmp.id); diff |= CT_DIFF_VAL(ORIG_ICMP_TYPE, ct_orig.proto.icmp.type); diff |= CT_DIFF_VAL(ORIG_ICMP_CODE, ct_orig.proto.icmp.code); diff |= CT_DIFF_VAL(ORIG_PACKETS, ct_orig.packets); diff |= CT_DIFF_VAL(ORIG_BYTES, ct_orig.bytes); diff |= CT_DIFF_ADDR(REPL_SRC, ct_repl.src); diff |= CT_DIFF_ADDR(REPL_DST, ct_repl.dst); diff |= CT_DIFF_VAL(REPL_SRC_PORT, ct_repl.proto.port.src); diff |= CT_DIFF_VAL(REPL_DST_PORT, ct_repl.proto.port.dst); diff |= CT_DIFF_VAL(REPL_ICMP_ID, ct_repl.proto.icmp.id); diff |= CT_DIFF_VAL(REPL_ICMP_TYPE, ct_repl.proto.icmp.type); diff |= CT_DIFF_VAL(REPL_ICMP_CODE, ct_repl.proto.icmp.code); diff |= CT_DIFF_VAL(REPL_PACKETS, ct_repl.packets); diff |= CT_DIFF_VAL(REPL_BYTES, ct_repl.bytes); if (flags & LOOSE_COMPARISON) diff |= CT_DIFF(STATUS, (a->ct_status ^ b->ct_status) & b->ct_status_mask); else diff |= CT_DIFF(STATUS, a->ct_status != b->ct_status); #undef CT_DIFF #undef CT_DIFF_VAL #undef CT_DIFF_ADDR return diff; } static const struct trans_tbl ct_attrs[] = { __ADD(CT_ATTR_FAMILY, family), __ADD(CT_ATTR_PROTO, proto), __ADD(CT_ATTR_TCP_STATE, tcpstate), __ADD(CT_ATTR_STATUS, status), __ADD(CT_ATTR_TIMEOUT, timeout), __ADD(CT_ATTR_MARK, mark), __ADD(CT_ATTR_USE, use), __ADD(CT_ATTR_ID, id), __ADD(CT_ATTR_ORIG_SRC, origsrc), __ADD(CT_ATTR_ORIG_DST, origdst), __ADD(CT_ATTR_ORIG_SRC_PORT, origsrcport), __ADD(CT_ATTR_ORIG_DST_PORT, origdstport), __ADD(CT_ATTR_ORIG_ICMP_ID, origicmpid), __ADD(CT_ATTR_ORIG_ICMP_TYPE, origicmptype), __ADD(CT_ATTR_ORIG_ICMP_CODE, origicmpcode), __ADD(CT_ATTR_ORIG_PACKETS, origpackets), __ADD(CT_ATTR_ORIG_BYTES, origbytes), __ADD(CT_ATTR_REPL_SRC, replysrc), __ADD(CT_ATTR_REPL_DST, replydst), __ADD(CT_ATTR_REPL_SRC_PORT, replysrcport), __ADD(CT_ATTR_REPL_DST_PORT, replydstport), __ADD(CT_ATTR_REPL_ICMP_ID, replyicmpid), __ADD(CT_ATTR_REPL_ICMP_TYPE, replyicmptype), __ADD(CT_ATTR_REPL_ICMP_CODE, replyicmpcode), __ADD(CT_ATTR_REPL_PACKETS, replypackets), __ADD(CT_ATTR_REPL_BYTES, replybytes), }; static char *ct_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, ct_attrs, ARRAY_SIZE(ct_attrs)); } /** * @name Allocation/Freeing * @{ */ struct nfnl_ct *nfnl_ct_alloc(void) { return (struct nfnl_ct *) nl_object_alloc(&ct_obj_ops); } void nfnl_ct_get(struct nfnl_ct *ct) { nl_object_get((struct nl_object *) ct); } void nfnl_ct_put(struct nfnl_ct *ct) { nl_object_put((struct nl_object *) ct); } /** @} */ /** * @name Attributes * @{ */ void nfnl_ct_set_family(struct nfnl_ct *ct, uint8_t family) { ct->ct_family = family; ct->ce_mask |= CT_ATTR_FAMILY; } uint8_t nfnl_ct_get_family(const struct nfnl_ct *ct) { if (ct->ce_mask & CT_ATTR_FAMILY) return ct->ct_family; else return AF_UNSPEC; } void nfnl_ct_set_proto(struct nfnl_ct *ct, uint8_t proto) { ct->ct_proto = proto; ct->ce_mask |= CT_ATTR_PROTO; } int nfnl_ct_test_proto(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_PROTO); } uint8_t nfnl_ct_get_proto(const struct nfnl_ct *ct) { return ct->ct_proto; } void nfnl_ct_set_tcp_state(struct nfnl_ct *ct, uint8_t state) { ct->ct_protoinfo.tcp.state = state; ct->ce_mask |= CT_ATTR_TCP_STATE; } int nfnl_ct_test_tcp_state(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_TCP_STATE); } uint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *ct) { return ct->ct_protoinfo.tcp.state; } static const struct trans_tbl tcp_states[] = { __ADD(TCP_CONNTRACK_NONE,NONE), __ADD(TCP_CONNTRACK_SYN_SENT,SYN_SENT), __ADD(TCP_CONNTRACK_SYN_RECV,SYN_RECV), __ADD(TCP_CONNTRACK_ESTABLISHED,ESTABLISHED), __ADD(TCP_CONNTRACK_FIN_WAIT,FIN_WAIT), __ADD(TCP_CONNTRACK_CLOSE_WAIT,CLOSE_WAIT), __ADD(TCP_CONNTRACK_LAST_ACK,LAST_ACK), __ADD(TCP_CONNTRACK_TIME_WAIT,TIME_WAIT), __ADD(TCP_CONNTRACK_CLOSE,CLOSE), __ADD(TCP_CONNTRACK_LISTEN,LISTEN), }; char *nfnl_ct_tcp_state2str(uint8_t state, char *buf, size_t len) { return __type2str(state, buf, len, tcp_states, ARRAY_SIZE(tcp_states)); } int nfnl_ct_str2tcp_state(const char *name) { return __str2type(name, tcp_states, ARRAY_SIZE(tcp_states)); } void nfnl_ct_set_status(struct nfnl_ct *ct, uint32_t status) { ct->ct_status_mask |= status; ct->ct_status |= status; ct->ce_mask |= CT_ATTR_STATUS; } void nfnl_ct_unset_status(struct nfnl_ct *ct, uint32_t status) { ct->ct_status_mask |= status; ct->ct_status &= ~status; ct->ce_mask |= CT_ATTR_STATUS; } int nfnl_ct_test_status(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_STATUS); } uint32_t nfnl_ct_get_status(const struct nfnl_ct *ct) { return ct->ct_status; } static const struct trans_tbl status_flags[] = { __ADD(IPS_EXPECTED, expected), __ADD(IPS_SEEN_REPLY, seen_reply), __ADD(IPS_ASSURED, assured), __ADD(IPS_CONFIRMED, confirmed), __ADD(IPS_SRC_NAT, snat), __ADD(IPS_DST_NAT, dnat), __ADD(IPS_SEQ_ADJUST, seqadjust), __ADD(IPS_SRC_NAT_DONE, snat_done), __ADD(IPS_DST_NAT_DONE, dnat_done), __ADD(IPS_DYING, dying), __ADD(IPS_FIXED_TIMEOUT, fixed_timeout), }; char * nfnl_ct_status2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, status_flags, ARRAY_SIZE(status_flags)); } int nfnl_ct_str2status(const char *name) { return __str2flags(name, status_flags, ARRAY_SIZE(status_flags)); } void nfnl_ct_set_timeout(struct nfnl_ct *ct, uint32_t timeout) { ct->ct_timeout = timeout; ct->ce_mask |= CT_ATTR_TIMEOUT; } int nfnl_ct_test_timeout(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_TIMEOUT); } uint32_t nfnl_ct_get_timeout(const struct nfnl_ct *ct) { return ct->ct_timeout; } void nfnl_ct_set_mark(struct nfnl_ct *ct, uint32_t mark) { ct->ct_mark = mark; ct->ce_mask |= CT_ATTR_MARK; } int nfnl_ct_test_mark(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_MARK); } uint32_t nfnl_ct_get_mark(const struct nfnl_ct *ct) { return ct->ct_mark; } void nfnl_ct_set_use(struct nfnl_ct *ct, uint32_t use) { ct->ct_use = use; ct->ce_mask |= CT_ATTR_USE; } int nfnl_ct_test_use(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_USE); } uint32_t nfnl_ct_get_use(const struct nfnl_ct *ct) { return ct->ct_use; } void nfnl_ct_set_id(struct nfnl_ct *ct, uint32_t id) { ct->ct_id = id; ct->ce_mask |= CT_ATTR_ID; } int nfnl_ct_test_id(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_ID); } uint32_t nfnl_ct_get_id(const struct nfnl_ct *ct) { return ct->ct_id; } void nfnl_ct_set_zone(struct nfnl_ct *ct, uint16_t zone) { ct->ct_zone = zone; ct->ce_mask |= CT_ATTR_ZONE; } int nfnl_ct_test_zone(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_ZONE); } uint16_t nfnl_ct_get_zone(const struct nfnl_ct *ct) { return ct->ct_zone; } static int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr, int attr, struct nl_addr ** ct_addr) { if (ct->ce_mask & CT_ATTR_FAMILY) { if (addr->a_family != ct->ct_family) return -NLE_AF_MISMATCH; } else nfnl_ct_set_family(ct, addr->a_family); if (*ct_addr) nl_addr_put(*ct_addr); nl_addr_get(addr); *ct_addr = addr; ct->ce_mask |= attr; return 0; } int nfnl_ct_set_src(struct nfnl_ct *ct, int repl, struct nl_addr *addr) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; return ct_set_addr(ct, addr, attr, &dir->src); } int nfnl_ct_set_dst(struct nfnl_ct *ct, int repl, struct nl_addr *addr) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; return ct_set_addr(ct, addr, attr, &dir->dst); } struct nl_addr *nfnl_ct_get_src(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; if (!(ct->ce_mask & attr)) return NULL; return dir->src; } struct nl_addr *nfnl_ct_get_dst(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; if (!(ct->ce_mask & attr)) return NULL; return dir->dst; } void nfnl_ct_set_src_port(struct nfnl_ct *ct, int repl, uint16_t port) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; dir->proto.port.src = port; ct->ce_mask |= attr; } int nfnl_ct_test_src_port(const struct nfnl_ct *ct, int repl) { int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; return !!(ct->ce_mask & attr); } uint16_t nfnl_ct_get_src_port(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; return dir->proto.port.src; } void nfnl_ct_set_dst_port(struct nfnl_ct *ct, int repl, uint16_t port) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; dir->proto.port.dst = port; ct->ce_mask |= attr; } int nfnl_ct_test_dst_port(const struct nfnl_ct *ct, int repl) { int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; return !!(ct->ce_mask & attr); } uint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; return dir->proto.port.dst; } void nfnl_ct_set_icmp_id(struct nfnl_ct *ct, int repl, uint16_t id) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; dir->proto.icmp.id = id; ct->ce_mask |= attr; } int nfnl_ct_test_icmp_id(const struct nfnl_ct *ct, int repl) { int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; return !!(ct->ce_mask & attr); } uint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; return dir->proto.icmp.id; } void nfnl_ct_set_icmp_type(struct nfnl_ct *ct, int repl, uint8_t type) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; dir->proto.icmp.type = type; ct->ce_mask |= attr; } int nfnl_ct_test_icmp_type(const struct nfnl_ct *ct, int repl) { int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; return !!(ct->ce_mask & attr); } uint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; return dir->proto.icmp.type; } void nfnl_ct_set_icmp_code(struct nfnl_ct *ct, int repl, uint8_t code) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; dir->proto.icmp.code = code; ct->ce_mask |= attr; } int nfnl_ct_test_icmp_code(const struct nfnl_ct *ct, int repl) { int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; return !!(ct->ce_mask & attr); } uint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; return dir->proto.icmp.code; } void nfnl_ct_set_packets(struct nfnl_ct *ct, int repl, uint64_t packets) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; dir->packets = packets; ct->ce_mask |= attr; } int nfnl_ct_test_packets(const struct nfnl_ct *ct, int repl) { int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; return !!(ct->ce_mask & attr); } uint64_t nfnl_ct_get_packets(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; return dir->packets; } void nfnl_ct_set_bytes(struct nfnl_ct *ct, int repl, uint64_t bytes) { struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; dir->bytes = bytes; ct->ce_mask |= attr; } int nfnl_ct_test_bytes(const struct nfnl_ct *ct, int repl) { int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; return !!(ct->ce_mask & attr); } uint64_t nfnl_ct_get_bytes(const struct nfnl_ct *ct, int repl) { const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; return dir->bytes; } void nfnl_ct_set_timestamp(struct nfnl_ct *ct, uint64_t start, uint64_t stop) { ct->ct_tstamp.start = start; ct->ct_tstamp.stop = stop; ct->ce_mask |= CT_ATTR_TIMESTAMP; } int nfnl_ct_test_timestamp(const struct nfnl_ct *ct) { return !!(ct->ce_mask & CT_ATTR_TIMESTAMP); } const struct nfnl_ct_timestamp *nfnl_ct_get_timestamp(const struct nfnl_ct *ct) { return &ct->ct_tstamp; } /** @} */ struct nl_object_ops ct_obj_ops = { .oo_name = "netfilter/ct", .oo_size = sizeof(struct nfnl_ct), .oo_free_data = ct_free_data, .oo_clone = ct_clone, .oo_dump = { [NL_DUMP_LINE] = ct_dump_line, [NL_DUMP_DETAILS] = ct_dump_details, [NL_DUMP_STATS] = ct_dump_stats, }, .oo_compare = ct_compare, .oo_attrs2str = ct_attrs2str, }; /** @} */ libnl-3.2.29/lib/netfilter/exp.c0000644000175000017500000003623513023014600013330 00000000000000/* * lib/netfilter/exp.c Conntrack Expectation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c= 2008 Patrick McHardy * Copyright (c) 2012 Rich Fought */ /** * @ingroup nfnl * @defgroup exp Expectation * @brief * @{ */ #include #include #include #include #include #include #include static struct nl_cache_ops nfnl_exp_ops; static struct nla_policy exp_policy[CTA_EXPECT_MAX+1] = { [CTA_EXPECT_MASTER] = { .type = NLA_NESTED }, [CTA_EXPECT_TUPLE] = { .type = NLA_NESTED }, [CTA_EXPECT_MASK] = { .type = NLA_NESTED }, [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 }, [CTA_EXPECT_ID] = { .type = NLA_U32 }, [CTA_EXPECT_HELP_NAME] = { .type = NLA_STRING }, [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, // Added in kernel 2.6.37 [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, // Added in kernel 3.5 [CTA_EXPECT_NAT] = { .type = NLA_NESTED }, // Added in kernel 3.5 [CTA_EXPECT_FN] = { .type = NLA_STRING }, // Added in kernel 3.5 }; static struct nla_policy exp_tuple_policy[CTA_TUPLE_MAX+1] = { [CTA_TUPLE_IP] = { .type = NLA_NESTED }, [CTA_TUPLE_PROTO] = { .type = NLA_NESTED }, }; static struct nla_policy exp_ip_policy[CTA_IP_MAX+1] = { [CTA_IP_V4_SRC] = { .type = NLA_U32 }, [CTA_IP_V4_DST] = { .type = NLA_U32 }, [CTA_IP_V6_SRC] = { .minlen = 16 }, [CTA_IP_V6_DST] = { .minlen = 16 }, }; static struct nla_policy exp_proto_policy[CTA_PROTO_MAX+1] = { [CTA_PROTO_NUM] = { .type = NLA_U8 }, [CTA_PROTO_SRC_PORT] = { .type = NLA_U16 }, [CTA_PROTO_DST_PORT] = { .type = NLA_U16 }, [CTA_PROTO_ICMP_ID] = { .type = NLA_U16 }, [CTA_PROTO_ICMP_TYPE] = { .type = NLA_U8 }, [CTA_PROTO_ICMP_CODE] = { .type = NLA_U8 }, [CTA_PROTO_ICMPV6_ID] = { .type = NLA_U16 }, [CTA_PROTO_ICMPV6_TYPE] = { .type = NLA_U8 }, [CTA_PROTO_ICMPV6_CODE] = { .type = NLA_U8 }, }; static struct nla_policy exp_nat_policy[CTA_EXPECT_NAT_MAX+1] = { [CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 }, [CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED }, }; static int exp_parse_ip(struct nfnl_exp *exp, int tuple, struct nlattr *attr) { struct nlattr *tb[CTA_IP_MAX+1]; struct nl_addr *addr; int err; err = nla_parse_nested(tb, CTA_IP_MAX, attr, exp_ip_policy); if (err < 0) goto errout; if (tb[CTA_IP_V4_SRC]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V4_SRC], AF_INET); if (addr == NULL) goto errout_enomem; err = nfnl_exp_set_src(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; } if (tb[CTA_IP_V4_DST]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V4_DST], AF_INET); if (addr == NULL) goto errout_enomem; err = nfnl_exp_set_dst(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; } if (tb[CTA_IP_V6_SRC]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V6_SRC], AF_INET6); if (addr == NULL) goto errout_enomem; err = nfnl_exp_set_src(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; } if (tb[CTA_IP_V6_DST]) { addr = nl_addr_alloc_attr(tb[CTA_IP_V6_DST], AF_INET6); if (addr == NULL) goto errout_enomem; err = nfnl_exp_set_dst(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; } return 0; errout_enomem: err = -NLE_NOMEM; errout: return err; } static int exp_parse_proto(struct nfnl_exp *exp, int tuple, struct nlattr *attr) { struct nlattr *tb[CTA_PROTO_MAX+1]; int err; uint16_t srcport = 0, dstport = 0, icmpid = 0; uint8_t icmptype = 0, icmpcode = 0; err = nla_parse_nested(tb, CTA_PROTO_MAX, attr, exp_proto_policy); if (err < 0) return err; if (tb[CTA_PROTO_NUM]) nfnl_exp_set_l4protonum(exp, tuple, nla_get_u8(tb[CTA_PROTO_NUM])); if (tb[CTA_PROTO_SRC_PORT]) srcport = ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT])); if (tb[CTA_PROTO_DST_PORT]) dstport = ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT])); if (tb[CTA_PROTO_SRC_PORT] || tb[CTA_PROTO_DST_PORT]) nfnl_exp_set_ports(exp, tuple, srcport, dstport); if (tb[CTA_PROTO_ICMP_ID]) icmpid = ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])); if (tb[CTA_PROTO_ICMP_TYPE]) icmptype = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]); if (tb[CTA_PROTO_ICMP_CODE]) icmpcode = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]); if (tb[CTA_PROTO_ICMP_ID] || tb[CTA_PROTO_ICMP_TYPE] || tb[CTA_PROTO_ICMP_CODE]) nfnl_exp_set_icmp(exp, tuple, icmpid, icmptype, icmpcode); return 0; } static int exp_parse_tuple(struct nfnl_exp *exp, int tuple, struct nlattr *attr) { struct nlattr *tb[CTA_TUPLE_MAX+1]; int err; err = nla_parse_nested(tb, CTA_TUPLE_MAX, attr, exp_tuple_policy); if (err < 0) return err; if (tb[CTA_TUPLE_IP]) { err = exp_parse_ip(exp, tuple, tb[CTA_TUPLE_IP]); if (err < 0) return err; } if (tb[CTA_TUPLE_PROTO]) { err = exp_parse_proto(exp, tuple, tb[CTA_TUPLE_PROTO]); if (err < 0) return err; } return 0; } static int exp_parse_nat(struct nfnl_exp *exp, struct nlattr *attr) { struct nlattr *tb[CTA_EXPECT_NAT_MAX+1]; int err; err = nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_policy); if (err < 0) return err; if (tb[CTA_EXPECT_NAT_DIR]) nfnl_exp_set_nat_dir(exp, nla_get_u32(tb[CTA_EXPECT_NAT_DIR])); if (tb[CTA_EXPECT_NAT_TUPLE]) { err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_NAT, tb[CTA_EXPECT_NAT_TUPLE]); if (err < 0) return err; } return 0; } int nfnlmsg_exp_group(struct nlmsghdr *nlh) { switch (nfnlmsg_subtype(nlh)) { case IPCTNL_MSG_EXP_NEW: if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL)) return NFNLGRP_CONNTRACK_EXP_NEW; else return NFNLGRP_CONNTRACK_EXP_UPDATE; case IPCTNL_MSG_EXP_DELETE: return NFNLGRP_CONNTRACK_EXP_DESTROY; default: return NFNLGRP_NONE; } } int nfnlmsg_exp_parse(struct nlmsghdr *nlh, struct nfnl_exp **result) { struct nfnl_exp *exp; struct nlattr *tb[CTA_MAX+1]; int err; exp = nfnl_exp_alloc(); if (!exp) return -NLE_NOMEM; exp->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_EXPECT_MAX, exp_policy); if (err < 0) goto errout; nfnl_exp_set_family(exp, nfnlmsg_family(nlh)); if (tb[CTA_EXPECT_TUPLE]) { err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_EXPECT, tb[CTA_EXPECT_TUPLE]); if (err < 0) goto errout; } if (tb[CTA_EXPECT_MASTER]) { err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_MASTER, tb[CTA_EXPECT_MASTER]); if (err < 0) goto errout; } if (tb[CTA_EXPECT_MASK]) { err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_MASK, tb[CTA_EXPECT_MASK]); if (err < 0) goto errout; } if (tb[CTA_EXPECT_NAT]) { err = exp_parse_nat(exp, tb[CTA_EXPECT_MASK]); if (err < 0) goto errout; } if (tb[CTA_EXPECT_CLASS]) nfnl_exp_set_class(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_CLASS]))); if (tb[CTA_EXPECT_FN]) nfnl_exp_set_fn(exp, nla_data(tb[CTA_EXPECT_FN])); if (tb[CTA_EXPECT_TIMEOUT]) nfnl_exp_set_timeout(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_TIMEOUT]))); if (tb[CTA_EXPECT_ID]) nfnl_exp_set_id(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_ID]))); if (tb[CTA_EXPECT_HELP_NAME]) nfnl_exp_set_helper_name(exp, nla_data(tb[CTA_EXPECT_HELP_NAME])); if (tb[CTA_EXPECT_ZONE]) nfnl_exp_set_zone(exp, ntohs(nla_get_u16(tb[CTA_EXPECT_ZONE]))); if (tb[CTA_EXPECT_FLAGS]) nfnl_exp_set_flags(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_FLAGS]))); *result = exp; return 0; errout: nfnl_exp_put(exp); return err; } static int exp_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct nfnl_exp *exp; int err; if ((err = nfnlmsg_exp_parse(nlh, &exp)) < 0) return err; err = pp->pp_cb((struct nl_object *) exp, pp); nfnl_exp_put(exp); return err; } /** * Send nfnl exp dump request * @arg sk Netlink socket. * * @return 0 on success or a negative error code. Due to a bug, this function * returns the number of bytes sent. Treat any non-negative number as success. */ int nfnl_exp_dump_request(struct nl_sock *sk) { return nfnl_send_simple(sk, NFNL_SUBSYS_CTNETLINK_EXP, IPCTNL_MSG_EXP_GET, NLM_F_DUMP, AF_UNSPEC, 0); } static int exp_request_update(struct nl_cache *cache, struct nl_sock *sk) { return nfnl_exp_dump_request(sk); } static int exp_get_tuple_attr(int tuple) { int attr = 0; switch (tuple) { case CTA_EXPECT_MASTER: attr = NFNL_EXP_TUPLE_MASTER; break; case CTA_EXPECT_MASK: attr = NFNL_EXP_TUPLE_MASK; break; case CTA_EXPECT_NAT: attr = NFNL_EXP_TUPLE_NAT; break; case CTA_EXPECT_TUPLE: default : attr = NFNL_EXP_TUPLE_EXPECT; break; } return attr; } static int nfnl_exp_build_tuple(struct nl_msg *msg, const struct nfnl_exp *exp, int cta) { struct nlattr *tuple, *ip, *proto; struct nl_addr *addr; int family; family = nfnl_exp_get_family(exp); int type = exp_get_tuple_attr(cta); if (cta == CTA_EXPECT_NAT) tuple = nla_nest_start(msg, CTA_EXPECT_NAT_TUPLE); else tuple = nla_nest_start(msg, cta); if (!tuple) goto nla_put_failure; ip = nla_nest_start(msg, CTA_TUPLE_IP); if (!ip) goto nla_put_failure; addr = nfnl_exp_get_src(exp, type); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC, addr); addr = nfnl_exp_get_dst(exp, type); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST, addr); nla_nest_end(msg, ip); proto = nla_nest_start(msg, CTA_TUPLE_PROTO); if (!proto) goto nla_put_failure; if (nfnl_exp_test_l4protonum(exp, type)) NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_exp_get_l4protonum(exp, type)); if (nfnl_exp_test_ports(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT, htons(nfnl_exp_get_src_port(exp, type))); NLA_PUT_U16(msg, CTA_PROTO_DST_PORT, htons(nfnl_exp_get_dst_port(exp, type))); } if (nfnl_exp_test_icmp(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID, htons(nfnl_exp_get_icmp_id(exp, type))); NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE, nfnl_exp_get_icmp_type(exp, type)); NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE, nfnl_exp_get_icmp_code(exp, type)); } nla_nest_end(msg, proto); nla_nest_end(msg, tuple); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int nfnl_exp_build_nat(struct nl_msg *msg, const struct nfnl_exp *exp) { struct nlattr *nat; int err; nat = nla_nest_start(msg, CTA_EXPECT_NAT); if (nfnl_exp_test_nat_dir(exp)) { NLA_PUT_U32(msg, CTA_EXPECT_NAT_DIR, nfnl_exp_get_nat_dir(exp)); } if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_NAT)) < 0) goto nla_put_failure; nla_nest_end(msg, nat); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int nfnl_exp_build_message(const struct nfnl_exp *exp, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; int err; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK_EXP, cmd, flags, nfnl_exp_get_family(exp), 0); if (msg == NULL) return -NLE_NOMEM; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_TUPLE)) < 0) goto err_out; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASTER)) < 0) goto err_out; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASK)) < 0) goto err_out; if (nfnl_exp_test_src(exp, NFNL_EXP_TUPLE_NAT)) { if ((err = nfnl_exp_build_nat(msg, exp)) < 0) goto err_out; } if (nfnl_exp_test_class(exp)) NLA_PUT_U32(msg, CTA_EXPECT_CLASS, htonl(nfnl_exp_get_class(exp))); if (nfnl_exp_test_fn(exp)) NLA_PUT_STRING(msg, CTA_EXPECT_FN, nfnl_exp_get_fn(exp)); if (nfnl_exp_test_id(exp)) NLA_PUT_U32(msg, CTA_EXPECT_ID, htonl(nfnl_exp_get_id(exp))); if (nfnl_exp_test_timeout(exp)) NLA_PUT_U32(msg, CTA_EXPECT_TIMEOUT, htonl(nfnl_exp_get_timeout(exp))); if (nfnl_exp_test_helper_name(exp)) NLA_PUT_STRING(msg, CTA_EXPECT_HELP_NAME, nfnl_exp_get_helper_name(exp)); if (nfnl_exp_test_zone(exp)) NLA_PUT_U16(msg, CTA_EXPECT_ZONE, htons(nfnl_exp_get_zone(exp))); if (nfnl_exp_test_flags(exp)) NLA_PUT_U32(msg, CTA_EXPECT_FLAGS, htonl(nfnl_exp_get_flags(exp))); *result = msg; return 0; nla_put_failure: err_out: nlmsg_free(msg); return err; } int nfnl_exp_build_add_request(const struct nfnl_exp *exp, int flags, struct nl_msg **result) { return nfnl_exp_build_message(exp, IPCTNL_MSG_EXP_NEW, flags, result); } int nfnl_exp_add(struct nl_sock *sk, const struct nfnl_exp *exp, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_exp_build_add_request(exp, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } int nfnl_exp_build_delete_request(const struct nfnl_exp *exp, int flags, struct nl_msg **result) { return nfnl_exp_build_message(exp, IPCTNL_MSG_EXP_DELETE, flags, result); } int nfnl_exp_del(struct nl_sock *sk, const struct nfnl_exp *exp, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_exp_build_delete_request(exp, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } int nfnl_exp_build_query_request(const struct nfnl_exp *exp, int flags, struct nl_msg **result) { return nfnl_exp_build_message(exp, IPCTNL_MSG_EXP_GET, flags, result); } int nfnl_exp_query(struct nl_sock *sk, const struct nfnl_exp *exp, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_exp_build_query_request(exp, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** * @name Cache Management * @{ */ /** * Build a expectation cache holding all expectations currently in the kernel * @arg sk Netlink socket. * @arg result Pointer to store resulting cache. * * Allocates a new cache, initializes it properly and updates it to * contain all expectations currently in the kernel. * * @return 0 on success or a negative error code. */ int nfnl_exp_alloc_cache(struct nl_sock *sk, struct nl_cache **result) { return nl_cache_alloc_and_fill(&nfnl_exp_ops, sk, result); } /** @} */ /** * @name Expectation Addition * @{ */ /** @} */ static struct nl_af_group exp_groups[] = { { AF_UNSPEC, NFNLGRP_CONNTRACK_EXP_NEW }, { AF_UNSPEC, NFNLGRP_CONNTRACK_EXP_UPDATE }, { AF_UNSPEC, NFNLGRP_CONNTRACK_EXP_DESTROY }, { END_OF_GROUP_LIST }, }; #define NFNLMSG_EXP_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_CTNETLINK_EXP, (type)) static struct nl_cache_ops nfnl_exp_ops = { .co_name = "netfilter/exp", .co_hdrsize = NFNL_HDRLEN, .co_msgtypes = { { NFNLMSG_EXP_TYPE(IPCTNL_MSG_EXP_NEW), NL_ACT_NEW, "new" }, { NFNLMSG_EXP_TYPE(IPCTNL_MSG_EXP_GET), NL_ACT_GET, "get" }, { NFNLMSG_EXP_TYPE(IPCTNL_MSG_EXP_DELETE), NL_ACT_DEL, "del" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_NETFILTER, .co_groups = exp_groups, .co_request_update = exp_request_update, .co_msg_parser = exp_msg_parser, .co_obj_ops = &exp_obj_ops, }; static void __init exp_init(void) { nl_cache_mngt_register(&nfnl_exp_ops); } static void __exit exp_exit(void) { nl_cache_mngt_unregister(&nfnl_exp_ops); } /** @} */ libnl-3.2.29/lib/netfilter/log.c0000644000175000017500000001243313023014600013307 00000000000000/* * lib/netfilter/log.c Netfilter Log * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ /** * @ingroup nfnl * @defgroup log Log * @brief * @{ */ #include #include #include #include #include #include /** * @name Log Commands * @{ */ static int build_log_cmd_request(uint8_t family, uint16_t queuenum, uint8_t command, struct nl_msg **result) { struct nl_msg *msg; struct nfulnl_msg_config_cmd cmd; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, family, queuenum); if (msg == NULL) return -NLE_NOMEM; cmd.command = command; if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } static int send_log_request(struct nl_sock *sk, struct nl_msg *msg) { int err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result) { return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result); } int nfnl_log_pf_bind(struct nl_sock *nlh, uint8_t pf) { struct nl_msg *msg; int err; if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0) return err; return send_log_request(nlh, msg); } int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result) { return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result); } int nfnl_log_pf_unbind(struct nl_sock *nlh, uint8_t pf) { struct nl_msg *msg; int err; if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0) return err; return send_log_request(nlh, msg); } static int nfnl_log_build_request(const struct nfnl_log *log, struct nl_msg **result) { struct nl_msg *msg; if (!nfnl_log_test_group(log)) return -NLE_MISSING_ATTR; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, 0, nfnl_log_get_group(log)); if (msg == NULL) return -NLE_NOMEM; /* This sucks. The nfnetlink_log interface always expects both * parameters to be present. Needs to be done properly. */ if (nfnl_log_test_copy_mode(log)) { struct nfulnl_msg_config_mode mode; switch (nfnl_log_get_copy_mode(log)) { case NFNL_LOG_COPY_NONE: mode.copy_mode = NFULNL_COPY_NONE; break; case NFNL_LOG_COPY_META: mode.copy_mode = NFULNL_COPY_META; break; case NFNL_LOG_COPY_PACKET: mode.copy_mode = NFULNL_COPY_PACKET; break; } mode.copy_range = htonl(nfnl_log_get_copy_range(log)); mode._pad = 0; if (nla_put(msg, NFULA_CFG_MODE, sizeof(mode), &mode) < 0) goto nla_put_failure; } if (nfnl_log_test_flush_timeout(log) && nla_put_u32(msg, NFULA_CFG_TIMEOUT, htonl(nfnl_log_get_flush_timeout(log))) < 0) goto nla_put_failure; if (nfnl_log_test_alloc_size(log) && nla_put_u32(msg, NFULA_CFG_NLBUFSIZ, htonl(nfnl_log_get_alloc_size(log))) < 0) goto nla_put_failure; if (nfnl_log_test_queue_threshold(log) && nla_put_u32(msg, NFULA_CFG_QTHRESH, htonl(nfnl_log_get_queue_threshold(log))) < 0) goto nla_put_failure; *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } int nfnl_log_build_create_request(const struct nfnl_log *log, struct nl_msg **result) { struct nfulnl_msg_config_cmd cmd; int err; if ((err = nfnl_log_build_request(log, result)) < 0) return err; cmd.command = NFULNL_CFG_CMD_BIND; if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; return 0; nla_put_failure: nlmsg_free(*result); return -NLE_MSGSIZE; } int nfnl_log_create(struct nl_sock *nlh, const struct nfnl_log *log) { struct nl_msg *msg; int err; if ((err = nfnl_log_build_create_request(log, &msg)) < 0) return err; return send_log_request(nlh, msg); } int nfnl_log_build_change_request(const struct nfnl_log *log, struct nl_msg **result) { return nfnl_log_build_request(log, result); } int nfnl_log_change(struct nl_sock *nlh, const struct nfnl_log *log) { struct nl_msg *msg; int err; if ((err = nfnl_log_build_change_request(log, &msg)) < 0) return err; return send_log_request(nlh, msg); } int nfnl_log_build_delete_request(const struct nfnl_log *log, struct nl_msg **result) { if (!nfnl_log_test_group(log)) return -NLE_MISSING_ATTR; return build_log_cmd_request(0, nfnl_log_get_group(log), NFULNL_CFG_CMD_UNBIND, result); } int nfnl_log_delete(struct nl_sock *nlh, const struct nfnl_log *log) { struct nl_msg *msg; int err; if ((err = nfnl_log_build_delete_request(log, &msg)) < 0) return err; return send_log_request(nlh, msg); } /** @} */ static struct nl_cache_ops nfnl_log_ops = { .co_name = "netfilter/log", .co_obj_ops = &log_obj_ops, .co_msgtypes = { END_OF_MSGTYPES_LIST, }, }; static void __init log_init(void) { nl_cache_mngt_register(&nfnl_log_ops); } static void __exit log_exit(void) { nl_cache_mngt_unregister(&nfnl_log_ops); } /** @} */ libnl-3.2.29/lib/utils.c0000644000175000017500000006540213031472653011715 00000000000000/* * lib/utils.c Utility Functions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup core * @defgroup utils Utilities * * Collection of helper functions * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include #include #include /* exit() */ #include /** * Global variable indicating the desired level of debugging output. * * Level | Messages Printed * ----- | --------------------------------------------------------- * 0 | Debugging output disabled * 1 | Warnings, important events and notifications * 2 | More or less important debugging messages * 3 | Repetitive events causing a flood of debugging messages * 4 | Even less important messages * * If available, the variable will be initialized to the value of the * environment variable `NLDBG`. The default value is 0 (disabled). * * For more information, see section @core_doc{_debugging, Debugging}. */ int nl_debug = 0; /** @cond SKIP */ #ifdef NL_DEBUG struct nl_dump_params nl_debug_dp = { .dp_type = NL_DUMP_DETAILS, }; static void __init nl_debug_init(void) { char *nldbg, *end; if ((nldbg = getenv("NLDBG"))) { long level = strtol(nldbg, &end, 0); if (nldbg != end) nl_debug = level; } nl_debug_dp.dp_fd = stderr; } #endif int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)) { FILE *fd; char buf[128]; fd = fopen(path, "r"); if (fd == NULL) return -nl_syserr2nlerr(errno); while (fgets(buf, sizeof(buf), fd)) { int goodlen, err; long num; char *end; if (*buf == '#' || *buf == '\n' || *buf == '\r') continue; num = strtol(buf, &end, 0); if (end == buf) { fclose(fd); return -NLE_INVAL; } if (num == LONG_MIN || num == LONG_MAX) { fclose(fd); return -NLE_RANGE; } while (*end == ' ' || *end == '\t') end++; goodlen = strcspn(end, "#\r\n\t "); if (goodlen == 0) { fclose(fd); return -NLE_INVAL; } end[goodlen] = '\0'; err = cb(num, end); if (err < 0) { fclose(fd); return err; } } fclose(fd); return 0; } const char *nl_strerror_l(int err) { int errno_save = errno; locale_t loc = newlocale(LC_MESSAGES_MASK, "", (locale_t)0); const char *buf; if (loc == (locale_t)0) { if (errno == ENOENT) loc = newlocale(LC_MESSAGES_MASK, "POSIX", (locale_t)0); } if (loc != (locale_t)0) { buf = strerror_l(err, loc); freelocale(loc); } else { buf = "newlocale() failed"; } errno = errno_save; return buf; } /** @endcond */ /** * @name Pretty Printing of Numbers * @{ */ /** * Cancel down a byte counter * @arg l byte counter * @arg unit destination unit pointer * * Cancels down a byte counter until it reaches a reasonable * unit. The chosen unit is assigned to \a unit. * This function assume 1024 bytes in one kilobyte * * @return The cancelled down byte counter in the new unit. */ double nl_cancel_down_bytes(unsigned long long l, char **unit) { if (l >= 1099511627776LL) { *unit = "TiB"; return ((double) l) / 1099511627776LL; } else if (l >= 1073741824) { *unit = "GiB"; return ((double) l) / 1073741824; } else if (l >= 1048576) { *unit = "MiB"; return ((double) l) / 1048576; } else if (l >= 1024) { *unit = "KiB"; return ((double) l) / 1024; } else { *unit = "B"; return (double) l; } } /** * Cancel down a bit counter * @arg l bit counter * @arg unit destination unit pointer * * Cancels down bit counter until it reaches a reasonable * unit. The chosen unit is assigned to \a unit. * This function assume 1000 bits in one kilobit * * @return The cancelled down bit counter in the new unit. */ double nl_cancel_down_bits(unsigned long long l, char **unit) { if (l >= 1000000000000ULL) { *unit = "Tbit"; return ((double) l) / 1000000000000ULL; } if (l >= 1000000000) { *unit = "Gbit"; return ((double) l) / 1000000000; } if (l >= 1000000) { *unit = "Mbit"; return ((double) l) / 1000000; } if (l >= 1000) { *unit = "Kbit"; return ((double) l) / 1000; } *unit = "bit"; return (double) l; } int nl_rate2str(unsigned long long rate, int type, char *buf, size_t len) { char *unit; double frac; switch (type) { case NL_BYTE_RATE: frac = nl_cancel_down_bytes(rate, &unit); break; case NL_BIT_RATE: frac = nl_cancel_down_bits(rate, &unit); break; default: BUG(); } return snprintf(buf, len, "%.2f%s/s", frac, unit); } /** * Cancel down a micro second value * @arg l micro seconds * @arg unit destination unit pointer * * Cancels down a microsecond counter until it reaches a * reasonable unit. The chosen unit is assigned to \a unit. * * @return The cancelled down microsecond in the new unit */ double nl_cancel_down_us(uint32_t l, char **unit) { if (l >= 1000000) { *unit = "s"; return ((double) l) / 1000000; } else if (l >= 1000) { *unit = "ms"; return ((double) l) / 1000; } else { *unit = "us"; return (double) l; } } /** @} */ /** * @name Generic Unit Translations * @{ */ /** * Convert a character string to a size * @arg str size encoded as character string * * Converts the specified size as character to the corresponding * number of bytes. * * Supported formats are: * - b,kb/k,m/mb,gb/g for bytes * - bit,kbit/mbit/gbit * * This function assume 1000 bits in one kilobit and * 1024 bytes in one kilobyte * * @return The number of bytes or -1 if the string is unparseable */ long nl_size2int(const char *str) { char *p; long l = strtol(str, &p, 0); if (p == str) return -NLE_INVAL; if (*p) { if (!strcasecmp(p, "kb") || !strcasecmp(p, "k")) l *= 1024; else if (!strcasecmp(p, "gb") || !strcasecmp(p, "g")) l *= 1024*1024*1024; else if (!strcasecmp(p, "gbit")) l *= 1000000000L/8; else if (!strcasecmp(p, "mb") || !strcasecmp(p, "m")) l *= 1024*1024; else if (!strcasecmp(p, "mbit")) l *= 1000000/8; else if (!strcasecmp(p, "kbit")) l *= 1000/8; else if (!strcasecmp(p, "bit")) l /= 8; else if (strcasecmp(p, "b") != 0) return -NLE_INVAL; } return l; } static const struct { double limit; const char *unit; } size_units[] = { { 1024. * 1024. * 1024. * 1024. * 1024., "EiB" }, { 1024. * 1024. * 1024. * 1024., "TiB" }, { 1024. * 1024. * 1024., "GiB" }, { 1024. * 1024., "MiB" }, { 1024., "KiB" }, { 0., "B" }, }; /** * Convert a size toa character string * @arg size Size in number of bytes * @arg buf Buffer to write character string to * @arg len Size of buf * * This function converts a value in bytes to a human readable representation * of it. The function uses IEC prefixes: * * @code * 1024 bytes => 1 KiB * 1048576 bytes => 1 MiB * @endcode * * The highest prefix is used which ensures a result of >= 1.0, the result * is provided as floating point number with a maximum precision of 2 digits: * @code * 965176 bytes => 942.55 KiB * @endcode * * @return pointer to buf */ char *nl_size2str(const size_t size, char *buf, const size_t len) { size_t i; if (size == 0) { snprintf(buf, len, "0B"); return buf; } for (i = 0; i < ARRAY_SIZE(size_units); i++) { if (size >= size_units[i].limit) { snprintf(buf, len, "%.2g%s", (double) size / size_units[i].limit, size_units[i].unit); return buf; } } BUG(); } /** * Convert a character string to a probability * @arg str probability encoded as character string * * Converts the specified probability as character to the * corresponding probability number. * * Supported formats are: * - 0.0-1.0 * - 0%-100% * * @return The probability relative to NL_PROB_MIN and NL_PROB_MAX */ long nl_prob2int(const char *str) { char *p; double d = strtod(str, &p); if (p == str) return -NLE_INVAL; if (d > 1.0) d /= 100.0f; if (d > 1.0f || d < 0.0f) return -NLE_RANGE; if (*p && strcmp(p, "%") != 0) return -NLE_INVAL; return rint(d * NL_PROB_MAX); } /** @} */ /** * @name Time Translations * @{ */ #ifndef USER_HZ #define USER_HZ 100 #endif static uint32_t user_hz = USER_HZ; static uint32_t psched_hz = USER_HZ; static double ticks_per_usec = 1.0f; /* Retrieves the configured HZ and ticks/us value in the kernel. * The value is cached. Supported ways of getting it: * * 1) environment variable * 2) /proc/net/psched and sysconf * * Supports the environment variables: * PROC_NET_PSCHED - may point to psched file in /proc * PROC_ROOT - may point to /proc fs */ static void __init get_psched_settings(void) { char name[FILENAME_MAX]; FILE *fd; int got_hz = 0; if (getenv("HZ")) { long hz = strtol(getenv("HZ"), NULL, 0); if (LONG_MIN != hz && LONG_MAX != hz) { user_hz = hz; got_hz = 1; } } if (!got_hz) user_hz = sysconf(_SC_CLK_TCK); psched_hz = user_hz; if (getenv("TICKS_PER_USEC")) { double t = strtod(getenv("TICKS_PER_USEC"), NULL); ticks_per_usec = t; } else { if (getenv("PROC_NET_PSCHED")) snprintf(name, sizeof(name), "%s", getenv("PROC_NET_PSCHED")); else if (getenv("PROC_ROOT")) snprintf(name, sizeof(name), "%s/net/psched", getenv("PROC_ROOT")); else strncpy(name, "/proc/net/psched", sizeof(name) - 1); if ((fd = fopen(name, "r"))) { unsigned int ns_per_usec, ns_per_tick, nom, denom; if (fscanf(fd, "%08x %08x %08x %08x", &ns_per_usec, &ns_per_tick, &nom, &denom) != 4) { NL_DBG(1, "Fatal error: can not read psched settings from \"%s\". " \ "Try to set TICKS_PER_USEC, PROC_NET_PSCHED or PROC_ROOT " \ "environment variables\n", name); exit(1); } ticks_per_usec = (double) ns_per_usec / (double) ns_per_tick; if (nom == 1000000) psched_hz = denom; fclose(fd); } } } /** * Return the value of HZ */ int nl_get_user_hz(void) { return user_hz; } /** * Return the value of packet scheduler HZ */ int nl_get_psched_hz(void) { return psched_hz; } /** * Convert micro seconds to ticks * @arg us micro seconds * @return number of ticks */ uint32_t nl_us2ticks(uint32_t us) { return us * ticks_per_usec; } /** * Convert ticks to micro seconds * @arg ticks number of ticks * @return microseconds */ uint32_t nl_ticks2us(uint32_t ticks) { return ticks / ticks_per_usec; } int nl_str2msec(const char *str, uint64_t *result) { uint64_t total = 0, l; int plen; char *p; do { l = strtoul(str, &p, 0); if (p == str) return -NLE_INVAL; else if (*p) { plen = strcspn(p, " \t"); if (!plen) total += l; else if (!strncasecmp(p, "sec", plen)) total += (l * 1000); else if (!strncasecmp(p, "min", plen)) total += (l * 1000*60); else if (!strncasecmp(p, "hour", plen)) total += (l * 1000*60*60); else if (!strncasecmp(p, "day", plen)) total += (l * 1000*60*60*24); else return -NLE_INVAL; str = p + plen; } else total += l; } while (*str && *p); *result = total; return 0; } /** * Convert milliseconds to a character string * @arg msec number of milliseconds * @arg buf destination buffer * @arg len buffer length * * Converts milliseconds to a character string split up in days, hours, * minutes, seconds, and milliseconds and stores it in the specified * destination buffer. * * @return The destination buffer. */ char * nl_msec2str(uint64_t msec, char *buf, size_t len) { uint64_t split[5]; size_t i; static const char *units[5] = {"d", "h", "m", "s", "msec"}; char * const buf_orig = buf; if (msec == 0) { snprintf(buf, len, "0msec"); return buf_orig; } #define _SPLIT(idx, unit) if ((split[idx] = msec / unit)) msec %= unit _SPLIT(0, 86400000); /* days */ _SPLIT(1, 3600000); /* hours */ _SPLIT(2, 60000); /* minutes */ _SPLIT(3, 1000); /* seconds */ #undef _SPLIT split[4] = msec; for (i = 0; i < ARRAY_SIZE(split) && len; i++) { int l; if (split[i] == 0) continue; l = snprintf(buf, len, "%s%" PRIu64 "%s", (buf==buf_orig) ? "" : " ", split[i], units[i]); buf += l; len -= l; } return buf_orig; } /** @} */ /** * @name Netlink Family Translations * @{ */ static const struct trans_tbl nlfamilies[] = { __ADD(NETLINK_ROUTE,route), __ADD(NETLINK_USERSOCK,usersock), __ADD(NETLINK_FIREWALL,firewall), __ADD(NETLINK_INET_DIAG,inetdiag), __ADD(NETLINK_NFLOG,nflog), __ADD(NETLINK_XFRM,xfrm), __ADD(NETLINK_SELINUX,selinux), __ADD(NETLINK_ISCSI,iscsi), __ADD(NETLINK_AUDIT,audit), __ADD(NETLINK_FIB_LOOKUP,fib_lookup), __ADD(NETLINK_CONNECTOR,connector), __ADD(NETLINK_NETFILTER,netfilter), __ADD(NETLINK_IP6_FW,ip6_fw), __ADD(NETLINK_DNRTMSG,dnrtmsg), __ADD(NETLINK_KOBJECT_UEVENT,kobject_uevent), __ADD(NETLINK_GENERIC,generic), __ADD(NETLINK_SCSITRANSPORT,scsitransport), __ADD(NETLINK_ECRYPTFS,ecryptfs), __ADD(NETLINK_RDMA,rdma), __ADD(NETLINK_CRYPTO,crypto), }; char * nl_nlfamily2str(int family, char *buf, size_t size) { return __type2str(family, buf, size, nlfamilies, ARRAY_SIZE(nlfamilies)); } int nl_str2nlfamily(const char *name) { return __str2type(name, nlfamilies, ARRAY_SIZE(nlfamilies)); } /** * @} */ /** * @name Link Layer Protocol Translations * @{ */ static const struct trans_tbl llprotos[] = { {0, "generic"}, __ADD(ARPHRD_NETROM,netrom), __ADD(ARPHRD_ETHER,ether), __ADD(ARPHRD_EETHER,eether), __ADD(ARPHRD_AX25,ax25), __ADD(ARPHRD_PRONET,pronet), __ADD(ARPHRD_CHAOS,chaos), __ADD(ARPHRD_IEEE802,ieee802), __ADD(ARPHRD_ARCNET,arcnet), __ADD(ARPHRD_APPLETLK,atalk), __ADD(ARPHRD_DLCI,dlci), __ADD(ARPHRD_ATM,atm), __ADD(ARPHRD_METRICOM,metricom), __ADD(ARPHRD_IEEE1394,ieee1394), __ADD(ARPHRD_EUI64,eui64), __ADD(ARPHRD_INFINIBAND,infiniband), __ADD(ARPHRD_SLIP,slip), __ADD(ARPHRD_CSLIP,cslip), __ADD(ARPHRD_SLIP6,slip6), __ADD(ARPHRD_CSLIP6,cslip6), __ADD(ARPHRD_RSRVD,rsrvd), __ADD(ARPHRD_ADAPT,adapt), __ADD(ARPHRD_ROSE,rose), __ADD(ARPHRD_X25,x25), __ADD(ARPHRD_HWX25,hwx25), __ADD(ARPHRD_CAN,can), __ADD(ARPHRD_PPP,ppp), __ADD(ARPHRD_CISCO,cisco), __ADD(ARPHRD_HDLC,hdlc), __ADD(ARPHRD_LAPB,lapb), __ADD(ARPHRD_DDCMP,ddcmp), __ADD(ARPHRD_RAWHDLC,rawhdlc), __ADD(ARPHRD_TUNNEL,ipip), __ADD(ARPHRD_TUNNEL6,tunnel6), __ADD(ARPHRD_FRAD,frad), __ADD(ARPHRD_SKIP,skip), __ADD(ARPHRD_LOOPBACK,loopback), __ADD(ARPHRD_LOCALTLK,localtlk), __ADD(ARPHRD_FDDI,fddi), __ADD(ARPHRD_BIF,bif), __ADD(ARPHRD_SIT,sit), __ADD(ARPHRD_IPDDP,ip/ddp), __ADD(ARPHRD_IPGRE,gre), __ADD(ARPHRD_PIMREG,pimreg), __ADD(ARPHRD_HIPPI,hippi), __ADD(ARPHRD_ASH,ash), __ADD(ARPHRD_ECONET,econet), __ADD(ARPHRD_IRDA,irda), __ADD(ARPHRD_FCPP,fcpp), __ADD(ARPHRD_FCAL,fcal), __ADD(ARPHRD_FCPL,fcpl), __ADD(ARPHRD_FCFABRIC,fcfb_0), __ADD(ARPHRD_FCFABRIC+1,fcfb_1), __ADD(ARPHRD_FCFABRIC+2,fcfb_2), __ADD(ARPHRD_FCFABRIC+3,fcfb_3), __ADD(ARPHRD_FCFABRIC+4,fcfb_4), __ADD(ARPHRD_FCFABRIC+5,fcfb_5), __ADD(ARPHRD_FCFABRIC+6,fcfb_6), __ADD(ARPHRD_FCFABRIC+7,fcfb_7), __ADD(ARPHRD_FCFABRIC+8,fcfb_8), __ADD(ARPHRD_FCFABRIC+9,fcfb_9), __ADD(ARPHRD_FCFABRIC+10,fcfb_10), __ADD(ARPHRD_FCFABRIC+11,fcfb_11), __ADD(ARPHRD_FCFABRIC+12,fcfb_12), __ADD(ARPHRD_IEEE802_TR,tr), __ADD(ARPHRD_IEEE80211,ieee802.11), __ADD(ARPHRD_IEEE80211_PRISM,ieee802.11_prism), __ADD(ARPHRD_IEEE80211_RADIOTAP,ieee802.11_radiotap), __ADD(ARPHRD_IEEE802154,ieee802.15.4), __ADD(ARPHRD_IEEE802154_MONITOR,ieee802.15.4_monitor), __ADD(ARPHRD_PHONET,phonet), __ADD(ARPHRD_PHONET_PIPE,phonet_pipe), __ADD(ARPHRD_CAIF,caif), __ADD(ARPHRD_IP6GRE,ip6gre), __ADD(ARPHRD_NETLINK,netlink), __ADD(ARPHRD_6LOWPAN,6lowpan), __ADD(ARPHRD_VOID,void), __ADD(ARPHRD_NONE,nohdr), }; char * nl_llproto2str(int llproto, char *buf, size_t len) { return __type2str(llproto, buf, len, llprotos, ARRAY_SIZE(llprotos)); } int nl_str2llproto(const char *name) { return __str2type(name, llprotos, ARRAY_SIZE(llprotos)); } /** @} */ /** * @name Ethernet Protocol Translations * @{ */ static const struct trans_tbl ether_protos[] = { __ADD(ETH_P_LOOP,loop), __ADD(ETH_P_PUP,pup), __ADD(ETH_P_PUPAT,pupat), __ADD(ETH_P_IP,ip), __ADD(ETH_P_X25,x25), __ADD(ETH_P_ARP,arp), __ADD(ETH_P_BPQ,bpq), __ADD(ETH_P_IEEEPUP,ieeepup), __ADD(ETH_P_IEEEPUPAT,ieeepupat), __ADD(ETH_P_DEC,dec), __ADD(ETH_P_DNA_DL,dna_dl), __ADD(ETH_P_DNA_RC,dna_rc), __ADD(ETH_P_DNA_RT,dna_rt), __ADD(ETH_P_LAT,lat), __ADD(ETH_P_DIAG,diag), __ADD(ETH_P_CUST,cust), __ADD(ETH_P_SCA,sca), __ADD(ETH_P_TEB,teb), __ADD(ETH_P_RARP,rarp), __ADD(ETH_P_ATALK,atalk), __ADD(ETH_P_AARP,aarp), #ifdef ETH_P_8021Q __ADD(ETH_P_8021Q,802.1q), #endif __ADD(ETH_P_IPX,ipx), __ADD(ETH_P_IPV6,ipv6), __ADD(ETH_P_PAUSE,pause), __ADD(ETH_P_SLOW,slow), #ifdef ETH_P_WCCP __ADD(ETH_P_WCCP,wccp), #endif __ADD(ETH_P_PPP_DISC,ppp_disc), __ADD(ETH_P_PPP_SES,ppp_ses), __ADD(ETH_P_MPLS_UC,mpls_uc), __ADD(ETH_P_MPLS_MC,mpls_mc), __ADD(ETH_P_ATMMPOA,atmmpoa), __ADD(ETH_P_LINK_CTL,link_ctl), __ADD(ETH_P_ATMFATE,atmfate), __ADD(ETH_P_PAE,pae), __ADD(ETH_P_AOE,aoe), __ADD(ETH_P_TIPC,tipc), __ADD(ETH_P_1588,ieee1588), __ADD(ETH_P_FCOE,fcoe), __ADD(ETH_P_FIP,fip), __ADD(ETH_P_EDSA,edsa), __ADD(ETH_P_EDP2,edp2), __ADD(ETH_P_802_3,802.3), __ADD(ETH_P_AX25,ax25), __ADD(ETH_P_ALL,all), __ADD(ETH_P_802_2,802.2), __ADD(ETH_P_SNAP,snap), __ADD(ETH_P_DDCMP,ddcmp), __ADD(ETH_P_WAN_PPP,wan_ppp), __ADD(ETH_P_PPP_MP,ppp_mp), __ADD(ETH_P_LOCALTALK,localtalk), __ADD(ETH_P_CAN,can), __ADD(ETH_P_PPPTALK,ppptalk), __ADD(ETH_P_TR_802_2,tr_802.2), __ADD(ETH_P_MOBITEX,mobitex), __ADD(ETH_P_CONTROL,control), __ADD(ETH_P_IRDA,irda), __ADD(ETH_P_ECONET,econet), __ADD(ETH_P_HDLC,hdlc), __ADD(ETH_P_ARCNET,arcnet), __ADD(ETH_P_DSA,dsa), __ADD(ETH_P_TRAILER,trailer), __ADD(ETH_P_PHONET,phonet), __ADD(ETH_P_IEEE802154,ieee802154), __ADD(ETH_P_CAIF,caif), }; char *nl_ether_proto2str(int eproto, char *buf, size_t len) { return __type2str(eproto, buf, len, ether_protos, ARRAY_SIZE(ether_protos)); } int nl_str2ether_proto(const char *name) { return __str2type(name, ether_protos, ARRAY_SIZE(ether_protos)); } /** @} */ /** * @name IP Protocol Translations * @{ */ char *nl_ip_proto2str(int proto, char *buf, size_t len) { struct protoent *p = getprotobynumber(proto); if (p) { snprintf(buf, len, "%s", p->p_name); return buf; } snprintf(buf, len, "0x%x", proto); return buf; } int nl_str2ip_proto(const char *name) { struct protoent *p = getprotobyname(name); unsigned long l; char *end; if (p) return p->p_proto; l = strtoul(name, &end, 0); if (l == ULONG_MAX || *end != '\0') return -NLE_OBJ_NOTFOUND; return (int) l; } /** @} */ /** * @name Dumping Helpers * @{ */ /** * Handle a new line while dumping * @arg params Dumping parameters * * This function must be called before dumping any onto a * new line. It will ensure proper prefixing as specified * by the dumping parameters. * * @note This function will NOT dump any newlines itself */ void nl_new_line(struct nl_dump_params *params) { params->dp_line++; if (params->dp_prefix) { int i; for (i = 0; i < params->dp_prefix; i++) { if (params->dp_fd) fprintf(params->dp_fd, " "); else if (params->dp_buf) strncat(params->dp_buf, " ", params->dp_buflen - strlen(params->dp_buf) - 1); } } if (params->dp_nl_cb) params->dp_nl_cb(params, params->dp_line); } static void dump_one(struct nl_dump_params *parms, const char *fmt, va_list args) { if (parms->dp_fd) vfprintf(parms->dp_fd, fmt, args); else if (parms->dp_buf || parms->dp_cb) { char *buf = NULL; if (vasprintf(&buf, fmt, args) >= 0) { if (parms->dp_cb) parms->dp_cb(parms, buf); else strncat(parms->dp_buf, buf, parms->dp_buflen - strlen(parms->dp_buf) - 1); free(buf); } } } /** * Dump a formatted character string * @arg params Dumping parameters * @arg fmt printf style formatting string * @arg ... Arguments to formatting string * * Dumps a printf style formatting string to the output device * as specified by the dumping parameters. */ void nl_dump(struct nl_dump_params *params, const char *fmt, ...) { va_list args; va_start(args, fmt); dump_one(params, fmt, args); va_end(args); } void nl_dump_line(struct nl_dump_params *parms, const char *fmt, ...) { va_list args; nl_new_line(parms); va_start(args, fmt); dump_one(parms, fmt, args); va_end(args); } /** @} */ /** @cond SKIP */ int __trans_list_add(int i, const char *a, struct nl_list_head *head) { struct trans_list *tl; tl = calloc(1, sizeof(*tl)); if (!tl) return -NLE_NOMEM; tl->i = i; tl->a = strdup(a); nl_list_add_tail(&tl->list, head); return 0; } void __trans_list_clear(struct nl_list_head *head) { struct trans_list *tl, *next; nl_list_for_each_entry_safe(tl, next, head, list) { free(tl->a); free(tl); } nl_init_list_head(head); } char *__type2str(int type, char *buf, size_t len, const struct trans_tbl *tbl, size_t tbl_len) { size_t i; for (i = 0; i < tbl_len; i++) { if (tbl[i].i == type) { snprintf(buf, len, "%s", tbl[i].a); return buf; } } snprintf(buf, len, "0x%x", type); return buf; } char *__list_type2str(int type, char *buf, size_t len, struct nl_list_head *head) { struct trans_list *tl; nl_list_for_each_entry(tl, head, list) { if (tl->i == type) { snprintf(buf, len, "%s", tl->a); return buf; } } snprintf(buf, len, "0x%x", type); return buf; } char *__flags2str(int flags, char *buf, size_t len, const struct trans_tbl *tbl, size_t tbl_len) { size_t i; int tmp = flags; memset(buf, 0, len); for (i = 0; i < tbl_len; i++) { if (tbl[i].i & tmp) { tmp &= ~tbl[i].i; strncat(buf, tbl[i].a, len - strlen(buf) - 1); if ((tmp & flags)) strncat(buf, ",", len - strlen(buf) - 1); } } return buf; } int __str2type(const char *buf, const struct trans_tbl *tbl, size_t tbl_len) { unsigned long l; char *end; size_t i; if (*buf == '\0') return -NLE_INVAL; for (i = 0; i < tbl_len; i++) if (!strcasecmp(tbl[i].a, buf)) return tbl[i].i; l = strtoul(buf, &end, 0); if (l == ULONG_MAX || *end != '\0') return -NLE_OBJ_NOTFOUND; return (int) l; } int __list_str2type(const char *buf, struct nl_list_head *head) { struct trans_list *tl; unsigned long l; char *end; if (*buf == '\0') return -NLE_INVAL; nl_list_for_each_entry(tl, head, list) { if (!strcasecmp(tl->a, buf)) return tl->i; } l = strtoul(buf, &end, 0); if (l == ULONG_MAX || *end != '\0') return -NLE_OBJ_NOTFOUND; return (int) l; } int __str2flags(const char *buf, const struct trans_tbl *tbl, size_t tbl_len) { int flags = 0; size_t i; size_t len; /* ptrdiff_t ? */ char *p = (char *) buf, *t; for (;;) { if (*p == ' ') p++; t = strchr(p, ','); len = t ? t - p : strlen(p); for (i = 0; i < tbl_len; i++) if (len == strlen(tbl[i].a) && !strncasecmp(tbl[i].a, p, len)) flags |= tbl[i].i; if (!t) return flags; p = ++t; } return 0; } void dump_from_ops(struct nl_object *obj, struct nl_dump_params *params) { int type = params->dp_type; if (type < 0 || type > NL_DUMP_MAX) BUG(); params->dp_line = 0; if (params->dp_dump_msgtype) { #if 0 /* XXX */ char buf[64]; dp_dump_line(params, 0, "%s ", nl_cache_mngt_type2name(obj->ce_ops, obj->ce_ops->co_protocol, obj->ce_msgtype, buf, sizeof(buf))); #endif params->dp_pre_dump = 1; } if (obj->ce_ops->oo_dump[type]) obj->ce_ops->oo_dump[type](obj, params); } /** * Check for library capabilities * * @arg capability capability identifier * * Check whether the loaded libnl library supports a certain capability. * This is useful so that applications can workaround known issues of * libnl that are fixed in newer library versions, without * having a hard dependency on the new version. It is also useful, for * capabilities that cannot easily be detected using autoconf tests. * The capabilities are integer constants with name NL_CAPABILITY_*. * * As this function is intended to detect capabilities at runtime, * you might not want to depend during compile time on the NL_CAPABILITY_* * names. Instead you can use their numeric values which are guaranteed not to * change meaning. * * @return non zero if libnl supports a certain capability, 0 otherwise. **/ int nl_has_capability (int capability) { static const uint8_t caps[ ( NL_CAPABILITY_MAX + 7 ) / 8 ] = { #define _NL_ASSERT(expr) ( 0 * sizeof(struct { unsigned int x: ( (!!(expr)) ? 1 : -1 ); }) ) #define _NL_SETV(i, r, v) \ ( _NL_ASSERT( (v) == 0 || (i) * 8 + (r) == (v) - 1 ) + \ ( (v) == 0 ? 0 : (1 << (r)) ) ) #define _NL_SET(i, v0, v1, v2, v3, v4, v5, v6, v7) \ [(i)] = ( \ _NL_SETV((i), 0, (v0)) | _NL_SETV((i), 4, (v4)) | \ _NL_SETV((i), 1, (v1)) | _NL_SETV((i), 5, (v5)) | \ _NL_SETV((i), 2, (v2)) | _NL_SETV((i), 6, (v6)) | \ _NL_SETV((i), 3, (v3)) | _NL_SETV((i), 7, (v7)) ) _NL_SET(0, NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE, NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE, NL_CAPABILITY_ROUTE_LINK_CLS_ADD_ACT_OWN_REFERENCE, NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE, NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP, NL_CAPABILITY_ROUTE_ADDR_COMPARE_CACHEINFO, NL_CAPABILITY_VERSION_3_2_26, NL_CAPABILITY_NL_RECV_FAIL_TRUNC_NO_PEEK), _NL_SET(1, NL_CAPABILITY_LINK_BUILD_CHANGE_REQUEST_SET_CHANGE, NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX, NL_CAPABILITY_VERSION_3_2_27, NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE, NL_CAPABILITY_RTNL_LINK_PARSE_GRE_REMOTE, NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR, NL_CAPABILITY_RTNL_LINK_VXLAN_IO_COMPARE, NL_CAPABILITY_NL_OBJECT_DIFF64), _NL_SET (2, NL_CAPABILITY_XFRM_SA_KEY_SIZE, NL_CAPABILITY_RTNL_ADDR_PEER_FIX, NL_CAPABILITY_VERSION_3_2_28, NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX, NL_CAPABILITY_NL_ADDR_FILL_SOCKADDR, NL_CAPABILITY_XFRM_SEC_CTX_LEN, NL_CAPABILITY_LINK_BUILD_ADD_REQUEST_SET_CHANGE, NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT), _NL_SET (3, NL_CAPABILITY_VERSION_3_2_29, 0, 0, 0, 0, 0, 0, 0), /* IMPORTANT: these capability numbers are intended to be universal and stable * for libnl3. Don't allocate new numbers on your own that differ from upstream * libnl3. * * Instead register a capability number upstream too. We will take patches * for that. We especially take patches to register a capability number that is * only implemented in your fork of libnl3. * * If you really don't want that, use capabilities in the range 0x7000 to 0x7FFF. * (NL_CAPABILITY_IS_USER_RESERVED). Upstream libnl3 will not register conflicting * capabilities in that range. * * Obviously, only backport capability numbers to libnl versions that actually * implement that capability as well. */ #undef _NL_SET #undef _NL_SETV #undef _NL_ASSERT }; if (capability <= 0 || capability > NL_CAPABILITY_MAX) return 0; capability--; return (caps[capability / 8] & (1 << (capability % 8))) != 0; } /** @endcond */ /** @} */ libnl-3.2.29/lib/addr.c0000644000175000017500000005522313023014600011450 00000000000000/* * lib/addr.c Network Address * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ /** * @ingroup core_types * @defgroup addr Network Address * * Abstract data type representing any kind of network address * * Related sections in the development guide: * - @core_doc{_abstract_address, Network Addresses} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include #include /* All this DECnet stuff is stolen from iproute2, thanks to whoever wrote * this, probably Alexey. */ static inline uint16_t dn_ntohs(uint16_t addr) { union { uint8_t byte[2]; uint16_t word; } u = { .word = addr, }; return ((uint16_t) u.byte[0]) | (((uint16_t) u.byte[1]) << 8); } static inline int do_digit(char *str, uint16_t *addr, uint16_t scale, size_t *pos, size_t len, int *started) { uint16_t tmp = *addr / scale; if (*pos == len) return 1; if (((tmp) > 0) || *started || (scale == 1)) { *str = tmp + '0'; *started = 1; (*pos)++; *addr -= (tmp * scale); } return 0; } static const char *dnet_ntop(const char *addrbuf, size_t addrlen, char *str, size_t len) { uint16_t addr = dn_ntohs(*(uint16_t *)addrbuf); uint16_t area = addr >> 10; size_t pos = 0; int started = 0; if (addrlen != 2) return NULL; addr &= 0x03ff; if (len == 0) return str; if (do_digit(str + pos, &area, 10, &pos, len, &started)) return str; if (do_digit(str + pos, &area, 1, &pos, len, &started)) return str; if (pos == len) return str; *(str + pos) = '.'; pos++; started = 0; if (do_digit(str + pos, &addr, 1000, &pos, len, &started)) return str; if (do_digit(str + pos, &addr, 100, &pos, len, &started)) return str; if (do_digit(str + pos, &addr, 10, &pos, len, &started)) return str; if (do_digit(str + pos, &addr, 1, &pos, len, &started)) return str; if (pos == len) return str; *(str + pos) = 0; return str; } static int dnet_num(const char *src, uint16_t * dst) { int rv = 0; int tmp; *dst = 0; while ((tmp = *src++) != 0) { tmp -= '0'; if ((tmp < 0) || (tmp > 9)) return rv; rv++; (*dst) *= 10; (*dst) += tmp; } return rv; } static inline int dnet_pton(const char *src, char *addrbuf) { uint16_t area = 0; uint16_t node = 0; int pos; pos = dnet_num(src, &area); if ((pos == 0) || (area > 63) || ((*(src + pos) != '.') && (*(src + pos) != ','))) return -NLE_INVAL; pos = dnet_num(src + pos + 1, &node); if ((pos == 0) || (node > 1023)) return -NLE_INVAL; *(uint16_t *)addrbuf = dn_ntohs((area << 10) | node); return 1; } static void addr_destroy(struct nl_addr *addr) { if (!addr) return; if (addr->a_refcnt != 1) BUG(); free(addr); } /** * @name Creating Abstract Network Addresses * @{ */ /** * Allocate empty abstract address * @arg maxsize Upper limit of the binary address to be stored * * The new address object will be empty with a prefix length of 0 and will * be capable of holding binary addresses up to the specified limit. * * @see nl_addr_build() * @see nl_addr_parse() * @see nl_addr_put() * * @return Allocated address object or NULL upon failure. */ struct nl_addr *nl_addr_alloc(size_t maxsize) { struct nl_addr *addr; addr = calloc(1, sizeof(*addr) + maxsize); if (!addr) return NULL; addr->a_refcnt = 1; addr->a_maxsize = maxsize; return addr; } /** * Allocate abstract address based on a binary address. * @arg family Address family * @arg buf Binary address * @arg size Length of binary address * * This function will allocate an abstract address capable of holding the * binary address specified. The prefix length will be set to the full * length of the binary address provided. * * @see nl_addr_alloc() * @see nl_addr_alloc_attr() * @see nl_addr_parse() * @see nl_addr_put() * * @return Allocated address object or NULL upon failure. */ struct nl_addr *nl_addr_build(int family, const void *buf, size_t size) { struct nl_addr *addr; addr = nl_addr_alloc(size); if (!addr) return NULL; addr->a_family = family; addr->a_len = size; addr->a_prefixlen = size*8; if (size) memcpy(addr->a_addr, buf, size); return addr; } /** * Allocate abstract address based on Netlink attribute. * @arg nla Netlink attribute * @arg family Address family. * * Allocates an abstract address based on the specified Netlink attribute * by interpreting the payload of the Netlink attribute as the binary * address. * * This function is identical to: * @code * nl_addr_build(family, nla_data(nla), nla_len(nla)); * @endcode * * @see nl_addr_alloc() * @see nl_addr_build() * @see nl_addr_parse() * @see nl_addr_put() * * @return Allocated address object or NULL upon failure. */ struct nl_addr *nl_addr_alloc_attr(const struct nlattr *nla, int family) { return nl_addr_build(family, nla_data(nla), nla_len(nla)); } /** * Allocate abstract address based on character string * @arg addrstr Address represented as character string. * @arg hint Address family hint or AF_UNSPEC. * @arg result Pointer to store resulting address. * * Regognizes the following address formats: * @code * Format Len Family * ---------------------------------------------------------------- * IPv6 address format 16 AF_INET6 * ddd.ddd.ddd.ddd 4 AF_INET * HH:HH:HH:HH:HH:HH 6 AF_LLC * AA{.|,}NNNN 2 AF_DECnet * HH:HH:HH:... variable AF_UNSPEC * @endcode * * Special values: * - none: All bits and length set to 0. * - {default|all|any}: All bits set to 0, length based on hint or * AF_INET if no hint is given. * * The prefix length may be appened at the end prefixed with a * slash, e.g. 10.0.0.0/8. * * @see nl_addr_alloc() * @see nl_addr_build() * @see nl_addr_put() * * @return 0 on success or a negative error code. */ int nl_addr_parse(const char *addrstr, int hint, struct nl_addr **result) { int err, copy = 0, len = 0, family = AF_UNSPEC; char *str, *prefix, buf[32]; struct nl_addr *addr = NULL; /* gcc ain't that smart */ str = strdup(addrstr); if (!str) { err = -NLE_NOMEM; goto errout; } prefix = strchr(str, '/'); if (prefix) *prefix = '\0'; if (!strcasecmp(str, "none")) { family = hint; goto prefix; } if (!strcasecmp(str, "default") || !strcasecmp(str, "all") || !strcasecmp(str, "any")) { len = 0; switch (hint) { case AF_INET: case AF_UNSPEC: /* Kind of a hack, we assume that if there is * no hint given the user wants to have a IPv4 * address given back. */ family = AF_INET; goto prefix; case AF_INET6: family = AF_INET6; goto prefix; case AF_LLC: family = AF_LLC; goto prefix; default: err = -NLE_AF_NOSUPPORT; goto errout; } } copy = 1; if (hint == AF_INET || hint == AF_UNSPEC) { if (inet_pton(AF_INET, str, buf) > 0) { family = AF_INET; len = 4; goto prefix; } if (hint == AF_INET) { err = -NLE_NOADDR; goto errout; } } if (hint == AF_INET6 || hint == AF_UNSPEC) { if (inet_pton(AF_INET6, str, buf) > 0) { family = AF_INET6; len = 16; goto prefix; } if (hint == AF_INET6) { err = -NLE_NOADDR; goto errout; } } if ((hint == AF_LLC || hint == AF_UNSPEC) && strchr(str, ':')) { unsigned int a, b, c, d, e, f; if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { family = AF_LLC; len = 6; buf[0] = (unsigned char) a; buf[1] = (unsigned char) b; buf[2] = (unsigned char) c; buf[3] = (unsigned char) d; buf[4] = (unsigned char) e; buf[5] = (unsigned char) f; goto prefix; } if (hint == AF_LLC) { err = -NLE_NOADDR; goto errout; } } if ((hint == AF_DECnet || hint == AF_UNSPEC) && (strchr(str, '.') || strchr(str, ','))) { if (dnet_pton(str, buf) > 0) { family = AF_DECnet; len = 2; goto prefix; } if (hint == AF_DECnet) { err = -NLE_NOADDR; goto errout; } } if (hint == AF_UNSPEC && strchr(str, ':')) { size_t i = 0; char *s = str, *p; for (;;) { long l = strtol(s, &p, 16); if (s == p || l > 0xff || i >= sizeof(buf)) { err = -NLE_INVAL; goto errout; } buf[i++] = (unsigned char) l; if (*p == '\0') break; s = ++p; } len = i; family = AF_UNSPEC; goto prefix; } err = -NLE_NOADDR; goto errout; prefix: addr = nl_addr_alloc(len); if (!addr) { err = -NLE_NOMEM; goto errout; } nl_addr_set_family(addr, family); if (copy) nl_addr_set_binary_addr(addr, buf, len); if (prefix) { char *p; long pl = strtol(++prefix, &p, 0); if (p == prefix) { addr_destroy(addr); err = -NLE_INVAL; goto errout; } nl_addr_set_prefixlen(addr, pl); } else nl_addr_set_prefixlen(addr, len * 8); *result = addr; err = 0; errout: free(str); return err; } /** * Clone existing abstract address object * @arg addr Abstract address object * * Allocates new abstract address representing an identical clone of an * existing address. * * @see nl_addr_alloc() * @see nl_addr_put() * * @return Allocated abstract address or NULL upon failure. */ struct nl_addr *nl_addr_clone(const struct nl_addr *addr) { struct nl_addr *new; new = nl_addr_build(addr->a_family, addr->a_addr, addr->a_len); if (new) new->a_prefixlen = addr->a_prefixlen; return new; } /** @} */ /** * @name Managing Usage References * @{ */ /** * Increase the reference counter of an abstract address * @arg addr Abstract address * * Increases the reference counter of the address and thus prevents the * release of the memory resources until the reference is given back * using the function nl_addr_put(). * * @see nl_addr_put() * * @return Pointer to the existing abstract address */ struct nl_addr *nl_addr_get(struct nl_addr *addr) { addr->a_refcnt++; return addr; } /** * Decrease the reference counter of an abstract address * @arg addr Abstract addr * * @note The resources of the abstract address will be freed after the * last reference to the address has been returned. * * @see nl_addr_get() */ void nl_addr_put(struct nl_addr *addr) { if (!addr) return; if (addr->a_refcnt == 1) addr_destroy(addr); else addr->a_refcnt--; } /** * Check whether an abstract address is shared. * @arg addr Abstract address object. * * @return Non-zero if the abstract address is shared, otherwise 0. */ int nl_addr_shared(const struct nl_addr *addr) { return addr->a_refcnt > 1; } /** @} */ /** * @name Miscellaneous * @{ */ /** * Compare abstract addresses * @arg a An abstract address * @arg b Another abstract address * * Verifies whether the address family, address length, prefix length, and * binary addresses of two abstract addresses matches. * * @note This function will *not* respect the prefix length in the sense * that only the actual prefix will be compared. Please refer to the * nl_addr_cmp_prefix() function if you require this functionality. * * @see nl_addr_cmp_prefix() * * @return Integer less than, equal to or greather than zero if the two * addresses match. */ int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b) { int d = a->a_family - b->a_family; if (d == 0) { d = a->a_len - b->a_len; if (a->a_len && d == 0) { d = memcmp(a->a_addr, b->a_addr, a->a_len); if (d == 0) return (a->a_prefixlen - b->a_prefixlen); } } return d; } /** * Compare the prefix of two abstract addresses * @arg a An abstract address * @arg b Another abstract address * * Verifies whether the address family and the binary address covered by * the smaller prefix length of the two abstract addresses matches. * * @see nl_addr_cmp() * * @return Integer less than, equal to or greather than zero if the two * addresses match. */ int nl_addr_cmp_prefix(const struct nl_addr *a, const struct nl_addr *b) { int d = a->a_family - b->a_family; if (d == 0) { int len = min(a->a_prefixlen, b->a_prefixlen); int bytes = len / 8; d = memcmp(a->a_addr, b->a_addr, bytes); if (d == 0 && (len % 8) != 0) { int mask = (0xFF00 >> (len % 8)) & 0xFF; d = (a->a_addr[bytes] & mask) - (b->a_addr[bytes] & mask); } } return d; } /** * Returns true if the address consists of all zeros * @arg addr Abstract address * * @return 1 if the binary address consists of all zeros, 0 otherwise. */ int nl_addr_iszero(const struct nl_addr *addr) { unsigned int i; for (i = 0; i < addr->a_len; i++) if (addr->a_addr[i]) return 0; return 1; } /** * Check if address string is parseable for a specific address family * @arg addr Address represented as character string. * @arg family Desired address family. * * @return 1 if the address is parseable assuming the specified address family, * otherwise 0 is returned. */ int nl_addr_valid(const char *addr, int family) { int ret; char buf[32]; switch (family) { case AF_INET: case AF_INET6: ret = inet_pton(family, addr, buf); if (ret <= 0) return 0; break; case AF_DECnet: ret = dnet_pton(addr, buf); if (ret <= 0) return 0; break; case AF_LLC: if (sscanf(addr, "%*02x:%*02x:%*02x:%*02x:%*02x:%*02x") != 6) return 0; break; } return 1; } /** * Guess address family of abstract address based on address size * @arg addr Abstract address object. * * @return Numeric address family or AF_UNSPEC */ int nl_addr_guess_family(const struct nl_addr *addr) { switch (addr->a_len) { case 4: return AF_INET; case 6: return AF_LLC; case 16: return AF_INET6; default: return AF_UNSPEC; } } /** * Fill out sockaddr structure with values from abstract address object. * @arg addr Abstract address object. * @arg sa Destination sockaddr structure buffer. * @arg salen Length of sockaddr structure buffer. * * Fills out the specified sockaddr structure with the data found in the * specified abstract address. The salen argument needs to be set to the * size of sa but will be modified to the actual size used during before * the function exits. * * @return 0 on success or a negative error code */ int nl_addr_fill_sockaddr(const struct nl_addr *addr, struct sockaddr *sa, socklen_t *salen) { switch (addr->a_family) { case AF_INET: { struct sockaddr_in *sai = (struct sockaddr_in *) sa; if (*salen < sizeof(*sai)) return -NLE_INVAL; if (addr->a_len == 4) memcpy(&sai->sin_addr, addr->a_addr, 4); else if (addr->a_len != 0) return -NLE_INVAL; else memset(&sai->sin_addr, 0, 4); sai->sin_family = addr->a_family; *salen = sizeof(*sai); } break; case AF_INET6: { struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa; if (*salen < sizeof(*sa6)) return -NLE_INVAL; if (addr->a_len == 16) memcpy(&sa6->sin6_addr, addr->a_addr, 16); else if (addr->a_len != 0) return -NLE_INVAL; else memset(&sa6->sin6_addr, 0, 16); sa6->sin6_family = addr->a_family; *salen = sizeof(*sa6); } break; default: return -NLE_INVAL; } return 0; } /** @} */ /** * @name Getting Information About Addresses * @{ */ /** * Call getaddrinfo() for an abstract address object. * @arg addr Abstract address object. * @arg result Pointer to store resulting address list. * * Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST * mode. * * @note The caller is responsible for freeing the linked list using the * interface provided by getaddrinfo(3). * * @return 0 on success or a negative error code. */ int nl_addr_info(const struct nl_addr *addr, struct addrinfo **result) { int err; char buf[INET6_ADDRSTRLEN+5]; struct addrinfo hint = { .ai_flags = AI_NUMERICHOST, .ai_family = addr->a_family, }; nl_addr2str(addr, buf, sizeof(buf)); err = getaddrinfo(buf, NULL, &hint, result); if (err != 0) { switch (err) { case EAI_ADDRFAMILY: return -NLE_AF_NOSUPPORT; case EAI_AGAIN: return -NLE_AGAIN; case EAI_BADFLAGS: return -NLE_INVAL; case EAI_FAIL: return -NLE_NOADDR; case EAI_FAMILY: return -NLE_AF_NOSUPPORT; case EAI_MEMORY: return -NLE_NOMEM; case EAI_NODATA: return -NLE_NOADDR; case EAI_NONAME: return -NLE_OBJ_NOTFOUND; case EAI_SERVICE: return -NLE_OPNOTSUPP; case EAI_SOCKTYPE: return -NLE_BAD_SOCK; default: return -NLE_FAILURE; } } return 0; } /** * Resolve abstract address object to a name using getnameinfo(). * @arg addr Abstract address object. * @arg host Destination buffer for host name. * @arg hostlen Length of destination buffer. * * Resolves the abstract address to a name and writes the looked up result * into the host buffer. getnameinfo() is used to perform the lookup and * is put into NI_NAMEREQD mode so the function will fail if the lookup * couldn't be performed. * * @return 0 on success or a negative error code. */ int nl_addr_resolve(const struct nl_addr *addr, char *host, size_t hostlen) { int err; struct sockaddr_in6 buf; socklen_t salen = sizeof(buf); err = nl_addr_fill_sockaddr(addr, (struct sockaddr *) &buf, &salen); if (err < 0) return err; err = getnameinfo((struct sockaddr *) &buf, salen, host, hostlen, NULL, 0, NI_NAMEREQD); if (err < 0) return nl_syserr2nlerr(err); return 0; } /** @} */ /** * @name Attributes * @{ */ /** * Set address family * @arg addr Abstract address object * @arg family Address family * * @see nl_addr_get_family() */ void nl_addr_set_family(struct nl_addr *addr, int family) { addr->a_family = family; } /** * Return address family * @arg addr Abstract address object * * @see nl_addr_set_family() * * @return The numeric address family or `AF_UNSPEC` */ int nl_addr_get_family(const struct nl_addr *addr) { return addr->a_family; } /** * Set binary address of abstract address object. * @arg addr Abstract address object. * @arg buf Buffer containing binary address. * @arg len Length of buffer containing binary address. * * Modifies the binary address portion of the abstract address. The * abstract address must be capable of holding the required amount * or this function will fail. * * @note This function will *not* modify the prefix length. It is within * the responsibility of the caller to set the prefix length to the * desirable length. * * @see nl_addr_alloc() * @see nl_addr_get_binary_addr() * @see nl_addr_get_len() * * @return 0 on success or a negative error code. */ int nl_addr_set_binary_addr(struct nl_addr *addr, const void *buf, size_t len) { if (len > addr->a_maxsize) return -NLE_RANGE; addr->a_len = len; memset(addr->a_addr, 0, addr->a_maxsize); if (len) memcpy(addr->a_addr, buf, len); return 0; } /** * Get binary address of abstract address object. * @arg addr Abstract address object. * * @see nl_addr_set_binary_addr() * @see nl_addr_get_len() * * @return Pointer to binary address of length nl_addr_get_len() */ void *nl_addr_get_binary_addr(const struct nl_addr *addr) { return (void*)addr->a_addr; } /** * Get length of binary address of abstract address object. * @arg addr Abstract address object. * * @see nl_addr_get_binary_addr() * @see nl_addr_set_binary_addr() */ unsigned int nl_addr_get_len(const struct nl_addr *addr) { return addr->a_len; } /** * Set the prefix length of an abstract address * @arg addr Abstract address object * @arg prefixlen New prefix length * * @see nl_addr_get_prefixlen() */ void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen) { addr->a_prefixlen = prefixlen; } /** * Return prefix length of abstract address object. * @arg addr Abstract address object * * @see nl_addr_set_prefixlen() */ unsigned int nl_addr_get_prefixlen(const struct nl_addr *addr) { return addr->a_prefixlen; } /** @} */ /** * @name Translations to Strings * @{ */ /** * Convert abstract address object to character string. * @arg addr Abstract address object. * @arg buf Destination buffer. * @arg size Size of destination buffer. * * Converts an abstract address to a character string and stores * the result in the specified destination buffer. * * @return Address represented in ASCII stored in destination buffer. */ char *nl_addr2str(const struct nl_addr *addr, char *buf, size_t size) { unsigned int i; char tmp[16]; if (!addr || !addr->a_len) { snprintf(buf, size, "none"); if (addr) goto prefix; else return buf; } switch (addr->a_family) { case AF_INET: inet_ntop(AF_INET, addr->a_addr, buf, size); break; case AF_INET6: inet_ntop(AF_INET6, addr->a_addr, buf, size); break; case AF_DECnet: dnet_ntop(addr->a_addr, addr->a_len, buf, size); break; case AF_LLC: default: snprintf(buf, size, "%02x", (unsigned char) addr->a_addr[0]); for (i = 1; i < addr->a_len; i++) { snprintf(tmp, sizeof(tmp), ":%02x", (unsigned char) addr->a_addr[i]); strncat(buf, tmp, size - strlen(buf) - 1); } break; } prefix: if (addr->a_prefixlen != (8 * addr->a_len)) { snprintf(tmp, sizeof(tmp), "/%u", addr->a_prefixlen); strncat(buf, tmp, size - strlen(buf) - 1); } return buf; } /** @} */ /** * @name Address Family Transformations * @{ */ static const struct trans_tbl afs[] = { __ADD(AF_UNSPEC,unspec), __ADD(AF_UNIX,unix), __ADD(AF_INET,inet), __ADD(AF_AX25,ax25), __ADD(AF_IPX,ipx), __ADD(AF_APPLETALK,appletalk), __ADD(AF_NETROM,netrom), __ADD(AF_BRIDGE,bridge), __ADD(AF_ATMPVC,atmpvc), __ADD(AF_X25,x25), __ADD(AF_INET6,inet6), __ADD(AF_ROSE,rose), __ADD(AF_DECnet,decnet), __ADD(AF_NETBEUI,netbeui), __ADD(AF_SECURITY,security), __ADD(AF_KEY,key), __ADD(AF_NETLINK,netlink), __ADD(AF_PACKET,packet), __ADD(AF_ASH,ash), __ADD(AF_ECONET,econet), __ADD(AF_ATMSVC,atmsvc), #ifdef AF_RDS __ADD(AF_RDS,rds), #endif __ADD(AF_SNA,sna), __ADD(AF_IRDA,irda), __ADD(AF_PPPOX,pppox), __ADD(AF_WANPIPE,wanpipe), __ADD(AF_LLC,llc), #ifdef AF_CAN __ADD(AF_CAN,can), #endif #ifdef AF_TIPC __ADD(AF_TIPC,tipc), #endif __ADD(AF_BLUETOOTH,bluetooth), #ifdef AF_IUCV __ADD(AF_IUCV,iucv), #endif #ifdef AF_RXRPC __ADD(AF_RXRPC,rxrpc), #endif #ifdef AF_ISDN __ADD(AF_ISDN,isdn), #endif #ifdef AF_PHONET __ADD(AF_PHONET,phonet), #endif #ifdef AF_IEEE802154 __ADD(AF_IEEE802154,ieee802154), #endif #ifdef AF_CAIF __ADD(AF_CAIF,caif), #endif #ifdef AF_ALG __ADD(AF_ALG,alg), #endif #ifdef AF_NFC __ADD(AF_NFC,nfc), #endif }; char *nl_af2str(int family, char *buf, size_t size) { return __type2str(family, buf, size, afs, ARRAY_SIZE(afs)); } int nl_str2af(const char *name) { int fam = __str2type(name, afs, ARRAY_SIZE(afs)); return fam >= 0 ? fam : -EINVAL; } /** @} */ /** @} */ libnl-3.2.29/lib/attr.c0000644000175000017500000006012413023014600011504 00000000000000/* * lib/attr.c Netlink Attributes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #include #include #include #include #include #include #include /** * @ingroup msg * @defgroup attr Attributes * Netlink Attributes Construction/Parsing Interface * * Related sections in the development guide: * - @core_doc{core_attr,Netlink Attributes} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ /** * @name Attribute Size Calculation * @{ */ /** * Return size of attribute whithout padding. * @arg payload Payload length of attribute. * * @code * <-------- nla_attr_size(payload) ---------> * +------------------+- - -+- - - - - - - - - +- - -+ * | Attribute Header | Pad | Payload | Pad | * +------------------+- - -+- - - - - - - - - +- - -+ * @endcode * * @return Size of attribute in bytes without padding. */ int nla_attr_size(int payload) { return NLA_HDRLEN + payload; } /** * Return size of attribute including padding. * @arg payload Payload length of attribute. * * @code * <----------- nla_total_size(payload) -----------> * +------------------+- - -+- - - - - - - - - +- - -+ * | Attribute Header | Pad | Payload | Pad | * +------------------+- - -+- - - - - - - - - +- - -+ * @endcode * * @return Size of attribute in bytes. */ int nla_total_size(int payload) { return NLA_ALIGN(nla_attr_size(payload)); } /** * Return length of padding at the tail of the attribute. * @arg payload Payload length of attribute. * * @code * +------------------+- - -+- - - - - - - - - +- - -+ * | Attribute Header | Pad | Payload | Pad | * +------------------+- - -+- - - - - - - - - +- - -+ * <---> * @endcode * * @return Length of padding in bytes. */ int nla_padlen(int payload) { return nla_total_size(payload) - nla_attr_size(payload); } /** @} */ /** * @name Parsing Attributes * @{ */ /** * Return type of the attribute. * @arg nla Attribute. * * @return Type of attribute. */ int nla_type(const struct nlattr *nla) { return nla->nla_type & NLA_TYPE_MASK; } /** * Return pointer to the payload section. * @arg nla Attribute. * * @return Pointer to start of payload section. */ void *nla_data(const struct nlattr *nla) { return (char *) nla + NLA_HDRLEN; } /** * Return length of the payload . * @arg nla Attribute * * @return Length of payload in bytes. */ int nla_len(const struct nlattr *nla) { return nla->nla_len - NLA_HDRLEN; } /** * Check if the attribute header and payload can be accessed safely. * @arg nla Attribute of any kind. * @arg remaining Number of bytes remaining in attribute stream. * * Verifies that the header and payload do not exceed the number of * bytes left in the attribute stream. This function must be called * before access the attribute header or payload when iterating over * the attribute stream using nla_next(). * * @return True if the attribute can be accessed safely, false otherwise. */ int nla_ok(const struct nlattr *nla, int remaining) { return remaining >= sizeof(*nla) && nla->nla_len >= sizeof(*nla) && nla->nla_len <= remaining; } /** * Return next attribute in a stream of attributes. * @arg nla Attribute of any kind. * @arg remaining Variable to count remaining bytes in stream. * * Calculates the offset to the next attribute based on the attribute * given. The attribute provided is assumed to be accessible, the * caller is responsible to use nla_ok() beforehand. The offset (length * of specified attribute including padding) is then subtracted from * the remaining bytes variable and a pointer to the next attribute is * returned. * * nla_next() can be called as long as remainig is >0. * * @return Pointer to next attribute. */ struct nlattr *nla_next(const struct nlattr *nla, int *remaining) { int totlen = NLA_ALIGN(nla->nla_len); *remaining -= totlen; return (struct nlattr *) ((char *) nla + totlen); } static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = { [NLA_U8] = sizeof(uint8_t), [NLA_U16] = sizeof(uint16_t), [NLA_U32] = sizeof(uint32_t), [NLA_U64] = sizeof(uint64_t), [NLA_STRING] = 1, [NLA_FLAG] = 0, }; static int validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy) { const struct nla_policy *pt; unsigned int minlen = 0; int type = nla_type(nla); if (type < 0 || type > maxtype) return 0; pt = &policy[type]; if (pt->type > NLA_TYPE_MAX) BUG(); if (pt->minlen) minlen = pt->minlen; else if (pt->type != NLA_UNSPEC) minlen = nla_attr_minlen[pt->type]; if (nla_len(nla) < minlen) return -NLE_RANGE; if (pt->maxlen && nla_len(nla) > pt->maxlen) return -NLE_RANGE; if (pt->type == NLA_STRING) { const char *data = nla_data(nla); if (data[nla_len(nla) - 1] != '\0') return -NLE_INVAL; } return 0; } /** * Create attribute index based on a stream of attributes. * @arg tb Index array to be filled (maxtype+1 elements). * @arg maxtype Maximum attribute type expected and accepted. * @arg head Head of attribute stream. * @arg len Length of attribute stream. * @arg policy Attribute validation policy. * * Iterates over the stream of attributes and stores a pointer to each * attribute in the index array using the attribute type as index to * the array. Attribute with a type greater than the maximum type * specified will be silently ignored in order to maintain backwards * compatibility. If \a policy is not NULL, the attribute will be * validated using the specified policy. * * @see nla_validate * @return 0 on success or a negative error code. */ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, struct nla_policy *policy) { struct nlattr *nla; int rem, err; memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); nla_for_each_attr(nla, head, len, rem) { int type = nla_type(nla); if (type > maxtype) continue; if (policy) { err = validate_nla(nla, maxtype, policy); if (err < 0) goto errout; } if (tb[type]) NL_DBG(1, "Attribute of type %#x found multiple times in message, " "previous attribute is being ignored.\n", type); tb[type] = nla; } if (rem > 0) NL_DBG(1, "netlink: %d bytes leftover after parsing " "attributes.\n", rem); err = 0; errout: return err; } /** * Validate a stream of attributes. * @arg head Head of attributes stream. * @arg len Length of attributes stream. * @arg maxtype Maximum attribute type expected and accepted. * @arg policy Validation policy. * * Iterates over the stream of attributes and validates each attribute * one by one using the specified policy. Attributes with a type greater * than the maximum type specified will be silently ignored in order to * maintain backwards compatibility. * * See section @core_doc{core_attr_parse,Attribute Parsing} for more details. * * @return 0 on success or a negative error code. */ int nla_validate(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy) { const struct nlattr *nla; int rem, err; nla_for_each_attr(nla, head, len, rem) { err = validate_nla(nla, maxtype, policy); if (err < 0) goto errout; } err = 0; errout: return err; } /** * Find a single attribute in a stream of attributes. * @arg head Head of attributes stream. * @arg len Length of attributes stream. * @arg attrtype Attribute type to look for. * * Iterates over the stream of attributes and compares each type with * the type specified. Returns the first attribute which matches the * type. * * @return Pointer to attribute found or NULL. */ struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype) { const struct nlattr *nla; int rem; nla_for_each_attr(nla, head, len, rem) if (nla_type(nla) == attrtype) return (struct nlattr*)nla; return NULL; } /** @} */ /** * @name Helper Functions * @{ */ /** * Copy attribute payload to another memory area. * @arg dest Pointer to destination memory area. * @arg src Attribute * @arg count Number of bytes to copy at most. * * Note: The number of bytes copied is limited by the length of * the attribute payload. * * @return The number of bytes copied to dest. */ int nla_memcpy(void *dest, const struct nlattr *src, int count) { int minlen; if (!src) return 0; minlen = min_t(int, count, nla_len(src)); memcpy(dest, nla_data(src), minlen); return minlen; } /** * Copy string attribute payload to a buffer. * @arg dst Pointer to destination buffer. * @arg nla Attribute of type NLA_STRING. * @arg dstsize Size of destination buffer in bytes. * * Copies at most dstsize - 1 bytes to the destination buffer. * The result is always a valid NUL terminated string. Unlike * strlcpy the destination buffer is always padded out. * * @return The length of string attribute without the terminating NUL. */ size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize) { size_t srclen = nla_len(nla); const char *src = nla_data(nla); if (srclen > 0 && src[srclen - 1] == '\0') srclen--; if (dstsize > 0) { size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen; memset(dst, 0, dstsize); memcpy(dst, src, len); } return srclen; } /** * Compare attribute payload with memory area. * @arg nla Attribute. * @arg data Memory area to compare to. * @arg size Number of bytes to compare. * * @see memcmp(3) * @return An integer less than, equal to, or greater than zero. */ int nla_memcmp(const struct nlattr *nla, const void *data, size_t size) { int d = nla_len(nla) - size; if (d == 0) d = memcmp(nla_data(nla), data, size); return d; } /** * Compare string attribute payload with string * @arg nla Attribute of type NLA_STRING. * @arg str NUL terminated string. * * @see strcmp(3) * @return An integer less than, equal to, or greater than zero. */ int nla_strcmp(const struct nlattr *nla, const char *str) { int len = strlen(str) + 1; int d = nla_len(nla) - len; if (d == 0) d = memcmp(nla_data(nla), str, len); return d; } /** @} */ /** * @name Unspecific Attribute * @{ */ /** * Reserve space for a attribute. * @arg msg Netlink Message. * @arg attrtype Attribute Type. * @arg attrlen Length of payload. * * Reserves room for a attribute in the specified netlink message and * fills in the attribute header (type, length). Returns NULL if there * is unsuficient space for the attribute. * * Any padding between payload and the start of the next attribute is * zeroed out. * * @return Pointer to start of attribute or NULL on failure. */ struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen) { struct nlattr *nla; int tlen; tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen); if (tlen > msg->nm_size) return NULL; nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh); nla->nla_type = attrtype; nla->nla_len = nla_attr_size(attrlen); if (attrlen) memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen)); msg->nm_nlh->nlmsg_len = tlen; NL_DBG(2, "msg %p: attr <%p> %d: Reserved %d (%d) bytes at offset +%td " "nlmsg_len=%d\n", msg, nla, nla->nla_type, nla_total_size(attrlen), attrlen, (void *) nla - nlmsg_data(msg->nm_nlh), msg->nm_nlh->nlmsg_len); return nla; } /** * Add a unspecific attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg datalen Length of data to be used as payload. * @arg data Pointer to data to be used as attribute payload. * * Reserves room for a unspecific attribute and copies the provided data * into the message as payload of the attribute. Returns an error if there * is insufficient space for the attribute. * * @see nla_reserve * @return 0 on success or a negative error code. */ int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data) { struct nlattr *nla; nla = nla_reserve(msg, attrtype, datalen); if (!nla) return -NLE_NOMEM; if (datalen > 0) { memcpy(nla_data(nla), data, datalen); NL_DBG(2, "msg %p: attr <%p> %d: Wrote %d bytes at offset +%td\n", msg, nla, nla->nla_type, datalen, (void *) nla - nlmsg_data(msg->nm_nlh)); } return 0; } /** * Add abstract data as unspecific attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg data Abstract data object. * * Equivalent to nla_put() except that the length of the payload is * derived from the abstract data object. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_data(struct nl_msg *msg, int attrtype, const struct nl_data *data) { return nla_put(msg, attrtype, nl_data_get_size(data), nl_data_get(data)); } /** * Add abstract address as unspecific attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg addr Abstract address object. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr) { return nla_put(msg, attrtype, nl_addr_get_len(addr), nl_addr_get_binary_addr(addr)); } /** @} */ /** * @name Integer Attributes */ /** * Add 8 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_s8(struct nl_msg *msg, int attrtype, int8_t value) { return nla_put(msg, attrtype, sizeof(int8_t), &value); } /** * Return value of 8 bit signed integer attribute. * @arg nla 8 bit integer attribute * * @return Payload as 8 bit integer. */ int8_t nla_get_s8(const struct nlattr *nla) { return *(const int8_t *) nla_data(nla); } /** * Add 8 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value) { return nla_put(msg, attrtype, sizeof(uint8_t), &value); } /** * Return value of 8 bit integer attribute. * @arg nla 8 bit integer attribute * * @return Payload as 8 bit integer. */ uint8_t nla_get_u8(const struct nlattr *nla) { return *(const uint8_t *) nla_data(nla); } /** * Add 16 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_s16(struct nl_msg *msg, int attrtype, int16_t value) { return nla_put(msg, attrtype, sizeof(int16_t), &value); } /** * Return payload of 16 bit signed integer attribute. * @arg nla 16 bit integer attribute * * @return Payload as 16 bit integer. */ int16_t nla_get_s16(const struct nlattr *nla) { return *(const int16_t *) nla_data(nla); } /** * Add 16 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value) { return nla_put(msg, attrtype, sizeof(uint16_t), &value); } /** * Return payload of 16 bit integer attribute. * @arg nla 16 bit integer attribute * * @return Payload as 16 bit integer. */ uint16_t nla_get_u16(const struct nlattr *nla) { return *(const uint16_t *) nla_data(nla); } /** * Add 32 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_s32(struct nl_msg *msg, int attrtype, int32_t value) { return nla_put(msg, attrtype, sizeof(int32_t), &value); } /** * Return payload of 32 bit signed integer attribute. * @arg nla 32 bit integer attribute. * * @return Payload as 32 bit integer. */ int32_t nla_get_s32(const struct nlattr *nla) { return *(const int32_t *) nla_data(nla); } /** * Add 32 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value) { return nla_put(msg, attrtype, sizeof(uint32_t), &value); } /** * Return payload of 32 bit integer attribute. * @arg nla 32 bit integer attribute. * * @return Payload as 32 bit integer. */ uint32_t nla_get_u32(const struct nlattr *nla) { return *(const uint32_t *) nla_data(nla); } /** * Add 64 bit signed integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_s64(struct nl_msg *msg, int attrtype, int64_t value) { return nla_put(msg, attrtype, sizeof(int64_t), &value); } /** * Return payload of s64 attribute * @arg nla s64 netlink attribute * * @return Payload as 64 bit integer. */ int64_t nla_get_s64(const struct nlattr *nla) { int64_t tmp = 0; if (nla && nla_len(nla) >= sizeof(tmp)) memcpy(&tmp, nla_data(nla), sizeof(tmp)); return tmp; } /** * Add 64 bit integer attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg value Numeric value to store as payload. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value) { return nla_put(msg, attrtype, sizeof(uint64_t), &value); } /** * Return payload of u64 attribute * @arg nla u64 netlink attribute * * @return Payload as 64 bit integer. */ uint64_t nla_get_u64(const struct nlattr *nla) { uint64_t tmp = 0; if (nla && nla_len(nla) >= sizeof(tmp)) memcpy(&tmp, nla_data(nla), sizeof(tmp)); return tmp; } /** @} */ /** * @name String Attribute */ /** * Add string attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg str NUL terminated string. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_string(struct nl_msg *msg, int attrtype, const char *str) { return nla_put(msg, attrtype, strlen(str) + 1, str); } /** * Return payload of string attribute. * @arg nla String attribute. * * @return Pointer to attribute payload. */ char *nla_get_string(const struct nlattr *nla) { return (char *) nla_data(nla); } char *nla_strdup(const struct nlattr *nla) { return strdup(nla_get_string(nla)); } /** @} */ /** * @name Flag Attribute */ /** * Add flag netlink attribute to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_flag(struct nl_msg *msg, int attrtype) { return nla_put(msg, attrtype, 0, NULL); } /** * Return true if flag attribute is set. * @arg nla Flag netlink attribute. * * @return True if flag is set, otherwise false. */ int nla_get_flag(const struct nlattr *nla) { return !!nla; } /** @} */ /** * @name Microseconds Attribute */ /** * Add a msecs netlink attribute to a netlink message * @arg n netlink message * @arg attrtype attribute type * @arg msecs number of msecs */ int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs) { return nla_put_u64(n, attrtype, msecs); } /** * Return payload of msecs attribute * @arg nla msecs netlink attribute * * @return the number of milliseconds. */ unsigned long nla_get_msecs(const struct nlattr *nla) { return nla_get_u64(nla); } /** @} */ /** * @name Nested Attribute */ /** * Add nested attributes to netlink message. * @arg msg Netlink message. * @arg attrtype Attribute type. * @arg nested Message containing attributes to be nested. * * Takes the attributes found in the \a nested message and appends them * to the message \a msg nested in a container of the type \a attrtype. * The \a nested message may not have a family specific header. * * @see nla_put * @return 0 on success or a negative error code. */ int nla_put_nested(struct nl_msg *msg, int attrtype, const struct nl_msg *nested) { NL_DBG(2, "msg %p: attr <> %d: adding msg %p as nested attribute\n", msg, attrtype, nested); return nla_put(msg, attrtype, nlmsg_datalen(nested->nm_nlh), nlmsg_data(nested->nm_nlh)); } /** * Start a new level of nested attributes. * @arg msg Netlink message. * @arg attrtype Attribute type of container. * * @return Pointer to container attribute. */ struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype) { struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh); if (nla_put(msg, attrtype, 0, NULL) < 0) return NULL; NL_DBG(2, "msg %p: attr <%p> %d: starting nesting\n", msg, start, start->nla_type); return start; } /** * Finalize nesting of attributes. * @arg msg Netlink message. * @arg start Container attribute as returned from nla_nest_start(). * * Corrects the container attribute header to include the appeneded attributes. * * @return 0 on success or a negative error code. */ int nla_nest_end(struct nl_msg *msg, struct nlattr *start) { size_t pad, len; len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) start; if (len == NLA_HDRLEN || len > USHRT_MAX) { /* * Max nlattr size exceeded or empty nested attribute, trim the * attribute header again */ nla_nest_cancel(msg, start); /* Return error only if nlattr size was exceeded */ return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE; } start->nla_len = len; pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len; if (pad > 0) { /* * Data inside attribute does not end at a alignment boundry. * Pad accordingly and accoun for the additional space in * the message. nlmsg_reserve() may never fail in this situation, * the allocate message buffer must be a multiple of NLMSG_ALIGNTO. */ if (!nlmsg_reserve(msg, pad, 0)) BUG(); NL_DBG(2, "msg %p: attr <%p> %d: added %zu bytes of padding\n", msg, start, start->nla_type, pad); } NL_DBG(2, "msg %p: attr <%p> %d: closing nesting, len=%u\n", msg, start, start->nla_type, start->nla_len); return 0; } /** * Cancel the addition of a nested attribute * @arg msg Netlink message * @arg attr Nested netlink attribute * * Removes any partially added nested Netlink attribute from the message * by resetting the message to the size before the call to nla_nest_start() * and by overwriting any potentially touched message segments with 0. */ void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr) { ssize_t len; len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) attr; if (len < 0) BUG(); else if (len > 0) { msg->nm_nlh->nlmsg_len -= len; memset(nlmsg_tail(msg->nm_nlh), 0, len); } } /** * Create attribute index based on nested attribute * @arg tb Index array to be filled (maxtype+1 elements). * @arg maxtype Maximum attribute type expected and accepted. * @arg nla Nested Attribute. * @arg policy Attribute validation policy. * * Feeds the stream of attributes nested into the specified attribute * to nla_parse(). * * @see nla_parse * @return 0 on success or a negative error code. */ int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy) { return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); } /** * Return true if attribute has NLA_F_NESTED flag set * @arg attr Netlink attribute * * @return True if attribute has NLA_F_NESTED flag set, oterhwise False. */ int nla_is_nested(const struct nlattr *attr) { return !!(attr->nla_type & NLA_F_NESTED); } /** @} */ /** @} */ libnl-3.2.29/lib/idiag/0000755000175000017500000000000013031473756011544 500000000000000libnl-3.2.29/lib/idiag/idiag_meminfo_obj.c0000644000175000017500000000511013023014600015222 00000000000000/* * lib/idiag/idiagnl_meminfo_obj.c Inet Diag Meminfo Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #include #include /** * @ingroup idiag * @defgroup idiagnl_meminfo Inet Diag Memory Info * * @details * @idiagnl_doc{idiagnl_meminfo, Inet Diag Memory Info Documentation} * @{ */ struct idiagnl_meminfo *idiagnl_meminfo_alloc(void) { return (struct idiagnl_meminfo *) nl_object_alloc(&idiagnl_meminfo_obj_ops); } void idiagnl_meminfo_get(struct idiagnl_meminfo *minfo) { nl_object_get((struct nl_object *) minfo); } void idiagnl_meminfo_put(struct idiagnl_meminfo *minfo) { nl_object_put((struct nl_object *) minfo); } /** * @name Attributes * @{ */ uint32_t idiagnl_meminfo_get_rmem(const struct idiagnl_meminfo *minfo) { return minfo->idiag_rmem; } void idiagnl_meminfo_set_rmem(struct idiagnl_meminfo *minfo, uint32_t rmem) { minfo->idiag_rmem = rmem; } uint32_t idiagnl_meminfo_get_wmem(const struct idiagnl_meminfo *minfo) { return minfo->idiag_wmem; } void idiagnl_meminfo_set_wmem(struct idiagnl_meminfo *minfo, uint32_t wmem) { minfo->idiag_wmem = wmem; } uint32_t idiagnl_meminfo_get_fmem(const struct idiagnl_meminfo *minfo) { return minfo->idiag_fmem; } void idiagnl_meminfo_set_fmem(struct idiagnl_meminfo *minfo, uint32_t fmem) { minfo->idiag_fmem = fmem; } uint32_t idiagnl_meminfo_get_tmem(const struct idiagnl_meminfo *minfo) { return minfo->idiag_tmem; } void idiagnl_meminfo_set_tmem(struct idiagnl_meminfo *minfo, uint32_t tmem) { minfo->idiag_tmem = tmem; } /** @} */ /** @cond SKIP */ static uint64_t idiagnl_meminfo_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct idiagnl_meminfo *a = (struct idiagnl_meminfo *) _a; struct idiagnl_meminfo *b = (struct idiagnl_meminfo *) _b; /* meminfo is a very simple object. It has no attribe flags (ce_mask), * hence compare just returns 0 or 1, not a bit mask of attributes. */ return a->idiag_rmem != b->idiag_rmem || a->idiag_wmem != b->idiag_wmem || a->idiag_fmem != b->idiag_fmem || a->idiag_tmem != b->idiag_tmem; } struct nl_object_ops idiagnl_meminfo_obj_ops = { .oo_name = "idiag/idiag_meminfo", .oo_size = sizeof(struct idiagnl_meminfo), .oo_compare = idiagnl_meminfo_compare, }; /** @endcond */ /** @} */ libnl-3.2.29/lib/idiag/idiag_vegasinfo_obj.c0000644000175000017500000000531413023014600015557 00000000000000/* * lib/idiag/idiagnl_vegasinfo_obj.c Inet Diag TCP Vegas Info Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #include #include /** * @ingroup idiag * @defgroup idiagnl_vegasinfo Inet Diag TCP Vegas Info * * @details * @idiagnl_doc{idiagnl_vegasinfo, Inet Diag TCP Vegas Info Documentation} * @{ */ struct idiagnl_vegasinfo *idiagnl_vegasinfo_alloc(void) { return (struct idiagnl_vegasinfo *) nl_object_alloc(&idiagnl_vegasinfo_obj_ops); } void idiagnl_vegasinfo_get(struct idiagnl_vegasinfo *vinfo) { nl_object_get((struct nl_object *) vinfo); } void idiagnl_vegasinfo_put(struct idiagnl_vegasinfo *vinfo) { nl_object_put((struct nl_object *) vinfo); } /** * @name Attributes * @{ */ uint32_t idiagnl_vegasinfo_get_enabled(const struct idiagnl_vegasinfo *vinfo) { return vinfo->tcpv_enabled; } void idiagnl_vegasinfo_set_enabled(struct idiagnl_vegasinfo *vinfo, uint32_t enabled) { vinfo->tcpv_enabled = enabled; } uint32_t idiagnl_vegasinfo_get_rttcnt(const struct idiagnl_vegasinfo *vinfo) { return vinfo->tcpv_rttcnt; } void idiagnl_vegasinfo_set_rttcnt(struct idiagnl_vegasinfo *vinfo, uint32_t rttcnt) { vinfo->tcpv_rttcnt = rttcnt; } uint32_t idiagnl_vegasinfo_get_rtt(const struct idiagnl_vegasinfo *vinfo) { return vinfo->tcpv_rtt; } void idiagnl_vegasinfo_set_rtt(struct idiagnl_vegasinfo *vinfo, uint32_t rtt) { vinfo->tcpv_rtt = rtt; } uint32_t idiagnl_vegasinfo_get_minrtt(const struct idiagnl_vegasinfo *vinfo) { return vinfo->tcpv_minrtt; } void idiagnl_vegasinfo_set_minrtt(struct idiagnl_vegasinfo *vinfo, uint32_t minrtt) { vinfo->tcpv_minrtt = minrtt; } /** @} */ /** @cond SKIP */ static uint64_t idiagnl_vegasinfo_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct idiagnl_vegasinfo *a = (struct idiagnl_vegasinfo *) _a; struct idiagnl_vegasinfo *b = (struct idiagnl_vegasinfo *) _b; /* vegasinfo is a very simple object. It has no attribe flags (ce_mask), * hence compare just returns 0 or 1, not a bit mask of attributes. */ return a->tcpv_enabled != b->tcpv_enabled || a->tcpv_rttcnt != b->tcpv_rttcnt || a->tcpv_rtt != b->tcpv_rtt || a->tcpv_minrtt != b->tcpv_minrtt; } struct nl_object_ops idiagnl_vegasinfo_obj_ops = { .oo_name = "idiag/idiag_vegasinfo", .oo_size = sizeof(struct idiagnl_vegasinfo), .oo_compare = idiagnl_vegasinfo_compare, }; /** @endcond */ /** @} */ libnl-3.2.29/lib/idiag/idiag_req_obj.c0000644000175000017500000001320613023014600014364 00000000000000/* * lib/idiag/idiagnl_req_obj.c Inet Diag Request Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #include #include #include /** * @ingroup idiag * @defgroup idiagnl_req Inet Diag Requests * * @details * @idiagnl_doc{idiagnl_req, Inet Diag Request Documentation} * @{ */ struct idiagnl_req *idiagnl_req_alloc(void) { return (struct idiagnl_req *) nl_object_alloc(&idiagnl_req_obj_ops); } void idiagnl_req_get(struct idiagnl_req *req) { nl_object_get((struct nl_object *) req); } void idiagnl_req_put(struct idiagnl_req *req) { nl_object_put((struct nl_object *) req); } /** * @name Attributes * @{ */ uint8_t idiagnl_req_get_family(const struct idiagnl_req *req) { return req->idiag_family; } void idiagnl_req_set_family(struct idiagnl_req *req, uint8_t family) { req->idiag_family = family; } uint8_t idiagnl_req_get_ext(const struct idiagnl_req *req) { return req->idiag_ext; } void idiagnl_req_set_ext(struct idiagnl_req *req, uint8_t ext) { req->idiag_ext = ext; } uint32_t idiagnl_req_get_ifindex(const struct idiagnl_req *req) { return req->idiag_ifindex; } void idiagnl_req_set_ifindex(struct idiagnl_req *req, uint32_t ifindex) { req->idiag_ifindex = ifindex; } uint32_t idiagnl_req_get_states(const struct idiagnl_req *req) { return req->idiag_states; } void idiagnl_req_set_states(struct idiagnl_req *req, uint32_t states) { req->idiag_states = states; } uint32_t idiagnl_req_get_dbs(const struct idiagnl_req *req) { return req->idiag_dbs; } void idiagnl_req_set_dbs(struct idiagnl_req *req, uint32_t dbs) { req->idiag_dbs = dbs; } struct nl_addr *idiagnl_req_get_src(const struct idiagnl_req *req) { return req->idiag_src; } int idiagnl_req_set_src(struct idiagnl_req *req, struct nl_addr *addr) { if (req->idiag_src) nl_addr_put(req->idiag_src); nl_addr_get(addr); req->idiag_src = addr; return 0; } struct nl_addr *idiagnl_req_get_dst(const struct idiagnl_req *req) { return req->idiag_dst; } int idiagnl_req_set_dst(struct idiagnl_req *req, struct nl_addr *addr) { if (req->idiag_dst) nl_addr_put(req->idiag_dst); nl_addr_get(addr); req->idiag_dst = addr; return 0; } /** @} */ static void idiag_req_dump_line(struct nl_object *a, struct nl_dump_params *p) { struct idiagnl_req *req = (struct idiagnl_req *) a; char buf[64] = { 0 }; nl_dump_line(p, "%s ", nl_af2str(req->idiag_family, buf, sizeof(buf))); nl_dump(p, "src %s ", nl_addr2str(req->idiag_src, buf, sizeof(buf))); nl_dump(p, "dst %s ", nl_addr2str(req->idiag_dst, buf, sizeof(buf))); nl_dump(p, "iif %d ", req->idiag_ifindex); nl_dump(p, "\n"); } static void idiag_req_dump_details(struct nl_object *a, struct nl_dump_params *p) { struct idiagnl_req *req = (struct idiagnl_req *) a; char buf[64]; nl_dump_line(p, " "); nl_dump(p, "%s ", nl_af2str(req->idiag_family, buf, sizeof(buf))); nl_dump(p, "exts %s ", idiagnl_exts2str(req->idiag_ext, buf, sizeof(buf))); nl_dump(p, "src %s ", nl_addr2str(req->idiag_src, buf, sizeof(buf))); nl_dump(p, "dst %s ", nl_addr2str(req->idiag_dst, buf, sizeof(buf))); nl_dump(p, "iif %d ", req->idiag_ifindex); nl_dump(p, "states %s ", idiagnl_state2str(req->idiag_states, buf, sizeof(buf))); nl_dump(p, "dbs %d", req->idiag_dbs); nl_dump(p, "\n"); } static void idiag_req_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { idiag_req_dump_details(obj, p); } static void idiagnl_req_free(struct nl_object *a) { struct idiagnl_req *req = (struct idiagnl_req *) a; if (a == NULL) return; nl_addr_put(req->idiag_src); nl_addr_put(req->idiag_dst); } static int idiagnl_req_clone(struct nl_object *_dst, struct nl_object *_src) { struct idiagnl_req *dst = (struct idiagnl_req *) _dst; struct idiagnl_req *src = (struct idiagnl_req *) _src; if (src->idiag_src) if (!(dst->idiag_src = nl_addr_clone(src->idiag_src))) return -NLE_NOMEM; if (src->idiag_dst) if (!(dst->idiag_dst = nl_addr_clone(src->idiag_dst))) return -NLE_NOMEM; return 0; } int idiagnl_req_parse(struct nlmsghdr *nlh, struct idiagnl_req **result) { struct idiagnl_req *req = NULL; struct inet_diag_req *raw_req = NULL; struct nl_addr *src = NULL, *dst = NULL; int err = 0; req = idiagnl_req_alloc(); if (!req) goto errout_nomem; raw_req = nlmsg_data(nlh); req->idiag_family = raw_req->idiag_family; req->idiag_ext = raw_req->idiag_ext; req->idiag_states = raw_req->idiag_states; req->idiag_dbs = raw_req->idiag_dbs; req->idiag_ifindex = raw_req->id.idiag_if; dst = nl_addr_build(raw_req->idiag_family, raw_req->id.idiag_dst, sizeof(raw_req->id.idiag_dst)); if (!dst) goto errout_nomem; err = idiagnl_req_set_dst(req, dst); if (err < 0) goto errout; nl_addr_put(dst); src = nl_addr_build(raw_req->idiag_family, raw_req->id.idiag_src, sizeof(raw_req->id.idiag_src)); if (!src) goto errout_nomem; err = idiagnl_req_set_src(req, src); if (err < 0) goto errout; nl_addr_put(src); *result = req; return 0; errout: idiagnl_req_put(req); return err; errout_nomem: err = -NLE_NOMEM; goto errout; } /** @cond SKIP */ struct nl_object_ops idiagnl_req_obj_ops = { .oo_name = "idiag/idiag_req", .oo_size = sizeof(struct idiagnl_req), .oo_free_data = idiagnl_req_free, .oo_clone = idiagnl_req_clone, .oo_dump = { [NL_DUMP_LINE] = idiag_req_dump_line, [NL_DUMP_DETAILS] = idiag_req_dump_details, [NL_DUMP_STATS] = idiag_req_dump_stats, }, }; /** @endcond */ /** @} */ libnl-3.2.29/lib/idiag/idiag_msg_obj.c0000644000175000017500000006574113023014600014376 00000000000000/* * lib/idiag/idiagnl_msg_obj.c Inet Diag Message Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ #include #include #include #include #include #include /** @cond SKIP */ #define IDIAGNL_ATTR_FAMILY (0x1 << 1) #define IDIAGNL_ATTR_STATE (0x1 << 2) #define IDIAGNL_ATTR_TIMER (0x1 << 3) #define IDIAGNL_ATTR_RETRANS (0x1 << 4) #define IDIAGNL_ATTR_SPORT (0x1 << 5) #define IDIAGNL_ATTR_DPORT (0x1 << 6) #define IDIAGNL_ATTR_SRC (0x1 << 7) #define IDIAGNL_ATTR_DST (0x1 << 8) #define IDIAGNL_ATTR_IFINDEX (0x1 << 9) #define IDIAGNL_ATTR_EXPIRES (0x1 << 10) #define IDIAGNL_ATTR_RQUEUE (0x1 << 11) #define IDIAGNL_ATTR_WQUEUE (0x1 << 12) #define IDIAGNL_ATTR_UID (0x1 << 13) #define IDIAGNL_ATTR_INODE (0x1 << 14) #define IDIAGNL_ATTR_TOS (0x1 << 15) #define IDIAGNL_ATTR_TCLASS (0x1 << 16) #define IDIAGNL_ATTR_SHUTDOWN (0x1 << 17) #define IDIAGNL_ATTR_CONG (0x1 << 18) #define IDIAGNL_ATTR_MEMINFO (0x1 << 19) #define IDIAGNL_ATTR_VEGASINFO (0x1 << 20) #define IDIAGNL_ATTR_TCPINFO (0x1 << 21) #define IDIAGNL_ATTR_SKMEMINFO (0x1 << 22) #define _INET_DIAG_ALL ((1<<(INET_DIAG_MAX+1))-1) /** @endcond */ /** * @ingroup idiag * @defgroup idiagnl_msg Inet Diag Messages * * @details * @idiagnl_doc{idiagnl_msg, Inet Diag Message Documentation} * @{ */ struct idiagnl_msg *idiagnl_msg_alloc(void) { return (struct idiagnl_msg *) nl_object_alloc(&idiagnl_msg_obj_ops); } void idiagnl_msg_get(struct idiagnl_msg *msg) { nl_object_get((struct nl_object *) msg); } void idiagnl_msg_put(struct idiagnl_msg *msg) { nl_object_put((struct nl_object *) msg); } static struct nl_cache_ops idiagnl_msg_ops; static int idiagnl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct idiagnl_msg *msg = NULL; int err = 0; if ((err = idiagnl_msg_parse(nlh, &msg)) < 0) return err; err = pp->pp_cb((struct nl_object *) msg, pp); idiagnl_msg_put(msg); return err; } static int idiagnl_request_update(struct nl_cache *cache, struct nl_sock *sk) { int family = cache->c_iarg1; int states = cache->c_iarg2; return idiagnl_send_simple(sk, 0, family, states, _INET_DIAG_ALL); } static struct nl_cache_ops idiagnl_msg_ops = { .co_name = "idiag/idiag", .co_hdrsize = sizeof(struct inet_diag_msg), .co_msgtypes = { { TCPDIAG_GETSOCK, NL_ACT_NEW, "new" }, { DCCPDIAG_GETSOCK, NL_ACT_NEW, "new" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_INET_DIAG, .co_request_update = idiagnl_request_update, .co_msg_parser = idiagnl_msg_parser, .co_obj_ops = &idiagnl_msg_obj_ops, }; static void __init idiagnl_init(void) { nl_cache_mngt_register(&idiagnl_msg_ops); } static void __exit idiagnl_exit(void) { nl_cache_mngt_unregister(&idiagnl_msg_ops); } /** * @name Cache Management * @{ */ /** * Build an inetdiag cache to hold socket state information. * @arg sk Netlink socket * @arg family The address family to query * @arg states Socket states to query * @arg result Result pointer * * @note The caller is responsible for destroying and free the cache after using * it. * @return 0 on success of a negative error code. */ int idiagnl_msg_alloc_cache(struct nl_sock *sk, int family, int states, struct nl_cache **result) { struct nl_cache *cache = NULL; int err; if (!(cache = nl_cache_alloc(&idiagnl_msg_ops))) return -NLE_NOMEM; cache->c_iarg1 = family; cache->c_iarg2 = states; if (sk && (err = nl_cache_refill(sk, cache)) < 0) { free(cache); return err; } *result = cache; return 0; } /** @} */ /** * @name Attributes * @{ */ uint8_t idiagnl_msg_get_family(const struct idiagnl_msg *msg) { return msg->idiag_family; } void idiagnl_msg_set_family(struct idiagnl_msg *msg, uint8_t family) { msg->idiag_family = family; msg->ce_mask |= IDIAGNL_ATTR_FAMILY; } uint8_t idiagnl_msg_get_state(const struct idiagnl_msg *msg) { return msg->idiag_state; } void idiagnl_msg_set_state(struct idiagnl_msg *msg, uint8_t state) { msg->idiag_state = state; msg->ce_mask |= IDIAGNL_ATTR_STATE; } uint8_t idiagnl_msg_get_timer(const struct idiagnl_msg *msg) { return msg->idiag_timer; } void idiagnl_msg_set_timer(struct idiagnl_msg *msg, uint8_t timer) { msg->idiag_timer = timer; msg->ce_mask |= IDIAGNL_ATTR_TIMER; } uint8_t idiagnl_msg_get_retrans(const struct idiagnl_msg *msg) { return msg->idiag_retrans; } void idiagnl_msg_set_retrans(struct idiagnl_msg *msg, uint8_t retrans) { msg->idiag_retrans = retrans; msg->ce_mask |= IDIAGNL_ATTR_RETRANS; } uint16_t idiagnl_msg_get_sport(struct idiagnl_msg *msg) { return msg->idiag_sport; } void idiagnl_msg_set_sport(struct idiagnl_msg *msg, uint16_t port) { msg->idiag_sport = port; msg->ce_mask |= IDIAGNL_ATTR_SPORT; } uint16_t idiagnl_msg_get_dport(struct idiagnl_msg *msg) { return msg->idiag_dport; } void idiagnl_msg_set_dport(struct idiagnl_msg *msg, uint16_t port) { msg->idiag_dport = port; msg->ce_mask |= IDIAGNL_ATTR_DPORT; } struct nl_addr *idiagnl_msg_get_src(const struct idiagnl_msg *msg) { return msg->idiag_src; } int idiagnl_msg_set_src(struct idiagnl_msg *msg, struct nl_addr *addr) { if (msg->idiag_src) nl_addr_put(msg->idiag_src); nl_addr_get(addr); msg->idiag_src = addr; msg->ce_mask |= IDIAGNL_ATTR_SRC; return 0; } struct nl_addr *idiagnl_msg_get_dst(const struct idiagnl_msg *msg) { return msg->idiag_dst; } int idiagnl_msg_set_dst(struct idiagnl_msg *msg, struct nl_addr *addr) { if (msg->idiag_dst) nl_addr_put(msg->idiag_dst); nl_addr_get(addr); msg->idiag_dst = addr; msg->ce_mask |= IDIAGNL_ATTR_DST; return 0; } uint32_t idiagnl_msg_get_ifindex(const struct idiagnl_msg *msg) { return msg->idiag_ifindex; } void idiagnl_msg_set_ifindex(struct idiagnl_msg *msg, uint32_t ifindex) { msg->idiag_ifindex = ifindex; msg->ce_mask |= IDIAGNL_ATTR_IFINDEX; } uint32_t idiagnl_msg_get_expires(const struct idiagnl_msg *msg) { return msg->idiag_expires; } void idiagnl_msg_set_expires(struct idiagnl_msg *msg, uint32_t expires) { msg->idiag_expires = expires; msg->ce_mask |= IDIAGNL_ATTR_EXPIRES; } uint32_t idiagnl_msg_get_rqueue(const struct idiagnl_msg *msg) { return msg->idiag_rqueue; } void idiagnl_msg_set_rqueue(struct idiagnl_msg *msg, uint32_t rqueue) { msg->idiag_rqueue = rqueue; msg->ce_mask |= IDIAGNL_ATTR_RQUEUE; } uint32_t idiagnl_msg_get_wqueue(const struct idiagnl_msg *msg) { return msg->idiag_wqueue; } void idiagnl_msg_set_wqueue(struct idiagnl_msg *msg, uint32_t wqueue) { msg->idiag_wqueue = wqueue; msg->ce_mask |= IDIAGNL_ATTR_WQUEUE; } uint32_t idiagnl_msg_get_uid(const struct idiagnl_msg *msg) { return msg->idiag_uid; } void idiagnl_msg_set_uid(struct idiagnl_msg *msg, uint32_t uid) { msg->idiag_uid = uid; msg->ce_mask |= IDIAGNL_ATTR_UID; } uint32_t idiagnl_msg_get_inode(const struct idiagnl_msg *msg) { return msg->idiag_inode; } void idiagnl_msg_set_inode(struct idiagnl_msg *msg, uint32_t inode) { msg->idiag_inode = inode; msg->ce_mask |= IDIAGNL_ATTR_INODE; } uint8_t idiagnl_msg_get_tos(const struct idiagnl_msg *msg) { return msg->idiag_tos; } void idiagnl_msg_set_tos(struct idiagnl_msg *msg, uint8_t tos) { msg->idiag_tos = tos; msg->ce_mask |= IDIAGNL_ATTR_TOS; } uint8_t idiagnl_msg_get_tclass(const struct idiagnl_msg *msg) { return msg->idiag_tclass; } void idiagnl_msg_set_tclass(struct idiagnl_msg *msg, uint8_t tclass) { msg->idiag_tclass = tclass; msg->ce_mask |= IDIAGNL_ATTR_TCLASS; } uint8_t idiagnl_msg_get_shutdown(const struct idiagnl_msg *msg) { return msg->idiag_shutdown; } void idiagnl_msg_set_shutdown(struct idiagnl_msg *msg, uint8_t shutdown) { msg->idiag_shutdown = shutdown; msg->ce_mask |= IDIAGNL_ATTR_SHUTDOWN; } char *idiagnl_msg_get_cong(const struct idiagnl_msg *msg) { return msg->idiag_cong; } void idiagnl_msg_set_cong(struct idiagnl_msg *msg, char *cong) { free (msg->idiag_cong); msg->idiag_cong = strdup(cong); msg->ce_mask |= IDIAGNL_ATTR_CONG; } struct idiagnl_meminfo *idiagnl_msg_get_meminfo(const struct idiagnl_msg *msg) { return msg->idiag_meminfo; } void idiagnl_msg_set_meminfo(struct idiagnl_msg *msg, struct idiagnl_meminfo *minfo) { if (msg->idiag_meminfo) idiagnl_meminfo_put(msg->idiag_meminfo); idiagnl_meminfo_get(minfo); msg->idiag_meminfo = minfo; msg->ce_mask |= IDIAGNL_ATTR_MEMINFO; } struct idiagnl_vegasinfo *idiagnl_msg_get_vegasinfo(const struct idiagnl_msg *msg) { return msg->idiag_vegasinfo; } void idiagnl_msg_set_vegasinfo(struct idiagnl_msg *msg, struct idiagnl_vegasinfo *vinfo) { if (msg->idiag_vegasinfo) idiagnl_vegasinfo_put(msg->idiag_vegasinfo); idiagnl_vegasinfo_get(vinfo); msg->idiag_vegasinfo = vinfo; msg->ce_mask |= IDIAGNL_ATTR_VEGASINFO; } struct tcp_info idiagnl_msg_get_tcpinfo(const struct idiagnl_msg *msg) { return msg->idiag_tcpinfo; } void idiagnl_msg_set_tcpinfo(struct idiagnl_msg *msg, struct tcp_info *tinfo) { memcpy(&msg->idiag_tcpinfo, tinfo, sizeof(struct tcp_info)); msg->ce_mask |= IDIAGNL_ATTR_TCPINFO; } /** @} */ static void idiag_msg_dump_line(struct nl_object *a, struct nl_dump_params *p) { struct idiagnl_msg *msg = (struct idiagnl_msg *) a; char buf[64] = { 0 }; nl_dump_line(p, "family: %s ", nl_af2str(msg->idiag_family, buf, sizeof(buf))); nl_dump(p, "src: %s:%d ", nl_addr2str(msg->idiag_src, buf, sizeof(buf)), ntohs(msg->idiag_sport)); nl_dump(p, "dst: %s:%d ", nl_addr2str(msg->idiag_dst, buf, sizeof(buf)), ntohs(msg->idiag_dport)); nl_dump(p, "iif: %d ", msg->idiag_ifindex); nl_dump(p, "\n"); } static void idiag_msg_dump_details(struct nl_object *a, struct nl_dump_params *p) { struct idiagnl_msg *msg = (struct idiagnl_msg *) a; char buf[64], buf2[64]; nl_dump(p, "\nfamily: %s\n", nl_af2str(msg->idiag_family, buf, sizeof(buf))); nl_dump(p, "state: %s\n", idiagnl_state2str(msg->idiag_state, buf, sizeof(buf))); nl_dump(p, "timer (%s, %s, retransmits: %d)\n", idiagnl_timer2str(msg->idiag_timer, buf, sizeof(buf)), nl_msec2str(msg->idiag_expires, buf2, sizeof(buf2)), msg->idiag_retrans); nl_dump(p, "source: %s:%d\n", nl_addr2str(msg->idiag_src, buf, sizeof(buf)), ntohs(msg->idiag_sport)); nl_dump(p, "destination: %s:%d\n", nl_addr2str(msg->idiag_dst, buf, sizeof(buf)), ntohs(msg->idiag_dport)); nl_dump(p, "ifindex: %d\n", msg->idiag_ifindex); nl_dump(p, "rqueue: %-6d wqueue: %-6d\n", msg->idiag_rqueue, msg->idiag_wqueue); nl_dump(p, "uid %d\n", msg->idiag_uid); nl_dump(p, "inode %d\n", msg->idiag_inode); if (msg->idiag_shutdown) { nl_dump(p, "socket shutdown: %s\n", idiagnl_shutdown2str(msg->idiag_shutdown, buf, sizeof(buf))); } nl_dump(p, "tos: 0x%x\n", msg->idiag_tos); nl_dump(p, "traffic class: %d\n", msg->idiag_tclass); nl_dump(p, "congestion algorithm: %s\n", msg->idiag_cong ? : ""); } static void idiag_msg_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { struct idiagnl_msg *msg = (struct idiagnl_msg *) obj; char buf[64]; idiag_msg_dump_details(obj, p); nl_dump(p, "tcp info: [\n"); nl_dump(p, "\tsocket state: %s\n", idiagnl_state2str(msg->idiag_tcpinfo.tcpi_state, buf, sizeof(buf))); nl_dump(p, "\ttcp state: %s\n", idiagnl_tcpstate2str(msg->idiag_tcpinfo.tcpi_ca_state, buf, sizeof(buf))); nl_dump(p, "\tretransmits: %d\n", msg->idiag_tcpinfo.tcpi_retransmits); nl_dump(p, "\tprobes: %d\n", msg->idiag_tcpinfo.tcpi_probes); nl_dump(p, "\tbackoff: %d\n", msg->idiag_tcpinfo.tcpi_backoff); nl_dump(p, "\toptions: %s\n", idiagnl_tcpopts2str(msg->idiag_tcpinfo.tcpi_options, buf, sizeof(buf))); nl_dump(p, "\tsnd_wscale: %d\n", msg->idiag_tcpinfo.tcpi_snd_wscale); nl_dump(p, "\trcv_wscale: %d\n", msg->idiag_tcpinfo.tcpi_rcv_wscale); nl_dump(p, "\trto: %d\n", msg->idiag_tcpinfo.tcpi_rto); nl_dump(p, "\tato: %d\n", msg->idiag_tcpinfo.tcpi_ato); nl_dump(p, "\tsnd_mss: %s\n", nl_size2str(msg->idiag_tcpinfo.tcpi_snd_mss, buf, sizeof(buf))); nl_dump(p, "\trcv_mss: %s\n", nl_size2str(msg->idiag_tcpinfo.tcpi_rcv_mss, buf, sizeof(buf))); nl_dump(p, "\tunacked: %d\n", msg->idiag_tcpinfo.tcpi_unacked); nl_dump(p, "\tsacked: %d\n", msg->idiag_tcpinfo.tcpi_sacked); nl_dump(p, "\tlost: %d\n", msg->idiag_tcpinfo.tcpi_lost); nl_dump(p, "\tretransmit segments: %d\n", msg->idiag_tcpinfo.tcpi_retrans); nl_dump(p, "\tfackets: %d\n", msg->idiag_tcpinfo.tcpi_fackets); nl_dump(p, "\tlast data sent: %s\n", nl_msec2str(msg->idiag_tcpinfo.tcpi_last_data_sent, buf, sizeof(buf))); nl_dump(p, "\tlast ack sent: %s\n", nl_msec2str(msg->idiag_tcpinfo.tcpi_last_ack_sent, buf, sizeof(buf))); nl_dump(p, "\tlast data recv: %s\n", nl_msec2str(msg->idiag_tcpinfo.tcpi_last_data_recv, buf, sizeof(buf))); nl_dump(p, "\tlast ack recv: %s\n", nl_msec2str(msg->idiag_tcpinfo.tcpi_last_ack_recv, buf, sizeof(buf))); nl_dump(p, "\tpath mtu: %s\n", nl_size2str(msg->idiag_tcpinfo.tcpi_pmtu, buf, sizeof(buf))); nl_dump(p, "\trcv ss threshold: %d\n", msg->idiag_tcpinfo.tcpi_rcv_ssthresh); nl_dump(p, "\tsmoothed round trip time: %d\n", msg->idiag_tcpinfo.tcpi_rtt); nl_dump(p, "\tround trip time variation: %d\n", msg->idiag_tcpinfo.tcpi_rttvar); nl_dump(p, "\tsnd ss threshold: %s\n", nl_size2str(msg->idiag_tcpinfo.tcpi_snd_ssthresh, buf, sizeof(buf))); nl_dump(p, "\tsend congestion window: %d\n", msg->idiag_tcpinfo.tcpi_snd_cwnd); nl_dump(p, "\tadvertised mss: %s\n", nl_size2str(msg->idiag_tcpinfo.tcpi_advmss, buf, sizeof(buf))); nl_dump(p, "\treordering: %d\n", msg->idiag_tcpinfo.tcpi_reordering); nl_dump(p, "\trcv rround trip time: %d\n", msg->idiag_tcpinfo.tcpi_rcv_rtt); nl_dump(p, "\treceive queue space: %s\n", nl_size2str(msg->idiag_tcpinfo.tcpi_rcv_space, buf, sizeof(buf))); nl_dump(p, "\ttotal retransmits: %d\n", msg->idiag_tcpinfo.tcpi_total_retrans); nl_dump(p, "]\n"); if (msg->idiag_meminfo) { nl_dump(p, "meminfo: [\n"); nl_dump(p, "\trmem: %s\n", nl_size2str(msg->idiag_meminfo->idiag_rmem, buf, sizeof(buf))); nl_dump(p, "\twmem: %s\n", nl_size2str(msg->idiag_meminfo->idiag_wmem, buf, sizeof(buf))); nl_dump(p, "\tfmem: %s\n", nl_size2str(msg->idiag_meminfo->idiag_fmem, buf, sizeof(buf))); nl_dump(p, "\ttmem: %s\n", nl_size2str(msg->idiag_meminfo->idiag_tmem, buf, sizeof(buf))); nl_dump(p, "]\n"); } if (msg->idiag_vegasinfo) { nl_dump(p, "vegasinfo: [\n"); nl_dump(p, "\tvegas enabled: %d\n", msg->idiag_vegasinfo->tcpv_enabled); if (msg->idiag_vegasinfo->tcpv_enabled) { nl_dump(p, "\trtt cnt: %d", msg->idiag_vegasinfo->tcpv_rttcnt); nl_dump(p, "\trtt (propagation delay): %d", msg->idiag_vegasinfo->tcpv_rtt); nl_dump(p, "\tmin rtt: %d", msg->idiag_vegasinfo->tcpv_minrtt); } nl_dump(p, "]\n"); } if (msg->ce_mask & IDIAGNL_ATTR_MEMINFO) { nl_dump(p, "skmeminfo: [\n"); nl_dump(p, "\trmem alloc: %d\n", msg->idiag_skmeminfo[SK_MEMINFO_RMEM_ALLOC]); nl_dump(p, "\trcv buf: %s\n", nl_size2str(msg->idiag_skmeminfo[SK_MEMINFO_RCVBUF], buf, sizeof(buf))); nl_dump(p, "\twmem alloc: %d\n", msg->idiag_skmeminfo[SK_MEMINFO_WMEM_ALLOC]); nl_dump(p, "\tsnd buf: %s\n", nl_size2str(msg->idiag_skmeminfo[SK_MEMINFO_SNDBUF], buf, sizeof(buf))); nl_dump(p, "\tfwd alloc: %d\n", msg->idiag_skmeminfo[SK_MEMINFO_FWD_ALLOC]); nl_dump(p, "\twmem queued: %s\n", nl_size2str(msg->idiag_skmeminfo[SK_MEMINFO_WMEM_QUEUED], buf, sizeof(buf))); nl_dump(p, "\topt mem: %d\n", msg->idiag_skmeminfo[SK_MEMINFO_OPTMEM]); nl_dump(p, "\tbacklog: %d\n", msg->idiag_skmeminfo[SK_MEMINFO_BACKLOG]); nl_dump(p, "]\n\n"); } } static void idiagnl_msg_free(struct nl_object *a) { struct idiagnl_msg *msg = (struct idiagnl_msg *) a; if (a == NULL) return; free(msg->idiag_cong); nl_addr_put(msg->idiag_src); nl_addr_put(msg->idiag_dst); idiagnl_meminfo_put(msg->idiag_meminfo); idiagnl_vegasinfo_put(msg->idiag_vegasinfo); } static int idiagnl_msg_clone(struct nl_object *_dst, struct nl_object *_src) { struct idiagnl_msg *dst = (struct idiagnl_msg *) _dst; struct idiagnl_msg *src = (struct idiagnl_msg *) _src; dst->idiag_cong = NULL; dst->idiag_src = NULL; dst->idiag_dst = NULL; dst->idiag_meminfo = NULL; dst->idiag_vegasinfo = NULL; dst->ce_mask &= ~(IDIAGNL_ATTR_CONG | IDIAGNL_ATTR_SRC | IDIAGNL_ATTR_DST | IDIAGNL_ATTR_MEMINFO | IDIAGNL_ATTR_VEGASINFO); if (src->idiag_cong) { if (!(dst->idiag_cong = strdup(src->idiag_cong))) return -NLE_NOMEM; dst->ce_mask |= IDIAGNL_ATTR_CONG; } if (src->idiag_src) { if (!(dst->idiag_src = nl_addr_clone(src->idiag_src))) return -NLE_NOMEM; dst->ce_mask |= IDIAGNL_ATTR_SRC; } if (src->idiag_dst) { if (!(dst->idiag_dst = nl_addr_clone(src->idiag_dst))) return -NLE_NOMEM; dst->ce_mask |= IDIAGNL_ATTR_DST; } if (src->idiag_meminfo) { if (!(dst->idiag_meminfo = (struct idiagnl_meminfo *) nl_object_clone((struct nl_object *) src->idiag_meminfo))) return -NLE_NOMEM; dst->ce_mask |= IDIAGNL_ATTR_MEMINFO; } if (src->idiag_vegasinfo) { if (!(dst->idiag_vegasinfo = (struct idiagnl_vegasinfo *) nl_object_clone((struct nl_object *) src->idiag_vegasinfo))) return -NLE_NOMEM; dst->ce_mask |= IDIAGNL_ATTR_VEGASINFO; } return 0; } static struct nla_policy ext_policy[INET_DIAG_MAX+1] = { [INET_DIAG_MEMINFO] = { .minlen = sizeof(struct inet_diag_meminfo) }, [INET_DIAG_INFO] = { .minlen = sizeof(struct tcp_info) }, [INET_DIAG_VEGASINFO] = { .minlen = sizeof(struct tcpvegas_info) }, [INET_DIAG_CONG] = { .type = NLA_STRING }, [INET_DIAG_TOS] = { .type = NLA_U8 }, [INET_DIAG_TCLASS] = { .type = NLA_U8 }, /* Older kernel doesn't have SK_MEMINFO_BACKLOG */ [INET_DIAG_SKMEMINFO] = { .minlen = (sizeof(uint32_t) * (SK_MEMINFO_OPTMEM + 1)) }, [INET_DIAG_SHUTDOWN] = { .type = NLA_U8 }, }; int idiagnl_msg_parse(struct nlmsghdr *nlh, struct idiagnl_msg **result) { struct idiagnl_msg *msg = NULL; struct inet_diag_msg *raw_msg = NULL; struct nl_addr *src = NULL, *dst = NULL; struct nlattr *tb[INET_DIAG_MAX+1]; int err = 0; msg = idiagnl_msg_alloc(); if (!msg) goto errout_nomem; err = nlmsg_parse(nlh, sizeof(struct inet_diag_msg), tb, INET_DIAG_MAX, ext_policy); if (err < 0) goto errout; raw_msg = nlmsg_data(nlh); msg->idiag_family = raw_msg->idiag_family; msg->idiag_state = raw_msg->idiag_state; msg->idiag_timer = raw_msg->idiag_timer; msg->idiag_retrans = raw_msg->idiag_retrans; msg->idiag_expires = raw_msg->idiag_expires; msg->idiag_rqueue = raw_msg->idiag_rqueue; msg->idiag_wqueue = raw_msg->idiag_wqueue; msg->idiag_uid = raw_msg->idiag_uid; msg->idiag_inode = raw_msg->idiag_inode; msg->idiag_sport = raw_msg->id.idiag_sport; msg->idiag_dport = raw_msg->id.idiag_dport; msg->idiag_ifindex = raw_msg->id.idiag_if; msg->ce_mask = (IDIAGNL_ATTR_FAMILY | IDIAGNL_ATTR_STATE | IDIAGNL_ATTR_TIMER | IDIAGNL_ATTR_RETRANS | IDIAGNL_ATTR_EXPIRES | IDIAGNL_ATTR_RQUEUE | IDIAGNL_ATTR_WQUEUE | IDIAGNL_ATTR_UID | IDIAGNL_ATTR_INODE | IDIAGNL_ATTR_SPORT | IDIAGNL_ATTR_DPORT | IDIAGNL_ATTR_IFINDEX); dst = nl_addr_build(raw_msg->idiag_family, raw_msg->id.idiag_dst, sizeof(raw_msg->id.idiag_dst)); if (!dst) goto errout_nomem; err = idiagnl_msg_set_dst(msg, dst); if (err < 0) goto errout; nl_addr_put(dst); src = nl_addr_build(raw_msg->idiag_family, raw_msg->id.idiag_src, sizeof(raw_msg->id.idiag_src)); if (!src) goto errout_nomem; err = idiagnl_msg_set_src(msg, src); if (err < 0) goto errout; nl_addr_put(src); if (tb[INET_DIAG_TOS]) { msg->idiag_tos = nla_get_u8(tb[INET_DIAG_TOS]); msg->ce_mask |= IDIAGNL_ATTR_TOS; } if (tb[INET_DIAG_TCLASS]) { msg->idiag_tclass = nla_get_u8(tb[INET_DIAG_TCLASS]); msg->ce_mask |= IDIAGNL_ATTR_TCLASS; } if (tb[INET_DIAG_SHUTDOWN]) { msg->idiag_shutdown = nla_get_u8(tb[INET_DIAG_SHUTDOWN]); msg->ce_mask |= IDIAGNL_ATTR_SHUTDOWN; } if (tb[INET_DIAG_CONG]) { msg->idiag_cong = nla_strdup(tb[INET_DIAG_CONG]); msg->ce_mask |= IDIAGNL_ATTR_CONG; } if (tb[INET_DIAG_INFO]) { nla_memcpy(&msg->idiag_tcpinfo, tb[INET_DIAG_INFO], sizeof(msg->idiag_tcpinfo)); msg->ce_mask |= IDIAGNL_ATTR_TCPINFO; } if (tb[INET_DIAG_MEMINFO]) { struct idiagnl_meminfo *minfo = idiagnl_meminfo_alloc(); struct inet_diag_meminfo *raw_minfo = NULL; if (!minfo) goto errout_nomem; raw_minfo = (struct inet_diag_meminfo *) nla_data(tb[INET_DIAG_MEMINFO]); idiagnl_meminfo_set_rmem(minfo, raw_minfo->idiag_rmem); idiagnl_meminfo_set_wmem(minfo, raw_minfo->idiag_wmem); idiagnl_meminfo_set_fmem(minfo, raw_minfo->idiag_fmem); idiagnl_meminfo_set_tmem(minfo, raw_minfo->idiag_tmem); msg->idiag_meminfo = minfo; msg->ce_mask |= IDIAGNL_ATTR_MEMINFO; } if (tb[INET_DIAG_VEGASINFO]) { struct idiagnl_vegasinfo *vinfo = idiagnl_vegasinfo_alloc(); struct tcpvegas_info *raw_vinfo = NULL; if (!vinfo) goto errout_nomem; raw_vinfo = (struct tcpvegas_info *) nla_data(tb[INET_DIAG_VEGASINFO]); idiagnl_vegasinfo_set_enabled(vinfo, raw_vinfo->tcpv_enabled); idiagnl_vegasinfo_set_rttcnt(vinfo, raw_vinfo->tcpv_rttcnt); idiagnl_vegasinfo_set_rtt(vinfo, raw_vinfo->tcpv_rtt); idiagnl_vegasinfo_set_minrtt(vinfo, raw_vinfo->tcpv_minrtt); msg->idiag_vegasinfo = vinfo; msg->ce_mask |= IDIAGNL_ATTR_VEGASINFO; } if (tb[INET_DIAG_SKMEMINFO]) { nla_memcpy(&msg->idiag_skmeminfo, tb[INET_DIAG_SKMEMINFO], sizeof(msg->idiag_skmeminfo)); msg->ce_mask |= IDIAGNL_ATTR_SKMEMINFO; } *result = msg; return 0; errout: idiagnl_msg_put(msg); return err; errout_nomem: err = -NLE_NOMEM; goto errout; } static const struct trans_tbl idiagnl_attrs[] = { __ADD(IDIAGNL_ATTR_FAMILY, family), __ADD(IDIAGNL_ATTR_STATE, state), __ADD(IDIAGNL_ATTR_TIMER, timer), __ADD(IDIAGNL_ATTR_RETRANS, retrans), __ADD(IDIAGNL_ATTR_SPORT, sport), __ADD(IDIAGNL_ATTR_DPORT, dport), __ADD(IDIAGNL_ATTR_SRC, src), __ADD(IDIAGNL_ATTR_DST, dst), __ADD(IDIAGNL_ATTR_IFINDEX, ifindex), __ADD(IDIAGNL_ATTR_EXPIRES, expires), __ADD(IDIAGNL_ATTR_RQUEUE, rqueue), __ADD(IDIAGNL_ATTR_WQUEUE, wqueue), __ADD(IDIAGNL_ATTR_UID, uid), __ADD(IDIAGNL_ATTR_INODE, inode), __ADD(IDIAGNL_ATTR_TOS, tos), __ADD(IDIAGNL_ATTR_TCLASS, tclass), __ADD(IDIAGNL_ATTR_SHUTDOWN, shutdown), __ADD(IDIAGNL_ATTR_CONG, cong), __ADD(IDIAGNL_ATTR_MEMINFO, meminfo), __ADD(IDIAGNL_ATTR_VEGASINFO, vegasinfo), __ADD(IDIAGNL_ATTR_TCPINFO, tcpinfo), __ADD(IDIAGNL_ATTR_SKMEMINFO, skmeminfo), }; static char *_idiagnl_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, idiagnl_attrs, ARRAY_SIZE(idiagnl_attrs)); } static uint64_t idiagnl_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct idiagnl_msg *a = (struct idiagnl_msg *) _a; struct idiagnl_msg *b = (struct idiagnl_msg *) _b; uint64_t diff = 0; #define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, IDIAGNL_ATTR_##ATTR, a, b, EXPR) diff |= _DIFF(FAMILY, a->idiag_family != b->idiag_family); diff |= _DIFF(STATE, a->idiag_state != b->idiag_state); diff |= _DIFF(TIMER, a->idiag_timer != b->idiag_timer); diff |= _DIFF(RETRANS, a->idiag_retrans != b->idiag_retrans); diff |= _DIFF(SPORT, a->idiag_sport != b->idiag_sport); diff |= _DIFF(DPORT, a->idiag_dport != b->idiag_dport); diff |= _DIFF(SRC, nl_addr_cmp (a->idiag_src, b->idiag_src)); diff |= _DIFF(DST, nl_addr_cmp (a->idiag_dst, b->idiag_dst)); diff |= _DIFF(IFINDEX, a->idiag_ifindex != b->idiag_ifindex); diff |= _DIFF(EXPIRES, a->idiag_expires != b->idiag_expires); diff |= _DIFF(RQUEUE, a->idiag_rqueue != b->idiag_rqueue); diff |= _DIFF(WQUEUE, a->idiag_wqueue != b->idiag_wqueue); diff |= _DIFF(UID, a->idiag_uid != b->idiag_uid); diff |= _DIFF(INODE, a->idiag_inode != b->idiag_inode); diff |= _DIFF(TOS, a->idiag_tos != b->idiag_tos); diff |= _DIFF(TCLASS, a->idiag_tclass != b->idiag_tclass); diff |= _DIFF(SHUTDOWN, a->idiag_shutdown != b->idiag_shutdown); diff |= _DIFF(CONG, strcmp(a->idiag_cong, b->idiag_cong)); diff |= _DIFF(MEMINFO, nl_object_diff((struct nl_object *) a->idiag_meminfo, (struct nl_object *) b->idiag_meminfo)); diff |= _DIFF(VEGASINFO, nl_object_diff((struct nl_object *) a->idiag_vegasinfo, (struct nl_object *) b->idiag_vegasinfo)); diff |= _DIFF(TCPINFO, memcmp(&a->idiag_tcpinfo, &b->idiag_tcpinfo, sizeof(a->idiag_tcpinfo))); diff |= _DIFF(SKMEMINFO, memcmp(a->idiag_skmeminfo, b->idiag_skmeminfo, sizeof(a->idiag_skmeminfo))); #undef _DIFF return diff; } static void idiagnl_keygen(struct nl_object *obj, uint32_t *hashkey, uint32_t table_sz) { struct idiagnl_msg *msg = (struct idiagnl_msg *)obj; unsigned int key_sz; struct idiagnl_hash_key { uint8_t family; uint32_t src_hash; uint32_t dst_hash; uint16_t sport; uint16_t dport; } __attribute__((packed)) key; key_sz = sizeof(key); key.family = msg->idiag_family; key.src_hash = 0; key.dst_hash = 0; key.sport = msg->idiag_sport; key.dport = msg->idiag_dport; if (msg->idiag_src) { key.src_hash = nl_hash (nl_addr_get_binary_addr(msg->idiag_src), nl_addr_get_len(msg->idiag_src), 0); } if (msg->idiag_dst) { key.dst_hash = nl_hash (nl_addr_get_binary_addr(msg->idiag_dst), nl_addr_get_len(msg->idiag_dst), 0); } *hashkey = nl_hash(&key, key_sz, 0) % table_sz; NL_DBG(5, "idiagnl %p key (fam %d src_hash %d dst_hash %d sport %d dport %d) keysz %d, hash 0x%x\n", msg, key.family, key.src_hash, key.dst_hash, key.sport, key.dport, key_sz, *hashkey); return; } /** @cond SKIP */ struct nl_object_ops idiagnl_msg_obj_ops = { .oo_name = "idiag/idiag_msg", .oo_size = sizeof(struct idiagnl_msg), .oo_free_data = idiagnl_msg_free, .oo_clone = idiagnl_msg_clone, .oo_dump = { [NL_DUMP_LINE] = idiag_msg_dump_line, [NL_DUMP_DETAILS] = idiag_msg_dump_details, [NL_DUMP_STATS] = idiag_msg_dump_stats, }, .oo_compare = idiagnl_compare, .oo_keygen = idiagnl_keygen, .oo_attrs2str = _idiagnl_attrs2str, .oo_id_attrs = (IDIAGNL_ATTR_FAMILY | IDIAGNL_ATTR_SRC | IDIAGNL_ATTR_DST | IDIAGNL_ATTR_SPORT | IDIAGNL_ATTR_DPORT), }; /** @endcond */ /** @} */ libnl-3.2.29/lib/idiag/idiag.c0000644000175000017500000001670313023014600012670 00000000000000/* * lib/idiag/idiag.c Inet Diag Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Sassano Systems LLC */ /** * @defgroup idiag Inet Diag library (libnl-idiag) * @brief * @{ */ #include #include #include #include #include /** * @name Socket Creation * @{ */ /** * Create and connect idiag netlink socket. * @arg sk Netlink socket. * * Creates a NETLINK_INET_DIAG socket, binds the socket, and issues a connection * attemp. * * @see nl_connect() * * @return 0 on success or a negative error code. */ int idiagnl_connect(struct nl_sock *sk) { return nl_connect(sk, NETLINK_INET_DIAG); } /** @} */ /** * @name Sending * @{ */ /** * Send trivial idiag netlink message * @arg sk Netlink socket. * @arg flags Message flags * @arg family Address family * @arg states Socket states to query * @arg ext Inet Diag attribute extensions to query * * @return 0 on success or a negative error code. Due to a bug, this function * returns the number of bytes sent. Treat any non-negative number as success. */ int idiagnl_send_simple(struct nl_sock *sk, int flags, uint8_t family, uint16_t states, uint16_t ext) { struct inet_diag_req req; memset(&req, 0, sizeof(req)); flags |= NLM_F_ROOT; req.idiag_family = family; req.idiag_states = states; req.idiag_ext = ext; return nl_send_simple(sk, TCPDIAG_GETSOCK, flags, &req, sizeof(req)); } /** @} */ /** * @name Inet Diag flag and attribute conversions * @{ */ static const struct trans_tbl idiag_states[] = { __ADD(TCP_ESTABLISHED, established), __ADD(TCP_SYN_SENT, syn_sent), __ADD(TCP_SYN_RECV, syn_recv), __ADD(TCP_FIN_WAIT1, fin_wait), __ADD(TCP_FIN_WAIT2, fin_wait2), __ADD(TCP_TIME_WAIT, time_wait), __ADD(TCP_CLOSE, close), __ADD(TCP_CLOSE_WAIT, close_wait), __ADD(TCP_LAST_ACK, last_ack), __ADD(TCP_LISTEN, listen), __ADD(TCP_CLOSING, closing), }; /** * Convert inet diag socket states to strings. * @arg state inetdiag socket state (e.g., TCP_ESTABLISHED) * @arg buf output buffer which will hold string result * @arg len length in bytes of the output buffer * * @return string representation of the inetdiag socket state or an empty * string. */ char * idiagnl_state2str(int state, char *buf, size_t len) { return __type2str(state, buf, len, idiag_states, ARRAY_SIZE(idiag_states)); } /** * Convert inet diag socket state string to int. * @arg name inetdiag socket state string * * @return the int representation of the socket state strign or a negative error * code. */ int idiagnl_str2state(const char *name) { return __str2type(name, idiag_states, ARRAY_SIZE(idiag_states)); } static const struct trans_tbl idiag_timers[] = { __ADD(IDIAGNL_TIMER_OFF, off), __ADD(IDIAGNL_TIMER_ON, on), __ADD(IDIAGNL_TIMER_KEEPALIVE, keepalive), __ADD(IDIAGNL_TIMER_TIMEWAIT, timewait), __ADD(IDIAGNL_TIMER_PERSIST, persist), __ADD(IDIAGNL_TIMER_UNKNOWN, unknown), }; /** * Convert inet diag timer types to strings. * @arg timer inetdiag timer (e.g., IDIAGNL_TIMER_ON) * @arg buf output buffer which will hold string result * @arg len length in bytes of the output buffer * * @return string representation of the inetdiag timer type or an empty string. */ char * idiagnl_timer2str(int timer, char *buf, size_t len) { return __type2str(timer, buf, len, idiag_timers, ARRAY_SIZE(idiag_timers)); } /** * Convert inet diag timer string to int. * @arg name inetdiag timer string * * @return the int representation of the timer string or a negative error code. */ int idiagnl_str2timer(const char *name) { return __str2type(name, idiag_timers, ARRAY_SIZE(idiag_timers)); } static const struct trans_tbl idiag_attrs[] = { __ADD(INET_DIAG_NONE, none), __ADD(INET_DIAG_MEMINFO, meminfo), __ADD(INET_DIAG_INFO, info), __ADD(INET_DIAG_VEGASINFO, vegasinfo), __ADD(INET_DIAG_CONG, congestion), __ADD(INET_DIAG_TOS, tos), __ADD(INET_DIAG_TCLASS, tclass), __ADD(INET_DIAG_SKMEMINFO, skmeminfo), __ADD(INET_DIAG_SHUTDOWN, shutdown), }; /** * Convert inet diag extension type to a string. * @arg attrs inet diag extension type (e.g. INET_DIAG_MEMINFO) * @arg buf output buffer which will hold string result * @arg len length in bytes of the output buffer * * @return string representation of inet diag extension type or an empty string. * @deprecated: don't use this function. It is not very useful and should * never have been exposed as public API. */ char *idiagnl_attrs2str(int attrs, char *buf, size_t len) { return __type2str(attrs, buf, len, idiag_attrs, ARRAY_SIZE(idiag_attrs)); } static const struct trans_tbl idiag_exts[] = { __ADD((1 << (INET_DIAG_MEMINFO - 1)), meminfo), __ADD((1 << (INET_DIAG_INFO - 1)), info), __ADD((1 << (INET_DIAG_VEGASINFO - 1)), vegasinfo), __ADD((1 << (INET_DIAG_CONG - 1)), congestion), __ADD((1 << (INET_DIAG_TOS - 1)), tos), __ADD((1 << (INET_DIAG_TCLASS - 1)), tclass), __ADD((1 << (INET_DIAG_SKMEMINFO - 1)), skmeminfo), __ADD((1 << (INET_DIAG_SHUTDOWN - 1)), shutdown), }; /** * Convert inet diag extension flags to a string. * @arg attrs inet diag extension flags (e.g. * ( (1<<(INET_DIAG_MEMINFO-1)) | (1<<(INET_DIAG_CONG-1)) | (1<<(INET_DIAG_TOS-1)) ) ) * @arg buf Output buffer to hold string representation * @arg len length in bytes of the output buffer */ char *idiagnl_exts2str(uint8_t attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, idiag_exts, ARRAY_SIZE(idiag_exts)); } static const struct trans_tbl idiagnl_tcpstates[] = { __ADD(TCP_CA_Open, open), __ADD(TCP_CA_Disorder, disorder), __ADD(TCP_CA_CWR, cwr), __ADD(TCP_CA_Recovery, recovery), __ADD(TCP_CA_Loss, loss), }; /** * Convert inetdiag tcp states to strings. * @arg state TCP state (e.g., TCP_CA_Open) * @arg buf output buffer which will hold string result * @arg len length in bytes of the output buffer */ char *idiagnl_tcpstate2str(uint8_t state, char *buf, size_t len) { return __type2str(state, buf, len, idiagnl_tcpstates, ARRAY_SIZE(idiagnl_tcpstates)); } static const struct trans_tbl idiagnl_tcpopt_attrs[] = { __ADD(TCPI_OPT_TIMESTAMPS, timestamps), __ADD(TCPI_OPT_SACK, sACK), __ADD(TCPI_OPT_WSCALE, wscale), __ADD(TCPI_OPT_ECN, ecn), }; /** * Convert TCP option attributes to string * @arg attrs TCP option attributes to convert (e.g., TCPI_OPT_SACK | * TCPI_OPT_WSCALE) * @arg buf Output buffer for string * @arg len Length in bytes of output buffer * * @return buffer with string representation or empty string */ char *idiagnl_tcpopts2str(uint8_t attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, idiagnl_tcpopt_attrs, ARRAY_SIZE(idiagnl_tcpopt_attrs)); } /** * Convert shutdown state to string. * @arg shutdown Shutdown state (e.g., idiag_msg->shutdown) * @arg buf Ouput buffer to hold string representation * @arg len Length in bytes of output buffer * * @return string representation of shutdown state or NULL */ char * idiagnl_shutdown2str(uint8_t shutdown, char *buf, size_t len) { if (shutdown == 0) { snprintf(buf, len, " "); return buf; } else if (shutdown == 1) { snprintf(buf, len, "receive shutdown"); return buf; } else if (shutdown == 2) { snprintf(buf, len, "send shutdown"); return buf; } return NULL; } /** @} */ /** @} */ libnl-3.2.29/lib/defs.h.in0000644000175000017500000000415213031473643012103 00000000000000/* lib/defs.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 to disable pthreads */ #undef DISABLE_PTHREADS /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 to enable debugging */ #undef NL_DEBUG /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif libnl-3.2.29/lib/genl/0000755000175000017500000000000013031473756011414 500000000000000libnl-3.2.29/lib/genl/ctrl.c0000644000175000017500000003173413023014600012430 00000000000000/* * lib/genl/ctrl.c Generic Netlink Controller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup genl * @defgroup genl_ctrl Controller (Resolver) * * Resolves Generic Netlink family names to numeric identifiers. * * The controller is a component in the kernel that resolves Generic Netlink * family names to their numeric identifiers. This module provides functions * to query the controller to access the resolving functionality. * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define CTRL_VERSION 0x0001 static struct nl_cache_ops genl_ctrl_ops; static int ctrl_request_update(struct nl_cache *c, struct nl_sock *h) { return genl_send_simple(h, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, CTRL_VERSION, NLM_F_DUMP); } static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING, .maxlen = GENL_NAMSIZ }, [CTRL_ATTR_VERSION] = { .type = NLA_U32 }, [CTRL_ATTR_HDRSIZE] = { .type = NLA_U32 }, [CTRL_ATTR_MAXATTR] = { .type = NLA_U32 }, [CTRL_ATTR_OPS] = { .type = NLA_NESTED }, [CTRL_ATTR_MCAST_GROUPS] = { .type = NLA_NESTED }, }; static struct nla_policy family_op_policy[CTRL_ATTR_OP_MAX+1] = { [CTRL_ATTR_OP_ID] = { .type = NLA_U32 }, [CTRL_ATTR_OP_FLAGS] = { .type = NLA_U32 }, }; static struct nla_policy family_grp_policy[CTRL_ATTR_MCAST_GRP_MAX+1] = { [CTRL_ATTR_MCAST_GRP_NAME] = { .type = NLA_STRING }, [CTRL_ATTR_MCAST_GRP_ID] = { .type = NLA_U32 }, }; static int parse_mcast_grps(struct genl_family *family, struct nlattr *grp_attr) { struct nlattr *nla; int remaining, err; if (!grp_attr) BUG(); nla_for_each_nested(nla, grp_attr, remaining) { struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1]; int id; const char * name; err = nla_parse_nested(tb, CTRL_ATTR_MCAST_GRP_MAX, nla, family_grp_policy); if (err < 0) goto errout; if (tb[CTRL_ATTR_MCAST_GRP_ID] == NULL) { err = -NLE_MISSING_ATTR; goto errout; } id = nla_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]); if (tb[CTRL_ATTR_MCAST_GRP_NAME] == NULL) { err = -NLE_MISSING_ATTR; goto errout; } name = nla_get_string(tb[CTRL_ATTR_MCAST_GRP_NAME]); err = genl_family_add_grp(family, id, name); if (err < 0) goto errout; } err = 0; errout: return err; } static int ctrl_msg_parser(struct nl_cache_ops *ops, struct genl_cmd *cmd, struct genl_info *info, void *arg) { struct genl_family *family; struct nl_parser_param *pp = arg; int err; family = genl_family_alloc(); if (family == NULL) { err = -NLE_NOMEM; goto errout; } if (info->attrs[CTRL_ATTR_FAMILY_NAME] == NULL) { err = -NLE_MISSING_ATTR; goto errout; } if (info->attrs[CTRL_ATTR_FAMILY_ID] == NULL) { err = -NLE_MISSING_ATTR; goto errout; } family->ce_msgtype = info->nlh->nlmsg_type; genl_family_set_id(family, nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID])); genl_family_set_name(family, nla_get_string(info->attrs[CTRL_ATTR_FAMILY_NAME])); if (info->attrs[CTRL_ATTR_VERSION]) { uint32_t version = nla_get_u32(info->attrs[CTRL_ATTR_VERSION]); genl_family_set_version(family, version); } if (info->attrs[CTRL_ATTR_HDRSIZE]) { uint32_t hdrsize = nla_get_u32(info->attrs[CTRL_ATTR_HDRSIZE]); genl_family_set_hdrsize(family, hdrsize); } if (info->attrs[CTRL_ATTR_MAXATTR]) { uint32_t maxattr = nla_get_u32(info->attrs[CTRL_ATTR_MAXATTR]); genl_family_set_maxattr(family, maxattr); } if (info->attrs[CTRL_ATTR_OPS]) { struct nlattr *nla, *nla_ops; int remaining; nla_ops = info->attrs[CTRL_ATTR_OPS]; nla_for_each_nested(nla, nla_ops, remaining) { struct nlattr *tb[CTRL_ATTR_OP_MAX+1]; int flags = 0, id; err = nla_parse_nested(tb, CTRL_ATTR_OP_MAX, nla, family_op_policy); if (err < 0) goto errout; if (tb[CTRL_ATTR_OP_ID] == NULL) { err = -NLE_MISSING_ATTR; goto errout; } id = nla_get_u32(tb[CTRL_ATTR_OP_ID]); if (tb[CTRL_ATTR_OP_FLAGS]) flags = nla_get_u32(tb[CTRL_ATTR_OP_FLAGS]); err = genl_family_add_op(family, id, flags); if (err < 0) goto errout; } } if (info->attrs[CTRL_ATTR_MCAST_GROUPS]) { err = parse_mcast_grps(family, info->attrs[CTRL_ATTR_MCAST_GROUPS]); if (err < 0) goto errout; } err = pp->pp_cb((struct nl_object *) family, pp); errout: genl_family_put(family); return err; } /** * process responses from from the query sent by genl_ctrl_probe_by_name * @arg nl_msg Returned message. * @arg name genl_family structure to fill out. * * Process returned messages, filling out the missing informatino in the * genl_family structure * * @return Indicator to keep processing frames or not * */ static int probe_response(struct nl_msg *msg, void *arg) { struct nlattr *tb[CTRL_ATTR_MAX+1]; struct nlmsghdr *nlh = nlmsg_hdr(msg); struct genl_family *ret = (struct genl_family *)arg; if (genlmsg_parse(nlh, 0, tb, CTRL_ATTR_MAX, ctrl_policy)) return NL_SKIP; if (tb[CTRL_ATTR_FAMILY_ID]) genl_family_set_id(ret, nla_get_u16(tb[CTRL_ATTR_FAMILY_ID])); if (tb[CTRL_ATTR_MCAST_GROUPS]) if (parse_mcast_grps(ret, tb[CTRL_ATTR_MCAST_GROUPS]) < 0) return NL_SKIP; return NL_STOP; } /** * Look up generic netlink family by family name querying the kernel directly * @arg sk Socket. * @arg name Family name. * * Directly query's the kernel for a given family name. The caller will own a * reference on the returned object which needsd to be given back after usage * using genl_family_put. * * Note: This API call differs from genl_ctrl_search_by_name in that it querys * the kernel directly, alowing for module autoload to take place to resolve the * family request. Using an nl_cache prevents that operation * * @return Generic netlink family object or NULL if no match was found. */ static struct genl_family *genl_ctrl_probe_by_name(struct nl_sock *sk, const char *name) { struct nl_msg *msg; struct genl_family *ret; struct nl_cb *cb, *orig; int rc; ret = genl_family_alloc(); if (!ret) goto out; genl_family_set_name(ret, name); msg = nlmsg_alloc(); if (!msg) goto out_fam_free; if (!(orig = nl_socket_get_cb(sk))) goto out_msg_free; cb = nl_cb_clone(orig); nl_cb_put(orig); if (!cb) goto out_msg_free; if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, 1)) { BUG(); goto out_cb_free; } if (nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, name) < 0) goto out_cb_free; rc = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, probe_response, (void *) ret); if (rc < 0) goto out_cb_free; rc = nl_send_auto_complete(sk, msg); if (rc < 0) goto out_cb_free; rc = nl_recvmsgs(sk, cb); if (rc < 0) goto out_cb_free; /* If search was successful, request may be ACKed after data */ rc = wait_for_ack(sk); if (rc < 0) goto out_cb_free; if (genl_family_get_id(ret) != 0) { nlmsg_free(msg); nl_cb_put(cb); return ret; } out_cb_free: nl_cb_put(cb); out_msg_free: nlmsg_free(msg); out_fam_free: genl_family_put(ret); ret = NULL; out: return ret; } /** @endcond */ /** * @name Controller Cache * * The controller cache allows to keep a local copy of the list of all * kernel side registered Generic Netlink families to quickly resolve * multiple Generic Netlink family names without requiring to communicate * with the kernel for each resolving iteration. * * @{ */ /** * Allocate a new controller cache * @arg sk Generic Netlink socket * @arg result Pointer to store resulting cache * * Allocates a new cache mirroring the state of the controller and stores it * in \c *result. The allocated cache will contain a list of all currently * registered kernel side Generic Netlink families. The cache is meant to be * used to resolve family names locally. * * @return 0 on success or a negative error code. */ int genl_ctrl_alloc_cache(struct nl_sock *sk, struct nl_cache **result) { return nl_cache_alloc_and_fill(&genl_ctrl_ops, sk, result); } /** * Search controller cache for a numeric address match * @arg cache Controller cache * @arg id Numeric family identifier. * * Searches a previously allocated controller cache and looks for an entry * that matches the specified numeric family identifier \c id. If a match * is found successfully, the reference count of the matching object is * increased by one before the objet is returned. * * @see genl_ctrl_alloc_cache() * @see genl_ctrl_search_by_name() * @see genl_family_put() * * @return Generic Netlink family object or NULL if no match was found. */ struct genl_family *genl_ctrl_search(struct nl_cache *cache, int id) { struct genl_family *fam; if (cache->c_ops != &genl_ctrl_ops) BUG(); nl_list_for_each_entry(fam, &cache->c_items, ce_list) { if (fam->gf_id == id) { nl_object_get((struct nl_object *) fam); return fam; } } return NULL; } /** * Search controller cache for a family name match * @arg cache Controller cache * @arg name Name of Generic Netlink family * * Searches a previously allocated controller cache and looks for an entry * that matches the specified family \c name. If a match is found successfully, * the reference count of the matching object is increased by one before the * objet is returned. * * @see genl_ctrl_alloc_cache() * @see genl_ctrl_search() * @see genl_family_put() * * @return Generic Netlink family object or NULL if no match was found. */ struct genl_family *genl_ctrl_search_by_name(struct nl_cache *cache, const char *name) { struct genl_family *fam; if (cache->c_ops != &genl_ctrl_ops) BUG(); nl_list_for_each_entry(fam, &cache->c_items, ce_list) { if (!strcmp(name, fam->gf_name)) { nl_object_get((struct nl_object *) fam); return fam; } } return NULL; } /** @} */ /** * @name Direct Resolvers * * These functions communicate directly with the kernel and do not require * a cache to be kept up to date. * * @{ */ /** * Resolve Generic Netlink family name to numeric identifier * @arg sk Generic Netlink socket. * @arg name Name of Generic Netlink family * * Resolves the Generic Netlink family name to the corresponding numeric * family identifier. This function queries the kernel directly, use * genl_ctrl_search_by_name() if you need to resolve multiple names. * * @see genl_ctrl_search_by_name() * * @return The numeric family identifier or a negative error code. */ int genl_ctrl_resolve(struct nl_sock *sk, const char *name) { struct genl_family *family; int err; family = genl_ctrl_probe_by_name(sk, name); if (family == NULL) { err = -NLE_OBJ_NOTFOUND; goto errout; } err = genl_family_get_id(family); genl_family_put(family); errout: return err; } static int genl_ctrl_grp_by_name(const struct genl_family *family, const char *grp_name) { struct genl_family_grp *grp; nl_list_for_each_entry(grp, &family->gf_mc_grps, list) { if (!strcmp(grp->name, grp_name)) { return grp->id; } } return -NLE_OBJ_NOTFOUND; } /** * Resolve Generic Netlink family group name * @arg sk Generic Netlink socket * @arg family_name Name of Generic Netlink family * @arg grp_name Name of group to resolve * * Looks up the family object and resolves the group name to the numeric * group identifier. * * @return Numeric group identifier or a negative error code. */ int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family_name, const char *grp_name) { struct genl_family *family; int err; family = genl_ctrl_probe_by_name(sk, family_name); if (family == NULL) { err = -NLE_OBJ_NOTFOUND; goto errout; } err = genl_ctrl_grp_by_name(family, grp_name); genl_family_put(family); errout: return err; } /** @} */ /** @cond SKIP */ static struct genl_cmd genl_cmds[] = { { .c_id = CTRL_CMD_NEWFAMILY, .c_name = "NEWFAMILY" , .c_maxattr = CTRL_ATTR_MAX, .c_attr_policy = ctrl_policy, .c_msg_parser = ctrl_msg_parser, }, { .c_id = CTRL_CMD_DELFAMILY, .c_name = "DELFAMILY" , }, { .c_id = CTRL_CMD_GETFAMILY, .c_name = "GETFAMILY" , }, { .c_id = CTRL_CMD_NEWOPS, .c_name = "NEWOPS" , }, { .c_id = CTRL_CMD_DELOPS, .c_name = "DELOPS" , }, }; static struct genl_ops genl_ops = { .o_cmds = genl_cmds, .o_ncmds = ARRAY_SIZE(genl_cmds), }; extern struct nl_object_ops genl_family_ops; static struct nl_cache_ops genl_ctrl_ops = { .co_name = "genl/family", .co_hdrsize = GENL_HDRSIZE(0), .co_msgtypes = GENL_FAMILY(GENL_ID_CTRL, "nlctrl"), .co_genl = &genl_ops, .co_protocol = NETLINK_GENERIC, .co_request_update = ctrl_request_update, .co_obj_ops = &genl_family_ops, }; static void __init ctrl_init(void) { genl_register(&genl_ctrl_ops); } static void __exit ctrl_exit(void) { genl_unregister(&genl_ctrl_ops); } /** @endcond */ /** @} */ libnl-3.2.29/lib/genl/family.c0000644000175000017500000002124713023014600012743 00000000000000/* * lib/genl/family.c Generic Netlink Family * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup genl_ctrl * @defgroup genl_family Generic Netlink Family Object * * Object representing a kernel side registered Generic Netlink family * * @{ */ #include #include #include #include #include /** @cond SKIP */ #define FAMILY_ATTR_ID 0x01 #define FAMILY_ATTR_NAME 0x02 #define FAMILY_ATTR_VERSION 0x04 #define FAMILY_ATTR_HDRSIZE 0x08 #define FAMILY_ATTR_MAXATTR 0x10 #define FAMILY_ATTR_OPS 0x20 struct nl_object_ops genl_family_ops; static void family_constructor(struct nl_object *c) { struct genl_family *family = (struct genl_family *) c; nl_init_list_head(&family->gf_ops); nl_init_list_head(&family->gf_mc_grps); } static void family_free_data(struct nl_object *c) { struct genl_family *family = (struct genl_family *) c; struct genl_family_op *ops, *tmp; struct genl_family_grp *grp, *t_grp; if (family == NULL) return; nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) { nl_list_del(&ops->o_list); free(ops); } nl_list_for_each_entry_safe(grp, t_grp, &family->gf_mc_grps, list) { nl_list_del(&grp->list); free(grp); } } static int family_clone(struct nl_object *_dst, struct nl_object *_src) { struct genl_family *dst = nl_object_priv(_dst); struct genl_family *src = nl_object_priv(_src); struct genl_family_op *ops; struct genl_family_grp *grp; int err; nl_list_for_each_entry(ops, &src->gf_ops, o_list) { err = genl_family_add_op(dst, ops->o_id, ops->o_flags); if (err < 0) return err; } nl_list_for_each_entry(grp, &src->gf_mc_grps, list) { err = genl_family_add_grp(dst, grp->id, grp->name); if (err < 0) return err; } return 0; } static void family_dump_line(struct nl_object *obj, struct nl_dump_params *p) { struct genl_family *family = (struct genl_family *) obj; nl_dump(p, "0x%04x %s version %u\n", family->gf_id, family->gf_name, family->gf_version); } static const struct trans_tbl ops_flags[] = { __ADD(GENL_ADMIN_PERM, admin_perm), __ADD(GENL_CMD_CAP_DO, has_doit), __ADD(GENL_CMD_CAP_DUMP, has_dump), __ADD(GENL_CMD_CAP_HASPOL, has_policy), }; static char *ops_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, ops_flags, ARRAY_SIZE(ops_flags)); } static void family_dump_details(struct nl_object *obj, struct nl_dump_params *p) { struct genl_family_grp *grp; struct genl_family *family = (struct genl_family *) obj; family_dump_line(obj, p); nl_dump_line(p, " hdrsize %u maxattr %u\n", family->gf_hdrsize, family->gf_maxattr); if (family->ce_mask & FAMILY_ATTR_OPS) { struct genl_family_op *op; char buf[64]; nl_list_for_each_entry(op, &family->gf_ops, o_list) { ops_flags2str(op->o_flags, buf, sizeof(buf)); genl_op2name(family->gf_id, op->o_id, buf, sizeof(buf)); nl_dump_line(p, " op %s (0x%02x)", buf, op->o_id); if (op->o_flags) nl_dump(p, " <%s>", ops_flags2str(op->o_flags, buf, sizeof(buf))); nl_dump(p, "\n"); } } nl_list_for_each_entry(grp, &family->gf_mc_grps, list) { nl_dump_line(p, " grp %s (0x%02x)\n", grp->name, grp->id); } } static void family_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { family_dump_details(obj, p); } static uint64_t family_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct genl_family *a = (struct genl_family *) _a; struct genl_family *b = (struct genl_family *) _b; uint64_t diff = 0; #define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR) diff |= FAM_DIFF(ID, a->gf_id != b->gf_id); diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version); diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize); diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr); diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name)); #undef FAM_DIFF return diff; } /** @endcond */ /** * @name Object Allocation * @{ */ /** * Allocate new Generic Netlink family object * * @return Newly allocated Generic Netlink family object or NULL. */ struct genl_family *genl_family_alloc(void) { return (struct genl_family *) nl_object_alloc(&genl_family_ops); } /** * Release reference on Generic Netlink family object * @arg family Generic Netlink family object * * Reduces the reference counter of a Generic Netlink family object by one. * The object is freed after the last user has returned its reference. * * @see nl_object_put() */ void genl_family_put(struct genl_family *family) { nl_object_put((struct nl_object *) family); } /** @} */ /** * @name Numeric Identifier * @{ */ /** * Return numeric identifier * @arg family Generic Netlink family object * * @return Numeric identifier or 0 if not available. */ unsigned int genl_family_get_id(struct genl_family *family) { if (family->ce_mask & FAMILY_ATTR_ID) return family->gf_id; else return GENL_ID_GENERATE; } /** * Set the numeric identifier * @arg family Generic Netlink family object * @arg id New numeric identifier */ void genl_family_set_id(struct genl_family *family, unsigned int id) { family->gf_id = id; family->ce_mask |= FAMILY_ATTR_ID; } /** @} */ /** * @name Human Readable Name * @{ */ /** * Return human readable name * @arg family Generic Netlink family object * * @return Name of family or NULL if not available */ char *genl_family_get_name(struct genl_family *family) { if (family->ce_mask & FAMILY_ATTR_NAME) return family->gf_name; else return NULL; } /** * Set human readable name * @arg family Generic Netlink family object * @arg name New human readable name */ void genl_family_set_name(struct genl_family *family, const char *name) { strncpy(family->gf_name, name, GENL_NAMSIZ-1); family->ce_mask |= FAMILY_ATTR_NAME; } /** * @name Interface Version * @{ */ /** * Return interface version * @arg family Generic Netlink family object * * @return Interface version or 0 if not available. */ uint8_t genl_family_get_version(struct genl_family *family) { if (family->ce_mask & FAMILY_ATTR_VERSION) return family->gf_version; else return 0; } /** * Set interface version * @arg family Generic Netlink family object * @arg version New interface version */ void genl_family_set_version(struct genl_family *family, uint8_t version) { family->gf_version = version; family->ce_mask |= FAMILY_ATTR_VERSION; } /** @} */ /** * @name Header Size * @{ */ /** * Return user header size expected by kernel component * @arg family Generic Netlink family object * * @return Expected header length or 0 if not available. */ uint32_t genl_family_get_hdrsize(struct genl_family *family) { if (family->ce_mask & FAMILY_ATTR_HDRSIZE) return family->gf_hdrsize; else return 0; } void genl_family_set_hdrsize(struct genl_family *family, uint32_t hdrsize) { family->gf_hdrsize = hdrsize; family->ce_mask |= FAMILY_ATTR_HDRSIZE; } /** @} */ /** * @name Maximum Expected Attribute * @{ */ uint32_t genl_family_get_maxattr(struct genl_family *family) { if (family->ce_mask & FAMILY_ATTR_MAXATTR) return family->gf_maxattr; else return family->gf_maxattr; } void genl_family_set_maxattr(struct genl_family *family, uint32_t maxattr) { family->gf_maxattr = maxattr; family->ce_mask |= FAMILY_ATTR_MAXATTR; } /** @} */ /** * @name Operations * @{ */ int genl_family_add_op(struct genl_family *family, int id, int flags) { struct genl_family_op *op; op = calloc(1, sizeof(*op)); if (op == NULL) return -NLE_NOMEM; op->o_id = id; op->o_flags = flags; nl_list_add_tail(&op->o_list, &family->gf_ops); family->ce_mask |= FAMILY_ATTR_OPS; return 0; } int genl_family_add_grp(struct genl_family *family, uint32_t id, const char *name) { struct genl_family_grp *grp; grp = calloc(1, sizeof(*grp)); if (grp == NULL) return -NLE_NOMEM; grp->id = id; strncpy(grp->name, name, GENL_NAMSIZ - 1); nl_list_add_tail(&grp->list, &family->gf_mc_grps); return 0; } /** @} */ /** @cond SKIP */ struct nl_object_ops genl_family_ops = { .oo_name = "genl/family", .oo_size = sizeof(struct genl_family), .oo_constructor = family_constructor, .oo_free_data = family_free_data, .oo_clone = family_clone, .oo_dump = { [NL_DUMP_LINE] = family_dump_line, [NL_DUMP_DETAILS] = family_dump_details, [NL_DUMP_STATS] = family_dump_stats, }, .oo_compare = family_compare, .oo_id_attrs = FAMILY_ATTR_ID, }; /** @endcond */ /** @} */ libnl-3.2.29/lib/genl/mngt.c0000644000175000017500000002002713023014600012422 00000000000000/* * lib/genl/mngt.c Generic Netlink Management * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup genl * @defgroup genl_mngt Family and Command Registration * * Registering Generic Netlink Families and Commands * * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ static NL_LIST_HEAD(genl_ops_list); static struct genl_cmd *lookup_cmd(struct genl_ops *ops, int cmd_id) { struct genl_cmd *cmd; int i; for (i = 0; i < ops->o_ncmds; i++) { cmd = &ops->o_cmds[i]; if (cmd->c_id == cmd_id) return cmd; } return NULL; } static int cmd_msg_parser(struct sockaddr_nl *who, struct nlmsghdr *nlh, struct genl_ops *ops, struct nl_cache_ops *cache_ops, void *arg) { int err; struct genlmsghdr *ghdr; struct genl_cmd *cmd; ghdr = genlmsg_hdr(nlh); if (!(cmd = lookup_cmd(ops, ghdr->cmd))) { err = -NLE_MSGTYPE_NOSUPPORT; goto errout; } if (cmd->c_msg_parser == NULL) err = -NLE_OPNOTSUPP; else { struct nlattr *tb[cmd->c_maxattr + 1]; struct genl_info info = { .who = who, .nlh = nlh, .genlhdr = ghdr, .userhdr = genlmsg_user_hdr(ghdr), .attrs = tb, }; err = nlmsg_parse(nlh, GENL_HDRSIZE(ops->o_hdrsize), tb, cmd->c_maxattr, cmd->c_attr_policy); if (err < 0) goto errout; err = cmd->c_msg_parser(cache_ops, cmd, &info, arg); } errout: return err; } static int genl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { if (ops->co_genl == NULL) BUG(); return cmd_msg_parser(who, nlh, ops->co_genl, ops, pp); } static struct genl_ops *lookup_family(int family) { struct genl_ops *ops; nl_list_for_each_entry(ops, &genl_ops_list, o_list) { if (ops->o_id == family) return ops; } return NULL; } static struct genl_ops *lookup_family_by_name(const char *name) { struct genl_ops *ops; nl_list_for_each_entry(ops, &genl_ops_list, o_list) { if (!strcmp(ops->o_name, name)) return ops; } return NULL; } char *genl_op2name(int family, int op, char *buf, size_t len) { struct genl_ops *ops; int i; if ((ops = lookup_family(family))) { for (i = 0; i < ops->o_ncmds; i++) { struct genl_cmd *cmd; cmd = &ops->o_cmds[i]; if (cmd->c_id == op) { strncpy(buf, cmd->c_name, len - 1); return buf; } } } strncpy(buf, "unknown", len - 1); return NULL; } /** @endcond */ /** * @name Registration * @{ */ /** * Register Generic Netlink family and associated commands * @arg ops Generic Netlink family definition * * Registers the specified Generic Netlink family definition together with * all associated commands. After registration, received Generic Netlink * messages can be passed to genl_handle_msg() which will validate the * messages, look for a matching command and call the respective callback * function automatically. * * @note Consider using genl_register() if the family is used to implement a * cacheable type. * * @see genl_unregister_family(); * @see genl_register(); * * @return 0 on success or a negative error code. */ int genl_register_family(struct genl_ops *ops) { if (!ops->o_name) return -NLE_INVAL; if (ops->o_cmds && ops->o_ncmds <= 0) return -NLE_INVAL; if (ops->o_id && lookup_family(ops->o_id)) return -NLE_EXIST; if (lookup_family_by_name(ops->o_name)) return -NLE_EXIST; nl_list_add_tail(&ops->o_list, &genl_ops_list); return 0; } /** * Unregister Generic Netlink family * @arg ops Generic Netlink family definition * * Unregisters a family and all associated commands that were previously * registered using genl_register_family(). * * @see genl_register_family() * * @return 0 on success or a negative error code. */ int genl_unregister_family(struct genl_ops *ops) { nl_list_del(&ops->o_list); return 0; } /** * Run a received message through the demultiplexer * @arg msg Generic Netlink message * @arg arg Argument passed on to the message handler callback * * @return 0 on success or a negative error code. */ int genl_handle_msg(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct genl_ops *ops; if (!genlmsg_valid_hdr(nlh, 0)) return -NLE_INVAL; if (!(ops = lookup_family(nlh->nlmsg_type))) return -NLE_MSGTYPE_NOSUPPORT; return cmd_msg_parser(nlmsg_get_src(msg), nlh, ops, NULL, arg); } /** @} */ /** * @name Registration of Cache Operations * @{ */ /** * Register Generic Netlink family backed cache * @arg ops Cache operations definition * * Same as genl_register_family() but additionally registers the specified * cache operations using nl_cache_mngt_register() and associates it with * the Generic Netlink family. * * @see genl_register_family() * * @return 0 on success or a negative error code. */ int genl_register(struct nl_cache_ops *ops) { int err; if (ops->co_protocol != NETLINK_GENERIC) { err = -NLE_PROTO_MISMATCH; goto errout; } if (ops->co_hdrsize < GENL_HDRSIZE(0)) { err = -NLE_INVAL; goto errout; } if (ops->co_genl == NULL) { err = -NLE_INVAL; goto errout; } ops->co_genl->o_cache_ops = ops; ops->co_genl->o_hdrsize = ops->co_hdrsize - GENL_HDRLEN; ops->co_genl->o_name = ops->co_msgtypes[0].mt_name; ops->co_genl->o_id = ops->co_msgtypes[0].mt_id; ops->co_msg_parser = genl_msg_parser; if ((err = genl_register_family(ops->co_genl)) < 0) goto errout; err = nl_cache_mngt_register(ops); errout: return err; } /** * Unregister cache based Generic Netlink family * @arg ops Cache operations definition */ void genl_unregister(struct nl_cache_ops *ops) { if (!ops) return; nl_cache_mngt_unregister(ops); genl_unregister_family(ops->co_genl); } /** @} */ /** @cond SKIP */ static int __genl_ops_resolve(struct nl_cache *ctrl, struct genl_ops *ops) { struct genl_family *family; family = genl_ctrl_search_by_name(ctrl, ops->o_name); if (family != NULL) { ops->o_id = genl_family_get_id(family); if (ops->o_cache_ops) ops->o_cache_ops->co_msgtypes[0].mt_id = ops->o_id; genl_family_put(family); return 0; } return -NLE_OBJ_NOTFOUND; } int genl_resolve_id(struct genl_ops *ops) { struct nl_sock *sk; int err = 0; /* Check if resolved already */ if (ops->o_id != GENL_ID_GENERATE) return 0; if (!ops->o_name) return -NLE_INVAL; if (!(sk = nl_socket_alloc())) return -NLE_NOMEM; if ((err = genl_connect(sk)) < 0) goto errout_free; err = genl_ops_resolve(sk, ops); errout_free: nl_socket_free(sk); return err; } /** @endcond */ /** * @name Resolving the name of registered families * @{ */ /** * Resolve a single Generic Netlink family * @arg sk Generic Netlink socket * @arg ops Generic Netlink family definition * * Resolves the family name to its numeric identifier. * * @return 0 on success or a negative error code. */ int genl_ops_resolve(struct nl_sock *sk, struct genl_ops *ops) { struct nl_cache *ctrl; int err; if ((err = genl_ctrl_alloc_cache(sk, &ctrl)) < 0) goto errout; err = __genl_ops_resolve(ctrl, ops); nl_cache_free(ctrl); errout: return err; } /** * Resolve all registered Generic Netlink families * @arg sk Generic Netlink socket * * Walks through all local Generic Netlink families that have been registered * using genl_register() and resolves the name of each family to the * corresponding numeric identifier. * * @see genl_register() * @see genl_ops_resolve() * * @return 0 on success or a negative error code. */ int genl_mngt_resolve(struct nl_sock *sk) { struct nl_cache *ctrl; struct genl_ops *ops; int err = 0; if ((err = genl_ctrl_alloc_cache(sk, &ctrl)) < 0) goto errout; nl_list_for_each_entry(ops, &genl_ops_list, o_list) { err = __genl_ops_resolve(ctrl, ops); } nl_cache_free(ctrl); errout: return err; } /** @} */ /** @} */ libnl-3.2.29/lib/genl/genl.c0000644000175000017500000002351413023014600012406 00000000000000/* * lib/genl/genl.c Generic Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @defgroup genl Generic Netlink Library (libnl-genl) * * @{ */ #include #include #include #include /** * @name Generic Netlink Socket * @{ */ /** * Connect a Generic Netlink socket * @arg sk Unconnected Netlink socket * * This function expects a struct nl_socket object previously allocated via * nl_socket_alloc(). It calls nl_connect() to create the local socket file * descriptor and binds the socket to the \c NETLINK_GENERIC Netlink protocol. * * Using this function is equivalent to: * @code * nl_connect(sk, NETLINK_GENERIC); * @endcode * * @see nl_connect() * * @return 0 on success or a negative error code. */ int genl_connect(struct nl_sock *sk) { return nl_connect(sk, NETLINK_GENERIC); } /** @} */ /** * @name Sending Data * @{ */ /** * Send a Generic Netlink message consisting only of a header * @arg sk Generic Netlink socket * @arg family Numeric family identifier * @arg cmd Numeric command identifier * @arg version Interface version * @arg flags Additional Netlink message flags (optional) * * This function is a shortcut for sending a Generic Netlink message without * any message payload. The message will only consist of the Netlink and * Generic Netlink headers. The header is constructed based on the specified * parameters and passed on to nl_send_simple() to send it on the specified * socket. * * @par Example: * @code * #include * #include * * err = genl_send_simple(sk, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, CTRL_VERSION, * NLM_F_DUMP); * @endcode * * @see nl_send_simple() * * @return 0 on success or a negative error code. Due to a bug, this function * returns the number of bytes sent. Treat any non-negative number as success. */ int genl_send_simple(struct nl_sock *sk, int family, int cmd, int version, int flags) { struct genlmsghdr hdr = { .cmd = cmd, .version = version, }; return nl_send_simple(sk, family, flags, &hdr, sizeof(hdr)); } /** @} */ /** * @name Message Parsing * @{ */ /** * Validate Generic Netlink message headers * @arg nlh Pointer to Netlink message header * @arg hdrlen Length of user header * * Verifies the integrity of the Netlink and Generic Netlink headers by * enforcing the following requirements: * - Valid Netlink message header (nlmsg_valid_hdr()) * - Presence of a complete Generic Netlink header * - At least \c hdrlen bytes of payload included after the generic * netlink header. * * @return A positive integer (true) if the headers are valid or * 0 (false) if not. */ int genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen) { struct genlmsghdr *ghdr; if (!nlmsg_valid_hdr(nlh, GENL_HDRLEN)) return 0; ghdr = nlmsg_data(nlh); if (genlmsg_len(ghdr) < NLMSG_ALIGN(hdrlen)) return 0; return 1; } /** * Validate Generic Netlink message including attributes * @arg nlh Pointer to Netlink message header * @arg hdrlen Length of user header * @arg maxtype Maximum attribtue id expected * @arg policy Attribute validation policy * * Verifies the validity of the Netlink and Generic Netlink headers using * genlmsg_valid_hdr() and calls nla_validate() on the message payload to * verify the integrity of eventual attributes. * * @note You may call genlmsg_parse() directly to perform validation and * parsing in a single step. * * @see genlmsg_valid_hdr() * @see nla_validate() * @see genlmsg_parse() * * @return 0 on success or a negative error code. */ int genlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, struct nla_policy *policy) { struct genlmsghdr *ghdr; if (!genlmsg_valid_hdr(nlh, hdrlen)) return -NLE_MSG_TOOSHORT; ghdr = nlmsg_data(nlh); return nla_validate(genlmsg_attrdata(ghdr, hdrlen), genlmsg_attrlen(ghdr, hdrlen), maxtype, policy); } /** * Parse Generic Netlink message including attributes * @arg nlh Pointer to Netlink message header * @arg hdrlen Length of user header * @arg tb Array to store parsed attributes * @arg maxtype Maximum attribute id expected * @arg policy Attribute validation policy * * Verifies the validity of the Netlink and Generic Netlink headers using * genlmsg_valid_hdr() and calls nla_parse() on the message payload to * parse eventual attributes. * * @par Example: * @code * struct nlattr *attrs[MY_TYPE_MAX+1]; * * if ((err = genlsmg_parse(nlmsg_nlh(msg), sizeof(struct my_hdr), attrs, * MY_TYPE_MAX, attr_policy)) < 0) * // ERROR * @endcode * * @see genlmsg_valid_hdr() * @see genlmsg_validate() * @see nla_parse() * * @return 0 on success or a negative error code. */ int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy) { struct genlmsghdr *ghdr; if (!genlmsg_valid_hdr(nlh, hdrlen)) return -NLE_MSG_TOOSHORT; ghdr = nlmsg_data(nlh); return nla_parse(tb, maxtype, genlmsg_attrdata(ghdr, hdrlen), genlmsg_attrlen(ghdr, hdrlen), policy); } /** * Return pointer to Generic Netlink header * @arg nlh Netlink message header * * @return Pointer to Generic Netlink message header */ struct genlmsghdr *genlmsg_hdr(struct nlmsghdr *nlh) { return nlmsg_data(nlh); } /** * Return length of message payload including user header * @arg gnlh Generic Netlink message header * * @see genlmsg_data() * * @return Length of user payload including an eventual user header in * number of bytes. */ int genlmsg_len(const struct genlmsghdr *gnlh) { const struct nlmsghdr *nlh; nlh = (const struct nlmsghdr *)((const unsigned char *) gnlh - NLMSG_HDRLEN); return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN); } /** * Return pointer to user header * @arg gnlh Generic Netlink message header * * Calculates the pointer to the user header based on the pointer to * the Generic Netlink message header. * * @return Pointer to the user header */ void *genlmsg_user_hdr(const struct genlmsghdr *gnlh) { return genlmsg_data(gnlh); } /** * Return pointer to user data * @arg gnlh Generic netlink message header * @arg hdrlen Length of user header * * Calculates the pointer to the user data based on the pointer to * the Generic Netlink message header. * * @see genlmsg_user_datalen() * * @return Pointer to the user data */ void *genlmsg_user_data(const struct genlmsghdr *gnlh, const int hdrlen) { return genlmsg_user_hdr(gnlh) + NLMSG_ALIGN(hdrlen); } /** * Return length of user data * @arg gnlh Generic Netlink message header * @arg hdrlen Length of user header * * @see genlmsg_user_data() * * @return Length of user data in bytes */ int genlmsg_user_datalen(const struct genlmsghdr *gnlh, const int hdrlen) { return genlmsg_len(gnlh) - NLMSG_ALIGN(hdrlen); } /** * Return pointer to message attributes * @arg gnlh Generic Netlink message header * @arg hdrlen Length of user header * * @see genlmsg_attrlen() * * @return Pointer to the start of the message's attributes section. */ struct nlattr *genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen) { return genlmsg_user_data(gnlh, hdrlen); } /** * Return length of message attributes * @arg gnlh Generic Netlink message header * @arg hdrlen Length of user header * * @see genlmsg_attrdata() * * @return Length of the message section containing attributes in number * of bytes. */ int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen) { return genlmsg_len(gnlh) - NLMSG_ALIGN(hdrlen); } /** @} */ /** * @name Message Construction * @{ */ /** * Add Generic Netlink headers to Netlink message * @arg msg Netlink message object * @arg port Netlink port or NL_AUTO_PORT * @arg seq Sequence number of message or NL_AUTO_SEQ * @arg family Numeric family identifier * @arg hdrlen Length of user header * @arg flags Additional Netlink message flags (optional) * @arg cmd Numeric command identifier * @arg version Interface version * * Calls nlmsg_put() on the specified message object to reserve space for * the Netlink header, the Generic Netlink header, and a user header of * specified length. Fills out the header fields with the specified * parameters. * * @par Example: * @code * struct nl_msg *msg; * struct my_hdr *user_hdr; * * if (!(msg = nlmsg_alloc())) * // ERROR * * user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, family_id, * sizeof(struct my_hdr), 0, MY_CMD_FOO, 0); * if (!user_hdr) * // ERROR * @endcode * * @see nlmsg_put() * * Returns Pointer to user header or NULL if an error occurred. */ void *genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) { struct nlmsghdr *nlh; struct genlmsghdr hdr = { .cmd = cmd, .version = version, }; nlh = nlmsg_put(msg, port, seq, family, GENL_HDRLEN + hdrlen, flags); if (nlh == NULL) return NULL; memcpy(nlmsg_data(nlh), &hdr, sizeof(hdr)); NL_DBG(2, "msg %p: Added generic netlink header cmd=%d version=%d\n", msg, cmd, version); return nlmsg_data(nlh) + GENL_HDRLEN; } /** @} */ /** * @name Deprecated * @{ */ /** * Return pointer to message payload * @arg gnlh Generic Netlink message header * * @deprecated This function has been deprecated due to inability to specify * the length of the user header. Use genlmsg_user_hdr() * respectively genlmsg_user_data(). * * @return Pointer to payload section */ void *genlmsg_data(const struct genlmsghdr *gnlh) { return ((unsigned char *) gnlh + GENL_HDRLEN); } /** @} */ /** @} */ libnl-3.2.29/lib/socket.c0000644000175000017500000005375613023014600012037 00000000000000/* * lib/socket.c Netlink Socket * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup core_types * @defgroup socket Socket * * Representation of a netlink socket * * Related sections in the development guide: * - @core_doc{core_sockets, Netlink Sockets} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include "defs.h" #include "sys/socket.h" #include #include #include #include #include #include #include #include static int default_cb = NL_CB_DEFAULT; static void __init init_default_cb(void) { char *nlcb; if ((nlcb = getenv("NLCB"))) { if (!strcasecmp(nlcb, "default")) default_cb = NL_CB_DEFAULT; else if (!strcasecmp(nlcb, "verbose")) default_cb = NL_CB_VERBOSE; else if (!strcasecmp(nlcb, "debug")) default_cb = NL_CB_DEBUG; else { fprintf(stderr, "Unknown value for NLCB, valid values: " "{default | verbose | debug}\n"); } } } static uint32_t used_ports_map[32]; static NL_RW_LOCK(port_map_lock); static uint32_t generate_local_port(void) { int i, j, n, m; static uint16_t idx_state = 0; uint32_t pid = getpid() & 0x3FFFFF; nl_write_lock(&port_map_lock); if (idx_state == 0) { uint32_t t = time(NULL); /* from time to time (on average each 2^15 calls), the idx_state will * be zero again. No problem, just "seed" anew with time(). */ idx_state = t ^ (t >> 16) ^ 0x3047; } else idx_state = idx_state + 20011; /* add prime number */ i = idx_state >> 5; n = idx_state; for (j = 0; j < 32; j++) { /* walk the index somewhat randomized, with always leaving the block * #0 as last. The reason is that libnl-1 will start at block #0, * so just leave the first 32 ports preferably for libnl-1 owned sockets * (this is relevant only if the applications ends up using both versions * of the library and doesn't hurt otherwise). */ if (j == 31) i = 0; else i = (((i-1) + 7) % 31) + 1; if (used_ports_map[i] == 0xFFFFFFFF) continue; for (m = 0; m < 32; m++) { n = (n + 13) % 32; if (1UL & (used_ports_map[i] >> n)) continue; used_ports_map[i] |= (1UL << n); n += (i * 32); /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit * to, i.e. 1024 unique ports per application. */ nl_write_unlock(&port_map_lock); /* ensure we don't return zero. */ pid = pid + (((uint32_t)n) << 22); return pid ? pid : 1024; } } nl_write_unlock(&port_map_lock); return 0; } static void release_local_port(uint32_t port) { int nr; uint32_t mask; BUG_ON(port == 0); nr = port >> 22; mask = 1UL << (nr % 32); nr /= 32; nl_write_lock(&port_map_lock); BUG_ON((used_ports_map[nr] & mask) != mask); used_ports_map[nr] &= ~mask; nl_write_unlock(&port_map_lock); } /** \cond skip */ void _nl_socket_used_ports_release_all(const uint32_t *used_ports) { int i; for (i = 0; i < 32; i++) { if (used_ports[i] != 0) { nl_write_lock(&port_map_lock); for (; i < 32; i++) { BUG_ON((used_ports_map[i] & used_ports[i]) != used_ports[i]); used_ports_map[i] &= ~(used_ports[i]); } nl_write_unlock(&port_map_lock); return; } } } void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port) { int nr; int32_t mask; nr = port >> 22; mask = 1UL << (nr % 32); nr /= 32; /* BUG_ON(port == 0 || (getpid() & 0x3FFFFF) != (port & 0x3FFFFF)); BUG_ON(used_ports[nr] & mask); */ used_ports[nr] |= mask; } /** \endcond */ /** * @name Allocation * @{ */ static struct nl_sock *__alloc_socket(struct nl_cb *cb) { struct nl_sock *sk; sk = calloc(1, sizeof(*sk)); if (!sk) return NULL; sk->s_fd = -1; sk->s_cb = nl_cb_get(cb); sk->s_local.nl_family = AF_NETLINK; sk->s_peer.nl_family = AF_NETLINK; sk->s_seq_expect = sk->s_seq_next = time(NULL); /* the port is 0 (unspecified), meaning NL_OWN_PORT */ sk->s_flags = NL_OWN_PORT; return sk; } /** * Allocate new netlink socket * * @return Newly allocated netlink socket or NULL. */ struct nl_sock *nl_socket_alloc(void) { struct nl_cb *cb; struct nl_sock *sk; cb = nl_cb_alloc(default_cb); if (!cb) return NULL; /* will increment cb reference count on success */ sk = __alloc_socket(cb); nl_cb_put(cb); return sk; } /** * Allocate new socket with custom callbacks * @arg cb Callback handler * * The reference to the callback handler is taken into account * automatically, it is released again upon calling nl_socket_free(). * *@return Newly allocted socket handle or NULL. */ struct nl_sock *nl_socket_alloc_cb(struct nl_cb *cb) { if (cb == NULL) BUG(); return __alloc_socket(cb); } /** * Free a netlink socket. * @arg sk Netlink socket. */ void nl_socket_free(struct nl_sock *sk) { if (!sk) return; if (sk->s_fd >= 0) close(sk->s_fd); if (!(sk->s_flags & NL_OWN_PORT)) release_local_port(sk->s_local.nl_pid); nl_cb_put(sk->s_cb); free(sk); } /** @} */ /** * @name Sequence Numbers * @{ */ static int noop_seq_check(struct nl_msg *msg, void *arg) { return NL_OK; } /** * Disable sequence number checking. * @arg sk Netlink socket. * * Disables checking of sequence numbers on the netlink socket This is * required to allow messages to be processed which were not requested by * a preceding request message, e.g. netlink events. * * @note This function modifies the NL_CB_SEQ_CHECK configuration in * the callback handle associated with the socket. */ void nl_socket_disable_seq_check(struct nl_sock *sk) { nl_cb_set(sk->s_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, noop_seq_check, NULL); } /** * Use next sequence number * @arg sk Netlink socket. * * Uses the next available sequence number and increases the counter * by one for subsequent calls. * * @return Unique serial sequence number */ unsigned int nl_socket_use_seq(struct nl_sock *sk) { return sk->s_seq_next++; } /** * Disable automatic request for ACK * @arg sk Netlink socket. * * The default behaviour of a socket is to request an ACK for * each message sent to allow for the caller to synchronize to * the completion of the netlink operation. This function * disables this behaviour and will result in requests being * sent which will not have the NLM_F_ACK flag set automatically. * However, it is still possible for the caller to set the * NLM_F_ACK flag explicitely. */ void nl_socket_disable_auto_ack(struct nl_sock *sk) { sk->s_flags |= NL_NO_AUTO_ACK; } /** * Enable automatic request for ACK (default) * @arg sk Netlink socket. * @see nl_socket_disable_auto_ack */ void nl_socket_enable_auto_ack(struct nl_sock *sk) { sk->s_flags &= ~NL_NO_AUTO_ACK; } /** @} */ /** \cond skip */ int _nl_socket_is_local_port_unspecified(struct nl_sock *sk) { return (sk->s_local.nl_pid == 0); } uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other) { uint32_t port; /* reset the port to generate_local_port(), but do not release * the previously generated port. */ if (generate_other) port = generate_local_port(); else port = 0; sk->s_local.nl_pid = port; if (port == 0) { /* failed to find an unsed port. Restore the socket to have an * unspecified port. */ sk->s_flags |= NL_OWN_PORT; } else sk->s_flags &= ~NL_OWN_PORT; return port; } /** \endcond */ /** * @name Source Idenficiation * @{ */ uint32_t nl_socket_get_local_port(const struct nl_sock *sk) { if (sk->s_local.nl_pid == 0) { struct nl_sock *sk_mutable = (struct nl_sock *) sk; /* modify the const argument sk. This is justified, because * nobody ever saw the local_port from externally. So, we * initilize it on first use. * * Note that this also means that you cannot call this function * from multiple threads without synchronization. But nl_sock * is not automatically threadsafe anyway, so the user is not * allowed to do that. */ sk_mutable->s_local.nl_pid = generate_local_port(); if (sk_mutable->s_local.nl_pid == 0) { /* could not generate a local port. Assign UINT32_MAX to preserve * backward compatibility. A user who cares can clear that anyway * with nl_socket_set_local_port(). */ sk_mutable->s_local.nl_pid = UINT32_MAX; sk_mutable->s_flags |= NL_OWN_PORT; } else sk_mutable->s_flags &= ~NL_OWN_PORT; } return sk->s_local.nl_pid; } /** * Set local port of socket * @arg sk Netlink socket. * @arg port Local port identifier * * Assigns a local port identifier to the socket. * * If port is 0, the port is reset to 'unspecified' as it is after newly * calling nl_socket_alloc(). * Unspecified means, that the port will be generated automatically later * on first use (either on nl_socket_get_local_port() or nl_connect()). */ void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port) { if (!(sk->s_flags & NL_OWN_PORT)) release_local_port(sk->s_local.nl_pid); sk->s_flags |= NL_OWN_PORT; sk->s_local.nl_pid = port; } /** @} */ /** * @name Group Subscriptions * @{ */ /** * Join groups * @arg sk Netlink socket * @arg group Group identifier * * Joins the specified groups using the modern socket option which * is available since kernel version 2.6.14. It allows joining an * almost arbitary number of groups without limitation. The list * of groups has to be terminated by 0 (%NFNLGRP_NONE). * * Make sure to use the correct group definitions as the older * bitmask definitions for nl_join_groups() are likely to still * be present for backward compatibility reasons. * * @return 0 on sucess or a negative error code. */ int nl_socket_add_memberships(struct nl_sock *sk, int group, ...) { int err; va_list ap; if (sk->s_fd == -1) return -NLE_BAD_SOCK; va_start(ap, group); while (group != 0) { if (group < 0) { va_end(ap); return -NLE_INVAL; } err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group)); if (err < 0) { va_end(ap); NL_DBG(4, "nl_socket_add_memberships(%p): setsockopt() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } group = va_arg(ap, int); } va_end(ap); return 0; } int nl_socket_add_membership(struct nl_sock *sk, int group) { return nl_socket_add_memberships(sk, group, 0); } /** * Leave groups * @arg sk Netlink socket * @arg group Group identifier * * Leaves the specified groups using the modern socket option * which is available since kernel version 2.6.14. The list of groups * has to terminated by 0 (%NFNLGRP_NONE). * * @see nl_socket_add_membership * @return 0 on success or a negative error code. */ int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...) { int err; va_list ap; if (sk->s_fd == -1) return -NLE_BAD_SOCK; va_start(ap, group); while (group != 0) { if (group < 0) { va_end(ap); return -NLE_INVAL; } err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, &group, sizeof(group)); if (err < 0) { va_end(ap); NL_DBG(4, "nl_socket_drop_memberships(%p): setsockopt() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } group = va_arg(ap, int); } va_end(ap); return 0; } int nl_socket_drop_membership(struct nl_sock *sk, int group) { return nl_socket_drop_memberships(sk, group, 0); } /** * Join multicast groups (deprecated) * @arg sk Netlink socket. * @arg groups Bitmask of groups to join. * * This function defines the old way of joining multicast group which * has to be done prior to calling nl_connect(). It works on any kernel * version but is very limited as only 32 groups can be joined. */ void nl_join_groups(struct nl_sock *sk, int groups) { sk->s_local.nl_groups |= groups; } /** @} */ /** * @name Peer Identfication * @{ */ uint32_t nl_socket_get_peer_port(const struct nl_sock *sk) { return sk->s_peer.nl_pid; } void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port) { sk->s_peer.nl_pid = port; } uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk) { return sk->s_peer.nl_groups; } void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups) { sk->s_peer.nl_groups = groups; } /** @} */ /** * @name File Descriptor * @{ */ /** * Return the file descriptor of the backing socket * @arg sk Netlink socket * * Only valid after calling nl_connect() to create and bind the respective * socket. * * @return File descriptor or -1 if not available. */ int nl_socket_get_fd(const struct nl_sock *sk) { return sk->s_fd; } /** * Set the socket file descriptor externally which initializes the * socket similar to nl_connect(). * * @arg sk Netlink socket (required) * @arg protocol The socket protocol (optional). Linux 2.6.32 supports * the socket option SO_PROTOCOL. In this case, you can set * protocol to a negative value and let it autodetect. * If you set it to a non-negative value, the detected protocol * must match the one provided. * To support older kernels, you must specify the protocol. * @arg fd Socket file descriptor to use (required) * * Set the socket file descriptor. @fd must be valid and bind'ed. * * This is an alternative to nl_connect(). nl_connect() creates, binds and * sets the socket. With this function you can set the socket to an externally * created file descriptor. * * @see nl_connect() * * @return 0 on success or a negative error code. On error, @fd is not closed but * possibly unusable. * * @retval -NLE_BAD_SOCK Netlink socket is already connected * @retval -NLE_INVAL Socket is of unexpected type */ int nl_socket_set_fd(struct nl_sock *sk, int protocol, int fd) { int err = 0; socklen_t addrlen; struct sockaddr_nl local = { 0 }; int so_type = -1, so_protocol = -1; if (sk->s_fd != -1) return -NLE_BAD_SOCK; if (fd < 0) return -NLE_INVAL; addrlen = sizeof(local); err = getsockname(fd, (struct sockaddr *) &local, &addrlen); if (err < 0) { NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockname() failed with %d (%s)\n", sk, fd, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } if (addrlen != sizeof(local)) return -NLE_INVAL; if (local.nl_family != AF_NETLINK) { NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockname() returned family %d instead of %d (AF_NETLINK)\n", sk, fd, local.nl_family, AF_NETLINK); return -NLE_INVAL; } addrlen = sizeof(so_type); err = getsockopt(fd, SOL_SOCKET, SO_TYPE, &so_type, &addrlen); if (err < 0) { NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() for SO_TYPE failed with %d (%s)\n", sk, fd, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } if (addrlen != sizeof(so_type)) return -NLE_INVAL; if (so_type != SOCK_RAW) { NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() returned SO_TYPE %d instead of %d (SOCK_RAW)\n", sk, fd, so_type, SOCK_RAW); return -NLE_INVAL; } #if SO_PROTOCOL addrlen = sizeof(so_protocol); err = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &so_protocol, &addrlen); if (err < 0) { if (errno == ENOPROTOOPT) goto no_so_protocol; NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() for SO_PROTOCOL failed with %d (%s)\n", sk, fd, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } if (addrlen != sizeof(so_protocol)) return -NLE_INVAL; if (protocol >= 0 && protocol != so_protocol) { NL_DBG(4, "nl_socket_set_fd(%p,%d): getsockopt() for SO_PROTOCOL returned %d instead of %d\n", sk, fd, so_protocol, protocol); return -NLE_INVAL; } if (0) #endif { no_so_protocol: if (protocol < 0) { NL_DBG(4, "nl_socket_set_fd(%p,%d): unknown protocol and unable to detect it via SO_PROTOCOL socket option\n", sk, fd); return -NLE_INVAL; } so_protocol = protocol; } nl_socket_set_local_port (sk, local.nl_pid); sk->s_local = local; sk->s_fd = fd; sk->s_proto = so_protocol; return 0; } /** * Set file descriptor of socket to non-blocking state * @arg sk Netlink socket. * * @return 0 on success or a negative error code. */ int nl_socket_set_nonblocking(const struct nl_sock *sk) { if (sk->s_fd == -1) return -NLE_BAD_SOCK; if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0) { NL_DBG(4, "nl_socket_set_nonblocking(%p): fcntl() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } return 0; } /** * Enable use of MSG_PEEK when reading from socket * @arg sk Netlink socket. * * See also NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT capability */ void nl_socket_enable_msg_peek(struct nl_sock *sk) { sk->s_flags |= (NL_MSG_PEEK | NL_MSG_PEEK_EXPLICIT); } /** * Disable use of MSG_PEEK when reading from socket * @arg sk Netlink socket. * * See also NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT capability */ void nl_socket_disable_msg_peek(struct nl_sock *sk) { sk->s_flags |= NL_MSG_PEEK_EXPLICIT; sk->s_flags &= ~NL_MSG_PEEK; } /** @} */ /** * @name Callback Handler * @{ */ struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk) { return nl_cb_get(sk->s_cb); } void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb) { if (cb == NULL) BUG(); nl_cb_put(sk->s_cb); sk->s_cb = nl_cb_get(cb); } /** * Modify the callback handler associated with the socket * @arg sk Netlink socket. * @arg type which type callback to set * @arg kind kind of callback * @arg func callback function * @arg arg argument to be passed to callback function * * @see nl_cb_set */ int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg) { return nl_cb_set(sk->s_cb, type, kind, func, arg); } /** * Modify the error callback handler associated with the socket * @arg sk Netlink socket. * @arg kind kind of callback * @arg func callback function * @arg arg argument to be passed to callback function * * @see nl_cb_err */ int nl_socket_modify_err_cb(struct nl_sock *sk, enum nl_cb_kind kind, nl_recvmsg_err_cb_t func, void *arg) { return nl_cb_err(sk->s_cb, kind, func, arg); } /** @} */ /** * @name Utilities * @{ */ /** * Set socket buffer size of netlink socket. * @arg sk Netlink socket. * @arg rxbuf New receive socket buffer size in bytes. * @arg txbuf New transmit socket buffer size in bytes. * * Sets the socket buffer size of a netlink socket to the specified * values \c rxbuf and \c txbuf. Providing a value of \c 0 assumes a * good default value. * * @note It is not required to call this function prior to nl_connect(). * @return 0 on sucess or a negative error code. */ int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf) { int err; if (rxbuf <= 0) rxbuf = 32768; if (txbuf <= 0) txbuf = 32768; if (sk->s_fd == -1) return -NLE_BAD_SOCK; err = setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF, &txbuf, sizeof(txbuf)); if (err < 0) { NL_DBG(4, "nl_socket_set_buffer_size(%p): setsockopt() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } err = setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF, &rxbuf, sizeof(rxbuf)); if (err < 0) { NL_DBG(4, "nl_socket_set_buffer_size(%p): setsockopt() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } return 0; } /** * Set default message buffer size of netlink socket. * @arg sk Netlink socket. * @arg bufsize Default message buffer size in bytes. * * Sets the default message buffer size to the specified length in bytes. * The default message buffer size limits the maximum message size the * socket will be able to receive. It is generally recommneded to specify * a buffer size no less than the size of a memory page. * * Setting the @bufsize to zero means to use a default of 4 times getpagesize(). * * When MSG_PEEK is enabled, the buffer size is used for the initial choice * of the buffer while peeking. It still makes sense to choose an optimal value * to avoid realloc(). * * When MSG_PEEK is disabled, the buffer size is important because a too small * size will lead to failure of receiving the message via nl_recvmsgs(). * * By default, MSG_PEEK is enabled unless the user calls either nl_socket_disable_msg_peek()/ * nl_socket_enable_msg_peek() or sets the message buffer size to a positive value. * See capability NL_CAPABILITY_NL_RECVMSGS_PEEK_BY_DEFAULT for that. * * @return 0 on success or a negative error code. */ int nl_socket_set_msg_buf_size(struct nl_sock *sk, size_t bufsize) { sk->s_bufsize = bufsize; return 0; } /** * Get default message buffer size of netlink socket. * @arg sk Netlink socket. * * @return Size of default message buffer. */ size_t nl_socket_get_msg_buf_size(struct nl_sock *sk) { return sk->s_bufsize; } /** * Enable/disable credential passing on netlink socket. * @arg sk Netlink socket. * @arg state New state (0 - disabled, 1 - enabled) * * @return 0 on success or a negative error code */ int nl_socket_set_passcred(struct nl_sock *sk, int state) { int err; if (sk->s_fd == -1) return -NLE_BAD_SOCK; err = setsockopt(sk->s_fd, SOL_SOCKET, SO_PASSCRED, &state, sizeof(state)); if (err < 0) { NL_DBG(4, "nl_socket_set_passcred(%p): setsockopt() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } if (state) sk->s_flags |= NL_SOCK_PASSCRED; else sk->s_flags &= ~NL_SOCK_PASSCRED; return 0; } /** * Enable/disable receival of additional packet information * @arg sk Netlink socket. * @arg state New state (0 - disabled, 1 - enabled) * * @return 0 on success or a negative error code */ int nl_socket_recv_pktinfo(struct nl_sock *sk, int state) { int err; if (sk->s_fd == -1) return -NLE_BAD_SOCK; err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_PKTINFO, &state, sizeof(state)); if (err < 0) { NL_DBG(4, "nl_socket_recv_pktinfo(%p): setsockopt() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } return 0; } /** @} */ /** @} */ libnl-3.2.29/lib/xfrm/0000755000175000017500000000000013031473756011443 500000000000000libnl-3.2.29/lib/xfrm/sp.c0000644000175000017500000011416613023014600012136 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * @ingroup xfrmnl * @defgroup sp Security Policy * @brief */ #include #include #include #include #include #include #include #include /** @cond SKIP */ #define XFRM_SP_ATTR_SEL 0x01 #define XFRM_SP_ATTR_LTIME_CFG 0x02 #define XFRM_SP_ATTR_LTIME_CUR 0x04 #define XFRM_SP_ATTR_PRIO 0x08 #define XFRM_SP_ATTR_INDEX 0x10 #define XFRM_SP_ATTR_DIR 0x20 #define XFRM_SP_ATTR_ACTION 0x40 #define XFRM_SP_ATTR_FLAGS 0x80 #define XFRM_SP_ATTR_SHARE 0x100 #define XFRM_SP_ATTR_POLTYPE 0x200 #define XFRM_SP_ATTR_SECCTX 0x400 #define XFRM_SP_ATTR_TMPL 0x800 #define XFRM_SP_ATTR_MARK 0x1000 static struct nl_cache_ops xfrmnl_sp_ops; static struct nl_object_ops xfrm_sp_obj_ops; /** @endcond */ static void xfrm_sp_alloc_data(struct nl_object *c) { struct xfrmnl_sp* sp = nl_object_priv (c); if ((sp->sel = xfrmnl_sel_alloc ()) == NULL) return; if ((sp->lft = xfrmnl_ltime_cfg_alloc ()) == NULL) return; nl_init_list_head(&sp->usertmpl_list); return; } static void xfrm_sp_free_data(struct nl_object *c) { struct xfrmnl_sp* sp = nl_object_priv (c); struct xfrmnl_user_tmpl *utmpl, *tmp; if (sp == NULL) return; xfrmnl_sel_put (sp->sel); xfrmnl_ltime_cfg_put (sp->lft); if(sp->sec_ctx) { free (sp->sec_ctx); } nl_list_for_each_entry_safe(utmpl, tmp, &sp->usertmpl_list, utmpl_list) { xfrmnl_sp_remove_usertemplate (sp, utmpl); xfrmnl_user_tmpl_free (utmpl); } } static int xfrm_sp_clone(struct nl_object *_dst, struct nl_object *_src) { struct xfrmnl_sp* dst = nl_object_priv(_dst); struct xfrmnl_sp* src = nl_object_priv(_src); uint32_t len = 0; struct xfrmnl_user_tmpl *utmpl, *new; if (src->sel) if ((dst->sel = xfrmnl_sel_clone (src->sel)) == NULL) return -NLE_NOMEM; if (src->lft) if ((dst->lft = xfrmnl_ltime_cfg_clone (src->lft)) == NULL) return -NLE_NOMEM; if(src->sec_ctx) { len = sizeof (struct xfrmnl_user_sec_ctx) + src->sec_ctx->ctx_len; if ((dst->sec_ctx = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->sec_ctx, (void *)src->sec_ctx, len); } nl_init_list_head(&dst->usertmpl_list); nl_list_for_each_entry(utmpl, &src->usertmpl_list, utmpl_list) { new = xfrmnl_user_tmpl_clone (utmpl); if (!new) return -NLE_NOMEM; xfrmnl_sp_add_usertemplate(dst, new); } return 0; } static uint64_t xfrm_sp_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct xfrmnl_sp* a = (struct xfrmnl_sp *) _a; struct xfrmnl_sp* b = (struct xfrmnl_sp *) _b; struct xfrmnl_user_tmpl *tmpl_a, *tmpl_b; uint64_t diff = 0; #define XFRM_SP_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, XFRM_SP_ATTR_##ATTR, a, b, EXPR) diff |= XFRM_SP_DIFF(SEL, xfrmnl_sel_cmp(a->sel, b->sel)); diff |= XFRM_SP_DIFF(LTIME_CFG, xfrmnl_ltime_cfg_cmp(a->lft, b->lft)); diff |= XFRM_SP_DIFF(PRIO, a->priority != b->priority); diff |= XFRM_SP_DIFF(INDEX, a->index != b->index); diff |= XFRM_SP_DIFF(DIR, a->dir != b->dir); diff |= XFRM_SP_DIFF(ACTION, a->action != b->action); diff |= XFRM_SP_DIFF(FLAGS, a->flags != b->flags); diff |= XFRM_SP_DIFF(SHARE, a->share != b->share); diff |= XFRM_SP_DIFF(SECCTX,((a->sec_ctx->len != b->sec_ctx->len) || (a->sec_ctx->exttype != b->sec_ctx->exttype) || (a->sec_ctx->ctx_alg != b->sec_ctx->ctx_alg) || (a->sec_ctx->ctx_doi != b->sec_ctx->ctx_doi) || (a->sec_ctx->ctx_len != b->sec_ctx->ctx_len) || strcmp(a->sec_ctx->ctx, b->sec_ctx->ctx))); diff |= XFRM_SP_DIFF(POLTYPE,(a->uptype.type != b->uptype.type)); diff |= XFRM_SP_DIFF(TMPL,(a->nr_user_tmpl != b->nr_user_tmpl)); diff |= XFRM_SP_DIFF(MARK,(a->mark.m != b->mark.m) || (a->mark.v != b->mark.v)); /* Compare the templates */ nl_list_for_each_entry(tmpl_b, &b->usertmpl_list, utmpl_list) nl_list_for_each_entry(tmpl_a, &a->usertmpl_list, utmpl_list) diff |= xfrmnl_user_tmpl_cmp (tmpl_a, tmpl_b); #undef XFRM_SP_DIFF return diff; } /** * @name XFRM SP Attribute Translations * @{ */ static const struct trans_tbl sp_attrs[] = { __ADD(XFRM_SP_ATTR_SEL, selector), __ADD(XFRM_SP_ATTR_LTIME_CFG, lifetime_cfg), __ADD(XFRM_SP_ATTR_LTIME_CUR, lifetime_cur), __ADD(XFRM_SP_ATTR_PRIO, priority), __ADD(XFRM_SP_ATTR_INDEX, index), __ADD(XFRM_SP_ATTR_DIR, direction), __ADD(XFRM_SP_ATTR_ACTION, action), __ADD(XFRM_SP_ATTR_FLAGS, flags), __ADD(XFRM_SP_ATTR_SHARE, share), __ADD(XFRM_SP_ATTR_POLTYPE, policy_type), __ADD(XFRM_SP_ATTR_SECCTX, security_context), __ADD(XFRM_SP_ATTR_TMPL, user_template), __ADD(XFRM_SP_ATTR_MARK, mark), }; static char* xfrm_sp_attrs2str(int attrs, char *buf, size_t len) { return __flags2str (attrs, buf, len, sp_attrs, ARRAY_SIZE(sp_attrs)); } /** @} */ /** * @name XFRM SP Action Translations * @{ */ static const struct trans_tbl sa_actions[] = { __ADD(XFRM_POLICY_ALLOW, allow), __ADD(XFRM_POLICY_BLOCK, block), }; char* xfrmnl_sp_action2str(int action, char *buf, size_t len) { return __type2str (action, buf, len, sa_actions, ARRAY_SIZE(sa_actions)); } int xfrmnl_sp_str2action(const char *name) { return __str2type (name, sa_actions, ARRAY_SIZE(sa_actions)); } /** @} */ /** * @name XFRM SP Flags Translations * @{ */ static const struct trans_tbl sp_flags[] = { __ADD(XFRM_POLICY_LOCALOK, allow policy override by user), __ADD(XFRM_POLICY_ICMP, auto include ICMP in policy), }; char* xfrmnl_sp_flags2str(int flags, char *buf, size_t len) { return __flags2str (flags, buf, len, sp_flags, ARRAY_SIZE(sp_flags)); } int xfrmnl_sp_str2flag(const char *name) { return __str2flags(name, sp_flags, ARRAY_SIZE(sp_flags)); } /** @} */ /** * @name XFRM SP Type Translations * @{ */ static const struct trans_tbl sp_types[] = { __ADD(XFRM_POLICY_TYPE_MAIN, main), __ADD(XFRM_POLICY_TYPE_SUB, sub), __ADD(XFRM_POLICY_TYPE_MAX, max), __ADD(XFRM_POLICY_TYPE_ANY, any), }; char* xfrmnl_sp_type2str(int type, char *buf, size_t len) { return __type2str(type, buf, len, sp_types, ARRAY_SIZE(sp_types)); } int xfrmnl_sp_str2type(const char *name) { return __str2type(name, sp_types, ARRAY_SIZE(sp_types)); } /** @} */ /** * @name XFRM SP Direction Translations * @{ */ static const struct trans_tbl sp_dir[] = { __ADD(XFRM_POLICY_IN, in), __ADD(XFRM_POLICY_OUT, out), __ADD(XFRM_POLICY_FWD, fwd), __ADD(XFRM_POLICY_MASK, mask), }; char* xfrmnl_sp_dir2str(int dir, char *buf, size_t len) { return __type2str (dir, buf, len, sp_dir, ARRAY_SIZE(sp_dir)); } int xfrmnl_sp_str2dir(const char *name) { return __str2type (name, sp_dir, ARRAY_SIZE(sp_dir)); } int xfrmnl_sp_index2dir (unsigned int index) { return index & 0x7; } /** @} */ /** * @name XFRM SP Share Translations * @{ */ static const struct trans_tbl sp_share[] = { __ADD(XFRM_SHARE_ANY, any), __ADD(XFRM_SHARE_SESSION, session), __ADD(XFRM_SHARE_USER, user), __ADD(XFRM_SHARE_UNIQUE, unique), }; char* xfrmnl_sp_share2str(int share, char *buf, size_t len) { return __type2str (share, buf, len, sp_share, ARRAY_SIZE(sp_share)); } int xfrmnl_sp_str2share(const char *name) { return __str2type (name, sp_share, ARRAY_SIZE(sp_share)); } /** @} */ static void xfrm_sp_dump_line(struct nl_object *a, struct nl_dump_params *p) { struct xfrmnl_sp* sp = (struct xfrmnl_sp *) a; char dir[32], action[32], share[32], flags[32]; char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5]; time_t add_time, use_time; struct tm *add_time_tm, *use_time_tm; nl_addr2str(xfrmnl_sel_get_saddr (sp->sel), src, sizeof(src)); nl_addr2str (xfrmnl_sel_get_daddr (sp->sel), dst, sizeof (dst)); nl_af2str (xfrmnl_sel_get_family (sp->sel), dir, 32); nl_dump_line(p, "src %s dst %s family: %s\n", src, dst, dir); nl_dump_line (p, "src port/mask: %d/%d dst port/mask: %d/%d\n", xfrmnl_sel_get_dport (sp->sel), xfrmnl_sel_get_dportmask (sp->sel), xfrmnl_sel_get_sport (sp->sel), xfrmnl_sel_get_sportmask (sp->sel)); nl_dump_line (p, "protocol: %s ifindex: %u uid: %u\n", nl_ip_proto2str (xfrmnl_sel_get_proto (sp->sel), dir, sizeof(dir)), xfrmnl_sel_get_ifindex (sp->sel), xfrmnl_sel_get_userid (sp->sel)); xfrmnl_sp_dir2str (sp->dir, dir, 32); xfrmnl_sp_action2str (sp->action, action, 32); xfrmnl_sp_share2str (sp->share, share, 32); xfrmnl_sp_flags2str (sp->flags, flags, 32); nl_dump_line(p, "\tdir: %s action: %s index: %u priority: %u share: %s flags: %s(0x%x) \n", dir, action, sp->index, sp->priority, share, flags, sp->flags); nl_dump_line(p, "\tlifetime configuration: \n"); if (sp->lft->soft_byte_limit == XFRM_INF) sprintf (dir, "INF"); else sprintf (dir, "%" PRIu64, sp->lft->soft_byte_limit); if (sp->lft->soft_packet_limit == XFRM_INF) sprintf (action, "INF"); else sprintf (action, "%" PRIu64, sp->lft->soft_packet_limit); if (sp->lft->hard_byte_limit == XFRM_INF) sprintf (flags, "INF"); else sprintf (flags, "%" PRIu64, sp->lft->hard_byte_limit); if (sp->lft->hard_packet_limit == XFRM_INF) sprintf (share, "INF"); else sprintf (share, "%" PRIu64, sp->lft->hard_packet_limit); nl_dump_line(p, "\t\tsoft limit: %s (bytes), %s (packets) \n", dir, action); nl_dump_line(p, "\t\thard limit: %s (bytes), %s (packets) \n", flags, share); nl_dump_line(p, "\t\tsoft add_time: %llu (seconds), soft use_time: %llu (seconds) \n", sp->lft->soft_add_expires_seconds, sp->lft->soft_use_expires_seconds); nl_dump_line(p, "\t\thard add_time: %llu (seconds), hard use_time: %llu (seconds) \n", sp->lft->hard_add_expires_seconds, sp->lft->hard_use_expires_seconds); nl_dump_line(p, "\tlifetime current: \n"); nl_dump_line(p, "\t\t%llu bytes, %llu packets\n", sp->curlft.bytes, sp->curlft.packets); if (sp->curlft.add_time != 0) { add_time = sp->curlft.add_time; add_time_tm = gmtime (&add_time); strftime (dst, INET6_ADDRSTRLEN+5, "%Y-%m-%d %H-%M-%S", add_time_tm); } else { sprintf (dst, "%s", "-"); } if (sp->curlft.use_time != 0) { use_time = sp->curlft.use_time; use_time_tm = gmtime (&use_time); strftime (src, INET6_ADDRSTRLEN+5, "%Y-%m-%d %H-%M-%S", use_time_tm); } else { sprintf (src, "%s", "-"); } nl_dump_line(p, "\t\tadd_time: %s, use_time: %s\n", dst, src); if (sp->ce_mask & XFRM_SP_ATTR_SECCTX) { nl_dump_line(p, "\tUser security context: \n"); nl_dump_line(p, "\t\tlen: %d exttype: %d Algo: %d DOI: %d ctxlen: %d\n", sp->sec_ctx->len, sp->sec_ctx->exttype, sp->sec_ctx->ctx_alg, sp->sec_ctx->ctx_doi, sp->sec_ctx->ctx_len); nl_dump_line (p, "\t\tctx: %s \n", sp->sec_ctx->ctx); } xfrmnl_sp_type2str (sp->uptype.type, flags, 32); if (sp->ce_mask & XFRM_SP_ATTR_POLTYPE) nl_dump_line(p, "\tUser policy type: %s\n", flags); if (sp->ce_mask & XFRM_SP_ATTR_TMPL) { struct xfrmnl_user_tmpl* utmpl; nl_dump_line(p, "\tUser template: \n"); nl_list_for_each_entry(utmpl, &sp->usertmpl_list, utmpl_list) xfrmnl_user_tmpl_dump (utmpl, p); } if (sp->ce_mask & XFRM_SP_ATTR_MARK) nl_dump_line(p, "\tMark mask: 0x%x Mark value: 0x%x\n", sp->mark.m, sp->mark.v); nl_dump(p, "\n"); } static void xfrm_sp_dump_details(struct nl_object *a, struct nl_dump_params *p) { xfrm_sp_dump_line(a, p); } static void xfrm_sp_dump_stats(struct nl_object *a, struct nl_dump_params *p) { xfrm_sp_dump_details(a, p); return; } /** * @name XFRM SP Object Allocation/Freeage * @{ */ struct xfrmnl_sp* xfrmnl_sp_alloc(void) { return (struct xfrmnl_sp*) nl_object_alloc(&xfrm_sp_obj_ops); } void xfrmnl_sp_put(struct xfrmnl_sp* sp) { nl_object_put((struct nl_object *) sp); } /** @} */ /** * @name SP Cache Managament * @{ */ /** * Build a SP cache including all SPs currently configured in the kernel. * @arg sock Netlink socket. * @arg result Pointer to store resulting cache. * * Allocates a new SP cache, initializes it properly and updates it * to include all SPs currently configured in the kernel. * * @return 0 on success or a negative error code. */ int xfrmnl_sp_alloc_cache(struct nl_sock *sock, struct nl_cache **result) { return nl_cache_alloc_and_fill(&xfrmnl_sp_ops, sock, result); } /** * Look up a SP by policy id and direction * @arg cache SP cache * @arg index Policy Id * @arg dir direction * @return sp handle or NULL if no match was found. */ struct xfrmnl_sp* xfrmnl_sp_get(struct nl_cache* cache, unsigned int index, unsigned int dir) { struct xfrmnl_sp *sp; //nl_list_for_each_entry(sp, &cache->c_items, ce_list) { for (sp = (struct xfrmnl_sp*)nl_cache_get_first (cache); sp != NULL; sp = (struct xfrmnl_sp*)nl_cache_get_next ((struct nl_object*)sp)) { if (sp->index == index && sp->dir == dir) { nl_object_get((struct nl_object *) sp); return sp; } } return NULL; } /** @} */ static struct nla_policy xfrm_sp_policy[XFRMA_MAX+1] = { [XFRMA_POLICY] = { .minlen = sizeof(struct xfrm_userpolicy_info)}, [XFRMA_SEC_CTX] = { .minlen = sizeof(struct xfrm_sec_ctx) }, [XFRMA_TMPL] = { .minlen = sizeof(struct xfrm_user_tmpl) }, [XFRMA_POLICY_TYPE] = { .minlen = sizeof(struct xfrm_userpolicy_type)}, [XFRMA_MARK] = { .minlen = sizeof(struct xfrm_mark) }, }; static int xfrm_sp_request_update(struct nl_cache *c, struct nl_sock *h) { struct xfrm_userpolicy_id sp_id; memset (&sp_id, 0, sizeof (sp_id)); return nl_send_simple (h, XFRM_MSG_GETPOLICY, NLM_F_DUMP, &sp_id, sizeof (sp_id)); } int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result) { struct xfrmnl_sp *sp; struct nlattr *tb[XFRMA_MAX + 1]; struct xfrm_userpolicy_info *sp_info; int len, err; struct nl_addr* addr; sp = xfrmnl_sp_alloc(); if (!sp) { err = -NLE_NOMEM; goto errout; } sp->ce_msgtype = n->nlmsg_type; if (n->nlmsg_type == XFRM_MSG_DELPOLICY) { sp_info = (struct xfrm_userpolicy_info*)(nlmsg_data(n) + sizeof (struct xfrm_userpolicy_id) + NLA_HDRLEN); } else { sp_info = nlmsg_data(n); } err = nlmsg_parse(n, sizeof(struct xfrm_userpolicy_info), tb, XFRMA_MAX, xfrm_sp_policy); if (err < 0) { printf ("parse error: %d \n", err); goto errout; } if (sp_info->sel.family == AF_INET) addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.daddr.a4, sizeof (sp_info->sel.daddr.a4)); else addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.daddr.a6, sizeof (sp_info->sel.daddr.a6)); nl_addr_set_prefixlen (addr, sp_info->sel.prefixlen_d); xfrmnl_sel_set_daddr (sp->sel, addr); xfrmnl_sel_set_prefixlen_d (sp->sel, sp_info->sel.prefixlen_d); if (sp_info->sel.family == AF_INET) addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.saddr.a4, sizeof (sp_info->sel.saddr.a4)); else addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.saddr.a6, sizeof (sp_info->sel.saddr.a6)); nl_addr_set_prefixlen (addr, sp_info->sel.prefixlen_s); xfrmnl_sel_set_saddr (sp->sel, addr); xfrmnl_sel_set_prefixlen_s (sp->sel, sp_info->sel.prefixlen_s); xfrmnl_sel_set_dport (sp->sel, ntohs (sp_info->sel.dport)); xfrmnl_sel_set_dportmask (sp->sel, ntohs (sp_info->sel.dport_mask)); xfrmnl_sel_set_sport (sp->sel, ntohs (sp_info->sel.sport)); xfrmnl_sel_set_sportmask (sp->sel, ntohs (sp_info->sel.sport_mask)); xfrmnl_sel_set_family (sp->sel, sp_info->sel.family); xfrmnl_sel_set_proto (sp->sel, sp_info->sel.proto); xfrmnl_sel_set_ifindex (sp->sel, sp_info->sel.ifindex); xfrmnl_sel_set_userid (sp->sel, sp_info->sel.user); sp->ce_mask |= XFRM_SP_ATTR_SEL; sp->lft->soft_byte_limit = sp_info->lft.soft_byte_limit; sp->lft->hard_byte_limit = sp_info->lft.hard_byte_limit; sp->lft->soft_packet_limit = sp_info->lft.soft_packet_limit; sp->lft->hard_packet_limit = sp_info->lft.hard_packet_limit; sp->lft->soft_add_expires_seconds = sp_info->lft.soft_add_expires_seconds; sp->lft->hard_add_expires_seconds = sp_info->lft.hard_add_expires_seconds; sp->lft->soft_use_expires_seconds = sp_info->lft.soft_use_expires_seconds; sp->lft->hard_use_expires_seconds = sp_info->lft.hard_use_expires_seconds; sp->ce_mask |= XFRM_SP_ATTR_LTIME_CFG; sp->curlft.bytes = sp_info->curlft.bytes; sp->curlft.packets = sp_info->curlft.packets; sp->curlft.add_time = sp_info->curlft.add_time; sp->curlft.use_time = sp_info->curlft.use_time; sp->ce_mask |= XFRM_SP_ATTR_LTIME_CUR; sp->priority = sp_info->priority; sp->index = sp_info->index; sp->dir = sp_info->dir; sp->action = sp_info->action; sp->flags = sp_info->flags; sp->share = sp_info->share; sp->ce_mask |= (XFRM_SP_ATTR_PRIO | XFRM_SP_ATTR_INDEX | XFRM_SP_ATTR_DIR | XFRM_SP_ATTR_ACTION | XFRM_SP_ATTR_FLAGS | XFRM_SP_ATTR_SHARE); if (tb[XFRMA_SEC_CTX]) { struct xfrm_user_sec_ctx* ctx = nla_data(tb[XFRMA_SEC_CTX]); len = sizeof (struct xfrmnl_user_sec_ctx) + ctx->ctx_len; if ((sp->sec_ctx = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } memcpy ((void *)sp->sec_ctx, (void *)ctx, len); sp->ce_mask |= XFRM_SP_ATTR_SECCTX; } if (tb[XFRMA_POLICY_TYPE]) { struct xfrm_userpolicy_type* up = nla_data(tb[XFRMA_POLICY_TYPE]); memcpy ((void *)&sp->uptype, (void *)up, sizeof (struct xfrm_userpolicy_type)); sp->ce_mask |= XFRM_SP_ATTR_POLTYPE; } if (tb[XFRMA_TMPL]) { struct xfrm_user_tmpl* tmpl = nla_data(tb[XFRMA_TMPL]); struct xfrmnl_user_tmpl* sputmpl; uint32_t i; uint32_t num_tmpls = nla_len(tb[XFRMA_TMPL]) / sizeof (*tmpl); struct nl_addr* addr; for (i = 0; (i < num_tmpls) && (tmpl); i ++, tmpl++) { if ((sputmpl = xfrmnl_user_tmpl_alloc ()) == NULL) { err = -NLE_NOMEM; goto errout; } if (tmpl->family == AF_INET) addr = nl_addr_build(tmpl->family, &tmpl->id.daddr.a4, sizeof (tmpl->id.daddr.a4)); else addr = nl_addr_build(tmpl->family, &tmpl->id.daddr.a6, sizeof (tmpl->id.daddr.a6)); xfrmnl_user_tmpl_set_daddr (sputmpl, addr); xfrmnl_user_tmpl_set_spi (sputmpl, ntohl(tmpl->id.spi)); xfrmnl_user_tmpl_set_proto (sputmpl, tmpl->id.proto); xfrmnl_user_tmpl_set_family (sputmpl, tmpl->family); if (tmpl->family == AF_INET) addr = nl_addr_build(tmpl->family, &tmpl->saddr.a4, sizeof (tmpl->saddr.a4)); else addr = nl_addr_build(tmpl->family, &tmpl->saddr.a6, sizeof (tmpl->saddr.a6)); xfrmnl_user_tmpl_set_saddr (sputmpl, addr); xfrmnl_user_tmpl_set_reqid (sputmpl, tmpl->reqid); xfrmnl_user_tmpl_set_mode (sputmpl, tmpl->mode); xfrmnl_user_tmpl_set_share (sputmpl, tmpl->share); xfrmnl_user_tmpl_set_optional (sputmpl, tmpl->optional); xfrmnl_user_tmpl_set_aalgos (sputmpl, tmpl->aalgos); xfrmnl_user_tmpl_set_ealgos (sputmpl, tmpl->ealgos); xfrmnl_user_tmpl_set_calgos (sputmpl, tmpl->calgos); xfrmnl_sp_add_usertemplate (sp, sputmpl); sp->ce_mask |= XFRM_SP_ATTR_TMPL; } } if (tb[XFRMA_MARK]) { struct xfrm_mark* m = nla_data(tb[XFRMA_MARK]); sp->mark.m = m->m; sp->mark.v = m->v; sp->ce_mask |= XFRM_SP_ATTR_MARK; } *result = sp; return 0; errout: xfrmnl_sp_put(sp); return err; } static int xfrm_sp_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct xfrmnl_sp* sp; int err; if ((err = xfrmnl_sp_parse(n, &sp)) < 0) { printf ("received error: %d \n", err); return err; } err = pp->pp_cb((struct nl_object *) sp, pp); xfrmnl_sp_put(sp); return err; } /** * @name XFRM SP Get * @{ */ int xfrmnl_sp_build_get_request(unsigned int index, unsigned int dir, unsigned int mark_v, unsigned int mark_m, struct nl_msg **result) { struct nl_msg *msg; struct xfrm_userpolicy_id spid; struct xfrm_mark mark; memset(&spid, 0, sizeof(spid)); spid.index = index; spid.dir = dir; if (!(msg = nlmsg_alloc_simple(XFRM_MSG_GETPOLICY, 0))) return -NLE_NOMEM; if (nlmsg_append(msg, &spid, sizeof(spid), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if ((mark_m & mark_v) != 0) { memset(&mark, 0, sizeof(struct xfrm_mark)); mark.m = mark_m; mark.v = mark_v; NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrm_mark), &mark); } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } int xfrmnl_sp_get_kernel(struct nl_sock* sock, unsigned int index, unsigned int dir, unsigned int mark_v, unsigned int mark_m, struct xfrmnl_sp** result) { struct nl_msg *msg = NULL; struct nl_object *obj; int err; if ((err = xfrmnl_sp_build_get_request(index, dir, mark_m, mark_v, &msg)) < 0) return err; err = nl_send_auto(sock, msg); nlmsg_free(msg); if (err < 0) return err; if ((err = nl_pickup(sock, &xfrm_sp_msg_parser, &obj)) < 0) return err; /* We have used xfrm_sp_msg_parser(), object is definitely a xfrm ae */ *result = (struct xfrmnl_sp *) obj; /* If an object has been returned, we also need to wait for the ACK */ if (err == 0 && obj) nl_wait_for_ack(sock); return 0; } /** @} */ static int build_xfrm_sp_message(struct xfrmnl_sp *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg* msg; struct xfrm_userpolicy_info sp_info; uint32_t len; struct nl_addr* addr; if (!(tmpl->ce_mask & XFRM_SP_ATTR_INDEX) || !(tmpl->ce_mask & XFRM_SP_ATTR_DIR)) return -NLE_MISSING_ATTR; memset ((void*)&sp_info, 0, sizeof (sp_info)); if (tmpl->ce_mask & XFRM_SP_ATTR_SEL) { addr = xfrmnl_sel_get_daddr (tmpl->sel); memcpy ((void*)&sp_info.sel.daddr, (void*)nl_addr_get_binary_addr (addr), sizeof (uint8_t) * nl_addr_get_len (addr)); addr = xfrmnl_sel_get_saddr (tmpl->sel); memcpy ((void*)&sp_info.sel.saddr, (void*)nl_addr_get_binary_addr (addr), sizeof (uint8_t) * nl_addr_get_len (addr)); sp_info.sel.dport = htons (xfrmnl_sel_get_dport (tmpl->sel)); sp_info.sel.dport_mask = htons (xfrmnl_sel_get_dportmask (tmpl->sel)); sp_info.sel.sport = htons (xfrmnl_sel_get_sport (tmpl->sel)); sp_info.sel.sport_mask = htons (xfrmnl_sel_get_sportmask (tmpl->sel)); sp_info.sel.family = xfrmnl_sel_get_family (tmpl->sel); sp_info.sel.prefixlen_d = xfrmnl_sel_get_prefixlen_d (tmpl->sel); sp_info.sel.prefixlen_s = xfrmnl_sel_get_prefixlen_s (tmpl->sel); sp_info.sel.proto = xfrmnl_sel_get_proto (tmpl->sel); sp_info.sel.ifindex = xfrmnl_sel_get_ifindex (tmpl->sel); sp_info.sel.user = xfrmnl_sel_get_userid (tmpl->sel); } if (tmpl->ce_mask & XFRM_SP_ATTR_LTIME_CFG) { sp_info.lft.soft_byte_limit = xfrmnl_ltime_cfg_get_soft_bytelimit (tmpl->lft); sp_info.lft.hard_byte_limit = xfrmnl_ltime_cfg_get_hard_bytelimit (tmpl->lft); sp_info.lft.soft_packet_limit = xfrmnl_ltime_cfg_get_soft_packetlimit (tmpl->lft); sp_info.lft.hard_packet_limit = xfrmnl_ltime_cfg_get_hard_packetlimit (tmpl->lft); sp_info.lft.soft_add_expires_seconds = xfrmnl_ltime_cfg_get_soft_addexpires (tmpl->lft); sp_info.lft.hard_add_expires_seconds = xfrmnl_ltime_cfg_get_hard_addexpires (tmpl->lft); sp_info.lft.soft_use_expires_seconds = xfrmnl_ltime_cfg_get_soft_useexpires (tmpl->lft); sp_info.lft.hard_use_expires_seconds = xfrmnl_ltime_cfg_get_hard_useexpires (tmpl->lft); } //Skip current lifetime: cur lifetime can be updated only via AE if (tmpl->ce_mask & XFRM_SP_ATTR_PRIO) sp_info.priority = tmpl->priority; if (tmpl->ce_mask & XFRM_SP_ATTR_INDEX) sp_info.index = tmpl->index; if (tmpl->ce_mask & XFRM_SP_ATTR_DIR) sp_info.dir = tmpl->dir; if (tmpl->ce_mask & XFRM_SP_ATTR_ACTION) sp_info.action = tmpl->action; if (tmpl->ce_mask & XFRM_SP_ATTR_FLAGS) sp_info.flags = tmpl->flags; if (tmpl->ce_mask & XFRM_SP_ATTR_SHARE) sp_info.share = tmpl->share; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &sp_info, sizeof(sp_info), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tmpl->ce_mask & XFRM_SP_ATTR_SECCTX) { len = (sizeof (struct xfrm_user_sec_ctx)) + tmpl->sec_ctx->ctx_len; NLA_PUT (msg, XFRMA_SEC_CTX, len, tmpl->sec_ctx); } if (tmpl->ce_mask & XFRM_SP_ATTR_POLTYPE) { len = sizeof (struct xfrm_userpolicy_type); NLA_PUT (msg, XFRMA_POLICY_TYPE, len, &tmpl->uptype); } if (tmpl->ce_mask & XFRM_SP_ATTR_TMPL) { struct nlattr* tmpls; struct xfrmnl_user_tmpl* utmpl; struct nl_addr* addr; if (!(tmpls = nla_nest_start(msg, XFRMA_TMPL))) goto nla_put_failure; nl_list_for_each_entry(utmpl, &tmpl->usertmpl_list, utmpl_list) { struct xfrm_user_tmpl* tmpl; tmpl = nlmsg_reserve(msg, sizeof(*tmpl), NLMSG_ALIGNTO); if (!tmpl) goto nla_put_failure; addr = xfrmnl_user_tmpl_get_daddr (utmpl); memcpy ((void *)&tmpl->id.daddr, nl_addr_get_binary_addr (addr), nl_addr_get_len (addr)); tmpl->id.spi = htonl(xfrmnl_user_tmpl_get_spi (utmpl)); tmpl->id.proto = xfrmnl_user_tmpl_get_proto (utmpl); tmpl->family = xfrmnl_user_tmpl_get_family (utmpl); addr = xfrmnl_user_tmpl_get_saddr (utmpl); memcpy ((void *)&tmpl->saddr, nl_addr_get_binary_addr (addr), nl_addr_get_len (addr)); tmpl->reqid = xfrmnl_user_tmpl_get_reqid (utmpl); tmpl->mode = xfrmnl_user_tmpl_get_mode (utmpl); tmpl->share = xfrmnl_user_tmpl_get_share (utmpl); tmpl->optional = xfrmnl_user_tmpl_get_optional (utmpl); tmpl->aalgos = xfrmnl_user_tmpl_get_aalgos (utmpl); tmpl->ealgos = xfrmnl_user_tmpl_get_ealgos (utmpl); tmpl->calgos = xfrmnl_user_tmpl_get_calgos (utmpl); } nla_nest_end(msg, tmpls); } if (tmpl->ce_mask & XFRM_SP_ATTR_MARK) { NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrm_mark), &tmpl->mark); } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * @name XFRM SP Add * @{ */ int xfrmnl_sp_build_add_request(struct xfrmnl_sp* tmpl, int flags, struct nl_msg **result) { return build_xfrm_sp_message (tmpl, XFRM_MSG_NEWPOLICY, flags, result); } int xfrmnl_sp_add(struct nl_sock* sk, struct xfrmnl_sp* tmpl, int flags) { int err; struct nl_msg *msg; if ((err = xfrmnl_sp_build_add_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); } /** * @name XFRM SP Update * @{ */ int xfrmnl_sp_build_update_request(struct xfrmnl_sp* tmpl, int flags, struct nl_msg **result) { return build_xfrm_sp_message (tmpl, XFRM_MSG_UPDPOLICY, flags, result); } int xfrmnl_sp_update(struct nl_sock* sk, struct xfrmnl_sp* tmpl, int flags) { int err; struct nl_msg *msg; if ((err = xfrmnl_sp_build_update_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); } /** @} */ static int build_xfrm_sp_delete_message(struct xfrmnl_sp *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg* msg; struct xfrm_userpolicy_id spid; if (!(tmpl->ce_mask & XFRM_SP_ATTR_INDEX) || !(tmpl->ce_mask & XFRM_SP_ATTR_DIR)) return -NLE_MISSING_ATTR; memset(&spid, 0, sizeof(spid)); spid.index = tmpl->index; spid.dir = tmpl->dir; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &spid, sizeof(spid), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tmpl->ce_mask & XFRM_SP_ATTR_MARK) { NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrm_mark), &tmpl->mark); } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * @name XFRM SA Delete * @{ */ int xfrmnl_sp_build_delete_request(struct xfrmnl_sp* tmpl, int flags, struct nl_msg **result) { return build_xfrm_sp_delete_message (tmpl, XFRM_MSG_DELPOLICY, flags, result); } int xfrmnl_sp_delete(struct nl_sock* sk, struct xfrmnl_sp* tmpl, int flags) { int err; struct nl_msg *msg; if ((err = xfrmnl_sp_build_delete_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); } /** @} */ /** * @name Attributes * @{ */ struct xfrmnl_sel* xfrmnl_sp_get_sel (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_SEL) return sp->sel; else return NULL; } int xfrmnl_sp_set_sel (struct xfrmnl_sp* sp, struct xfrmnl_sel* sel) { /* Release any previously held selector object from the SP */ if (sp->sel) xfrmnl_sel_put (sp->sel); /* Increment ref count on new selector and save it in the SP */ xfrmnl_sel_get (sel); sp->sel = sel; sp->ce_mask |= XFRM_SP_ATTR_SEL; return 0; } struct xfrmnl_ltime_cfg* xfrmnl_sp_get_lifetime_cfg (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_LTIME_CFG) return sp->lft; else return NULL; } int xfrmnl_sp_set_lifetime_cfg (struct xfrmnl_sp* sp, struct xfrmnl_ltime_cfg* ltime) { /* Release any previously held lifetime cfg object from the SP */ if (sp->lft) xfrmnl_ltime_cfg_put (sp->lft); /* Increment ref count on new lifetime object and save it in the SP */ xfrmnl_ltime_cfg_get (ltime); sp->lft = ltime; sp->ce_mask |= XFRM_SP_ATTR_LTIME_CFG; return 0; } int xfrmnl_sp_get_curlifetime (struct xfrmnl_sp* sa, unsigned long long int* curr_bytes, unsigned long long int* curr_packets, unsigned long long int* curr_add_time, unsigned long long int* curr_use_time) { if (sa == NULL || curr_bytes == NULL || curr_packets == NULL || curr_add_time == NULL || curr_use_time == NULL) return -1; *curr_bytes = sa->curlft.bytes; *curr_packets = sa->curlft.packets; *curr_add_time = sa->curlft.add_time; *curr_use_time = sa->curlft.use_time; return 0; } int xfrmnl_sp_get_priority (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_PRIO) return sp->priority; else return -1; } int xfrmnl_sp_set_priority (struct xfrmnl_sp* sp, unsigned int prio) { sp->priority = prio; sp->ce_mask |= XFRM_SP_ATTR_PRIO; return 0; } int xfrmnl_sp_get_index (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_INDEX) return sp->index; else return -1; } int xfrmnl_sp_set_index (struct xfrmnl_sp* sp, unsigned int index) { sp->index = index; sp->ce_mask |= XFRM_SP_ATTR_INDEX; return 0; } int xfrmnl_sp_get_dir (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_DIR) return sp->dir; else return -1; } int xfrmnl_sp_set_dir (struct xfrmnl_sp* sp, unsigned int dir) { sp->dir = dir; sp->ce_mask |= XFRM_SP_ATTR_DIR; return 0; } int xfrmnl_sp_get_action (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_ACTION) return sp->action; else return -1; } int xfrmnl_sp_set_action (struct xfrmnl_sp* sp, unsigned int action) { sp->action = action; sp->ce_mask |= XFRM_SP_ATTR_ACTION; return 0; } int xfrmnl_sp_get_flags (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_FLAGS) return sp->flags; else return -1; } int xfrmnl_sp_set_flags (struct xfrmnl_sp* sp, unsigned int flags) { sp->flags = flags; sp->ce_mask |= XFRM_SP_ATTR_FLAGS; return 0; } int xfrmnl_sp_get_share (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_SHARE) return sp->share; else return -1; } int xfrmnl_sp_set_share (struct xfrmnl_sp* sp, unsigned int share) { sp->share = share; sp->ce_mask |= XFRM_SP_ATTR_SHARE; return 0; } int xfrmnl_sp_get_sec_ctx (struct xfrmnl_sp* sp, unsigned int* len, unsigned int* exttype, unsigned int* alg, unsigned int* doi, unsigned int* ctx_len, char* ctx_str) { if (sp->ce_mask & XFRM_SP_ATTR_SECCTX) { *len = sp->sec_ctx->len; *exttype= sp->sec_ctx->exttype; *alg = sp->sec_ctx->ctx_alg; *doi = sp->sec_ctx->ctx_doi; *ctx_len= sp->sec_ctx->ctx_len; memcpy ((void *)ctx_str, (void *)sp->sec_ctx->ctx, sizeof (uint8_t) * sp->sec_ctx->ctx_len); } else return -1; return 0; } int xfrmnl_sp_set_sec_ctx (struct xfrmnl_sp* sp, unsigned int len, unsigned int exttype, unsigned int alg, unsigned int doi, unsigned int ctx_len, char* ctx_str) { /* Free up the old context string and allocate new one */ if (sp->sec_ctx) free (sp->sec_ctx); if ((sp->sec_ctx = calloc (1, sizeof (struct xfrmnl_user_sec_ctx) + (sizeof (uint8_t) * ctx_len))) == NULL) return -1; /* Save the new info */ sp->sec_ctx->len = len; sp->sec_ctx->exttype = exttype; sp->sec_ctx->ctx_alg = alg; sp->sec_ctx->ctx_doi = doi; sp->sec_ctx->ctx_len = len; memcpy ((void *)sp->sec_ctx->ctx, (void *)ctx_str, sizeof (uint8_t) * ctx_len); sp->ce_mask |= XFRM_SP_ATTR_SECCTX; return 0; } int xfrmnl_sp_get_userpolicy_type (struct xfrmnl_sp* sp) { if (sp->ce_mask & XFRM_SP_ATTR_POLTYPE) return sp->uptype.type; else return -1; } int xfrmnl_sp_set_userpolicy_type (struct xfrmnl_sp* sp, unsigned int type) { sp->uptype.type = type; sp->ce_mask |= XFRM_SP_ATTR_POLTYPE; return 0; } void xfrmnl_sp_add_usertemplate(struct xfrmnl_sp *sp, struct xfrmnl_user_tmpl *utmpl) { nl_list_add_tail(&utmpl->utmpl_list, &sp->usertmpl_list); sp->nr_user_tmpl++; sp->ce_mask |= XFRM_SP_ATTR_TMPL; } void xfrmnl_sp_remove_usertemplate(struct xfrmnl_sp *sp, struct xfrmnl_user_tmpl *utmpl) { if (sp->ce_mask & XFRM_SP_ATTR_TMPL) { sp->nr_user_tmpl--; nl_list_del(&utmpl->utmpl_list); } } struct nl_list_head *xfrmnl_sp_get_usertemplates(struct xfrmnl_sp *sp) { if (sp->ce_mask & XFRM_SP_ATTR_TMPL) return &sp->usertmpl_list; return NULL; } int xfrmnl_sp_get_nusertemplates(struct xfrmnl_sp *sp) { if (sp->ce_mask & XFRM_SP_ATTR_TMPL) return sp->nr_user_tmpl; return 0; } void xfrmnl_sp_foreach_usertemplate(struct xfrmnl_sp *r, void (*cb)(struct xfrmnl_user_tmpl *, void *), void *arg) { struct xfrmnl_user_tmpl *utmpl; if (r->ce_mask & XFRM_SP_ATTR_TMPL) { nl_list_for_each_entry(utmpl, &r->usertmpl_list, utmpl_list) { cb(utmpl, arg); } } } struct xfrmnl_user_tmpl *xfrmnl_sp_usertemplate_n(struct xfrmnl_sp *r, int n) { struct xfrmnl_user_tmpl *utmpl; uint32_t i; if (r->ce_mask & XFRM_SP_ATTR_TMPL && r->nr_user_tmpl > n) { i = 0; nl_list_for_each_entry(utmpl, &r->usertmpl_list, utmpl_list) { if (i == n) return utmpl; i++; } } return NULL; } int xfrmnl_sp_get_mark (struct xfrmnl_sp* sp, unsigned int* mark_mask, unsigned int* mark_value) { if (mark_mask == NULL || mark_value == NULL) return -1; if (sp->ce_mask & XFRM_SP_ATTR_MARK) { *mark_mask = sp->mark.m; *mark_value = sp->mark.v; return 0; } else return -1; } int xfrmnl_sp_set_mark (struct xfrmnl_sp* sp, unsigned int value, unsigned int mask) { sp->mark.v = value; sp->mark.m = mask; sp->ce_mask |= XFRM_SP_ATTR_MARK; return 0; } /** @} */ static struct nl_object_ops xfrm_sp_obj_ops = { .oo_name = "xfrm/sp", .oo_size = sizeof(struct xfrmnl_sp), .oo_constructor = xfrm_sp_alloc_data, .oo_free_data = xfrm_sp_free_data, .oo_clone = xfrm_sp_clone, .oo_dump = { [NL_DUMP_LINE] = xfrm_sp_dump_line, [NL_DUMP_DETAILS] = xfrm_sp_dump_details, [NL_DUMP_STATS] = xfrm_sp_dump_stats, }, .oo_compare = xfrm_sp_compare, .oo_attrs2str = xfrm_sp_attrs2str, .oo_id_attrs = (XFRM_SP_ATTR_SEL | XFRM_SP_ATTR_INDEX | XFRM_SP_ATTR_DIR), }; static struct nl_af_group xfrm_sp_groups[] = { { AF_UNSPEC, XFRMNLGRP_POLICY }, { END_OF_GROUP_LIST }, }; static struct nl_cache_ops xfrmnl_sp_ops = { .co_name = "xfrm/sp", .co_hdrsize = sizeof(struct xfrm_userpolicy_info), .co_msgtypes = { { XFRM_MSG_NEWPOLICY, NL_ACT_NEW, "new" }, { XFRM_MSG_DELPOLICY, NL_ACT_DEL, "del" }, { XFRM_MSG_GETPOLICY, NL_ACT_GET, "get" }, { XFRM_MSG_UPDPOLICY, NL_ACT_NEW, "update" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_XFRM, .co_groups = xfrm_sp_groups, .co_request_update = xfrm_sp_request_update, .co_msg_parser = xfrm_sp_msg_parser, .co_obj_ops = &xfrm_sp_obj_ops, }; /** * @name XFRM SA Cache Managament * @{ */ static void __attribute__ ((constructor)) xfrm_sp_init(void) { nl_cache_mngt_register(&xfrmnl_sp_ops); } static void __attribute__ ((destructor)) xfrm_sp_exit(void) { nl_cache_mngt_unregister(&xfrmnl_sp_ops); } /** @} */ libnl-3.2.29/lib/xfrm/template.c0000644000175000017500000001777513023014600013337 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * @ingroup xfrmnl * @defgroup XFRM User Template Object * * Abstract data type representing XFRM SA properties * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include void xfrmnl_user_tmpl_free(struct xfrmnl_user_tmpl* utmpl) { if (!utmpl) return; nl_addr_put (utmpl->id.daddr); nl_addr_put (utmpl->saddr); free(utmpl); } /** * @name Creating User Template Object * @{ */ /** * Allocate new user template object. * @return Newly allocated user template object or NULL */ struct xfrmnl_user_tmpl* xfrmnl_user_tmpl_alloc() { struct xfrmnl_user_tmpl* utmpl; utmpl = calloc(1, sizeof(struct xfrmnl_user_tmpl)); if (!utmpl) return NULL; nl_init_list_head(&utmpl->utmpl_list); return utmpl; } /** * Clone existing user template object. * @arg utmpl Selector object. * @return Newly allocated user template object being a duplicate of the * specified user template object or NULL if a failure occured. */ struct xfrmnl_user_tmpl* xfrmnl_user_tmpl_clone(struct xfrmnl_user_tmpl* utmpl) { struct xfrmnl_user_tmpl* new; new = xfrmnl_user_tmpl_alloc(); if (!new) return NULL; memcpy(new, utmpl, sizeof(struct xfrmnl_user_tmpl)); new->id.daddr = nl_addr_clone (utmpl->id.daddr); new->saddr = nl_addr_clone (utmpl->saddr); return new; } /** @} */ /** * @name XFRM Template Mode Translations * @{ */ static const struct trans_tbl tmpl_modes[] = { __ADD(XFRM_MODE_TRANSPORT, transport), __ADD(XFRM_MODE_TUNNEL, tunnel), __ADD(XFRM_MODE_ROUTEOPTIMIZATION, route optimization), __ADD(XFRM_MODE_IN_TRIGGER, in trigger), __ADD(XFRM_MODE_BEET, beet), }; char* xfrmnl_user_tmpl_mode2str(int mode, char *buf, size_t len) { return __type2str (mode, buf, len, tmpl_modes, ARRAY_SIZE(tmpl_modes)); } int xfrmnl_user_tmpl_str2mode(const char *name) { return __str2type (name, tmpl_modes, ARRAY_SIZE(tmpl_modes)); } /** @} */ /** * @name Miscellaneous * @{ */ /** * Compares two user template objects. * @arg a A user template object. * @arg b Another user template object. * * @return Non zero if difference is found, 0 otherwise if both * the objects are identical. */ int xfrmnl_user_tmpl_cmp(struct xfrmnl_user_tmpl* a, struct xfrmnl_user_tmpl* b) { /* Check for any differences */ if ((nl_addr_cmp_prefix (a->id.daddr, b->id.daddr) != 0) || (a->id.spi != b->id.spi) || (a->id.proto && (a->id.proto != b->id.proto)) || (nl_addr_cmp_prefix (a->saddr, b->saddr) != 0) || (a->family != b->family) || (a->reqid != b->reqid) || (a->mode != b->mode) || (a->share != b->share) || (a->aalgos != b->aalgos) || (a->ealgos != b->ealgos) || (a->calgos != b->calgos)) return 1; /* The objects are identical */ return 0; } void xfrmnl_user_tmpl_dump(struct xfrmnl_user_tmpl* tmpl, struct nl_dump_params *p) { char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5]; char buf [128]; nl_dump_line(p, "\t\tsrc %s dst %s family: %s \n", nl_addr2str(tmpl->saddr, src, sizeof(src)), nl_addr2str (tmpl->id.daddr, dst, sizeof (dst)), nl_af2str (tmpl->family, buf, 128)); nl_dump_line (p, "\t\tprotocol: %s spi: 0x%x reqid: %u mode: %s\n", nl_ip_proto2str (tmpl->id.proto, buf, sizeof(buf)), tmpl->id.spi, tmpl->reqid, xfrmnl_user_tmpl_mode2str (tmpl->mode, buf, 128)); nl_dump_line (p, "\t\tAuth Algo: 0x%x Crypto Algo: 0x%x Compr Algo: 0x%x\n", tmpl->aalgos, tmpl->ealgos, tmpl->calgos); return; } /** @} */ /** * @name Attributes * @{ */ struct nl_addr* xfrmnl_user_tmpl_get_daddr (struct xfrmnl_user_tmpl* utmpl) { return utmpl->id.daddr; } int xfrmnl_user_tmpl_set_daddr (struct xfrmnl_user_tmpl* utmpl, struct nl_addr* addr) { /* Increment reference counter on this to keep this address * object around while user template in use */ nl_addr_get(addr); utmpl->id.daddr = addr; return 0; } int xfrmnl_user_tmpl_get_spi (struct xfrmnl_user_tmpl* utmpl) { return utmpl->id.spi; } int xfrmnl_user_tmpl_set_spi (struct xfrmnl_user_tmpl* utmpl, unsigned int spi) { utmpl->id.spi = spi; return 0; } int xfrmnl_user_tmpl_get_proto (struct xfrmnl_user_tmpl* utmpl) { return utmpl->id.proto; } int xfrmnl_user_tmpl_set_proto (struct xfrmnl_user_tmpl* utmpl, unsigned int protocol) { utmpl->id.proto = protocol; return 0; } int xfrmnl_user_tmpl_get_family(struct xfrmnl_user_tmpl *utmpl) { return utmpl->family; } int xfrmnl_user_tmpl_set_family(struct xfrmnl_user_tmpl *utmpl, int family) { utmpl->family = family; return 0; } struct nl_addr* xfrmnl_user_tmpl_get_saddr (struct xfrmnl_user_tmpl* utmpl) { return utmpl->saddr; } int xfrmnl_user_tmpl_set_saddr (struct xfrmnl_user_tmpl* utmpl, struct nl_addr* addr) { /* Increment reference counter on this to keep this address * object around while user template in use */ nl_addr_get(addr); utmpl->saddr = addr; return 0; } int xfrmnl_user_tmpl_get_reqid (struct xfrmnl_user_tmpl* utmpl) { return utmpl->reqid; } int xfrmnl_user_tmpl_set_reqid (struct xfrmnl_user_tmpl* utmpl, unsigned int reqid) { utmpl->reqid = reqid; return 0; } int xfrmnl_user_tmpl_get_mode (struct xfrmnl_user_tmpl* utmpl) { return utmpl->mode; } int xfrmnl_user_tmpl_set_mode (struct xfrmnl_user_tmpl* utmpl, unsigned int mode) { utmpl->mode = mode; return 0; } int xfrmnl_user_tmpl_get_share (struct xfrmnl_user_tmpl* utmpl) { return utmpl->share; } int xfrmnl_user_tmpl_set_share (struct xfrmnl_user_tmpl* utmpl, unsigned int share) { utmpl->share = share; return 0; } int xfrmnl_user_tmpl_get_optional (struct xfrmnl_user_tmpl* utmpl) { return utmpl->optional; } int xfrmnl_user_tmpl_set_optional (struct xfrmnl_user_tmpl* utmpl, unsigned int optional) { utmpl->optional = optional; return 0; } int xfrmnl_user_tmpl_get_aalgos (struct xfrmnl_user_tmpl* utmpl) { return utmpl->aalgos; } int xfrmnl_user_tmpl_set_aalgos (struct xfrmnl_user_tmpl* utmpl, unsigned int aalgos) { utmpl->aalgos = aalgos; return 0; } int xfrmnl_user_tmpl_get_ealgos (struct xfrmnl_user_tmpl* utmpl) { return utmpl->ealgos; } int xfrmnl_user_tmpl_set_ealgos (struct xfrmnl_user_tmpl* utmpl, unsigned int ealgos) { utmpl->ealgos = ealgos; return 0; } int xfrmnl_user_tmpl_get_calgos (struct xfrmnl_user_tmpl* utmpl) { return utmpl->calgos; } int xfrmnl_user_tmpl_set_calgos (struct xfrmnl_user_tmpl* utmpl, unsigned int calgos) { utmpl->calgos = calgos; return 0; } /** @} */ libnl-3.2.29/lib/xfrm/selector.c0000644000175000017500000001663513023014600013336 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * @ingroup xfrmnl * @defgroup XFRM Address Selector * * Abstract data type representing XFRM SA/SP selector properties * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include static void sel_destroy(struct xfrmnl_sel* sel) { if (!sel) return; if (sel->refcnt != 1) { fprintf(stderr, "BUG: %s:%d\n", __FILE__, __LINE__); assert(0); } nl_addr_put (sel->daddr); nl_addr_put (sel->saddr); free(sel); } /** * @name Creating Selector * @{ */ /** * Allocate new selector object. * @return Newly allocated selector object or NULL */ struct xfrmnl_sel* xfrmnl_sel_alloc() { struct xfrmnl_sel* sel; sel = calloc(1, sizeof(struct xfrmnl_sel)); if (!sel) return NULL; sel->refcnt = 1; return sel; } /** * Clone existing selector object. * @arg sel Selector object. * @return Newly allocated selector object being a duplicate of the * specified selector object or NULL if a failure occured. */ struct xfrmnl_sel* xfrmnl_sel_clone(struct xfrmnl_sel* sel) { struct xfrmnl_sel* new; new = xfrmnl_sel_alloc(); if (!new) return NULL; memcpy(new, sel, sizeof(struct xfrmnl_sel)); new->daddr = nl_addr_clone(sel->daddr); new->saddr = nl_addr_clone(sel->saddr); return new; } /** @} */ /** * @name Managing Usage References * @{ */ struct xfrmnl_sel* xfrmnl_sel_get(struct xfrmnl_sel* sel) { sel->refcnt++; return sel; } void xfrmnl_sel_put(struct xfrmnl_sel* sel) { if (!sel) return; if (sel->refcnt == 1) sel_destroy(sel); else sel->refcnt--; } /** * Check whether an selector object is shared. * @arg addr Selector object. * @return Non-zero if the selector object is shared, otherwise 0. */ int xfrmnl_sel_shared(struct xfrmnl_sel* sel) { return sel->refcnt > 1; } /** @} */ /** * @name Miscellaneous * @{ */ /** * Compares two selector objects. * @arg a A selector object. * @arg b Another selector object. * * @return Non zero if difference is found, 0 otherwise if both * the objects are identical. */ int xfrmnl_sel_cmp(struct xfrmnl_sel* a, struct xfrmnl_sel* b) { /* Check for any differences */ if ((nl_addr_cmp_prefix (a->daddr, b->daddr) != 0) || (nl_addr_cmp_prefix (a->saddr, b->saddr) != 0) || ((a->sport & a->sport_mask) != (b->sport & b->sport_mask)) || ((a->dport & a->dport_mask) != (b->dport & b->dport_mask)) || (a->family != b->family) || (a->proto && (a->proto != b->proto)) || (a->ifindex && a->ifindex != b->ifindex) || (a->user != b->user)) return 1; /* The objects are identical */ return 0; } void xfrmnl_sel_dump(struct xfrmnl_sel* sel, struct nl_dump_params *p) { char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5]; char buf [128]; nl_dump_line(p, "\t\tsrc %s dst %s family: %s\n", nl_addr2str(sel->saddr, src, sizeof(src)), nl_addr2str (sel->daddr, dst, sizeof (dst)), nl_af2str (sel->family, buf, 128)); nl_dump_line (p, "\t\tsrc port/mask: %d/%d dst port/mask: %d/%d\n", sel->dport, sel->dport_mask, sel->sport, sel->sport_mask); nl_dump_line (p, "\t\tprotocol: %s ifindex: %u user: %u\n", nl_ip_proto2str (sel->proto, buf, sizeof(buf)), sel->ifindex, sel->user); return; } /** @} */ /** * @name Attributes * @{ */ struct nl_addr* xfrmnl_sel_get_daddr (struct xfrmnl_sel* sel) { return sel->daddr; } int xfrmnl_sel_set_daddr (struct xfrmnl_sel* sel, struct nl_addr* addr) { /* Increment reference counter on this to keep this address * object around while selector in use */ nl_addr_get(addr); sel->daddr = addr; return 0; } struct nl_addr* xfrmnl_sel_get_saddr (struct xfrmnl_sel* sel) { return sel->saddr; } int xfrmnl_sel_set_saddr (struct xfrmnl_sel* sel, struct nl_addr* addr) { /* Increment reference counter on this to keep this address * object around while selector in use */ nl_addr_get(addr); sel->saddr = addr; return 0; } int xfrmnl_sel_get_dport (struct xfrmnl_sel* sel) { return sel->dport; } int xfrmnl_sel_set_dport (struct xfrmnl_sel* sel, unsigned int dport) { sel->dport = dport; return 0; } int xfrmnl_sel_get_dportmask (struct xfrmnl_sel* sel) { return sel->dport_mask; } int xfrmnl_sel_set_dportmask (struct xfrmnl_sel* sel, unsigned int dport_mask) { sel->dport_mask = dport_mask; return 0; } int xfrmnl_sel_get_sport (struct xfrmnl_sel* sel) { return sel->sport; } int xfrmnl_sel_set_sport (struct xfrmnl_sel* sel, unsigned int sport) { sel->sport = sport; return 0; } int xfrmnl_sel_get_sportmask (struct xfrmnl_sel* sel) { return sel->sport_mask; } int xfrmnl_sel_set_sportmask (struct xfrmnl_sel* sel, unsigned int sport_mask) { sel->sport_mask = sport_mask; return 0; } int xfrmnl_sel_get_family(struct xfrmnl_sel *sel) { return sel->family; } int xfrmnl_sel_set_family(struct xfrmnl_sel *sel, int family) { sel->family = family; return 0; } int xfrmnl_sel_get_prefixlen_d (struct xfrmnl_sel* sel) { return sel->prefixlen_d; } int xfrmnl_sel_set_prefixlen_d (struct xfrmnl_sel* sel, unsigned int prefixlen) { sel->prefixlen_d = prefixlen; return 0; } int xfrmnl_sel_get_prefixlen_s (struct xfrmnl_sel* sel) { return sel->prefixlen_s; } int xfrmnl_sel_set_prefixlen_s (struct xfrmnl_sel* sel, unsigned int prefixlen) { sel->prefixlen_s = prefixlen; return 0; } int xfrmnl_sel_get_proto (struct xfrmnl_sel* sel) { return sel->proto; } int xfrmnl_sel_set_proto (struct xfrmnl_sel* sel, unsigned int protocol) { sel->proto = protocol; return 0; } int xfrmnl_sel_get_ifindex (struct xfrmnl_sel* sel) { return sel->ifindex; } int xfrmnl_sel_set_ifindex (struct xfrmnl_sel* sel, unsigned int ifindex) { sel->ifindex = ifindex; return 0; } int xfrmnl_sel_get_userid (struct xfrmnl_sel* sel) { return sel->user; } int xfrmnl_sel_set_userid (struct xfrmnl_sel* sel, unsigned int userid) { sel->user = userid; return 0; } /** @} */ libnl-3.2.29/lib/xfrm/lifetime.c0000644000175000017500000001560313023014600013306 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * @ingroup xfrmnl * @defgroup XFRM Lifetime Configuration Object * * Abstract data type representing XFRM SA lifetime properties * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include static void ltime_cfg_destroy(struct xfrmnl_ltime_cfg* ltime) { if (!ltime) return; if (ltime->refcnt != 1) { fprintf(stderr, "BUG: %s:%d\n", __FILE__, __LINE__); assert(0); } free(ltime); } /** * @name Creating Selector * @{ */ /** * Allocate new lifetime config object. * @return Newly allocated lifetime config object or NULL */ struct xfrmnl_ltime_cfg* xfrmnl_ltime_cfg_alloc() { struct xfrmnl_ltime_cfg* ltime; ltime = calloc(1, sizeof(struct xfrmnl_ltime_cfg)); if (!ltime) return NULL; ltime->refcnt = 1; return ltime; } /** * Clone existing lifetime config object. * @arg ltime Selector object. * @return Newly allocated lifetime config object being a duplicate of the * specified lifetime config object or NULL if a failure occured. */ struct xfrmnl_ltime_cfg* xfrmnl_ltime_cfg_clone(struct xfrmnl_ltime_cfg* ltime) { struct xfrmnl_ltime_cfg* new; new = xfrmnl_ltime_cfg_alloc(); if (new) memcpy ((void*)new, (void*)ltime, sizeof (struct xfrmnl_ltime_cfg)); return new; } /** @} */ /** * @name Managing Usage References * @{ */ struct xfrmnl_ltime_cfg* xfrmnl_ltime_cfg_get(struct xfrmnl_ltime_cfg* ltime) { ltime->refcnt++; return ltime; } void xfrmnl_ltime_cfg_put(struct xfrmnl_ltime_cfg* ltime) { if (!ltime) return; if (ltime->refcnt == 1) ltime_cfg_destroy(ltime); else ltime->refcnt--; } /** * Check whether an lifetime config object is shared. * @arg addr Selector object. * @return Non-zero if the lifetime config object is shared, otherwise 0. */ int xfrmnl_ltime_cfg_shared(struct xfrmnl_ltime_cfg* ltime) { return ltime->refcnt > 1; } /** @} */ /** * @name Miscellaneous * @{ */ /** * Compares two lifetime config objects. * @arg a A lifetime config object. * @arg b Another lifetime config object. * * @return Non zero if difference is found, 0 otherwise if both * the objects are identical. */ int xfrmnl_ltime_cfg_cmp(struct xfrmnl_ltime_cfg* a, struct xfrmnl_ltime_cfg* b) { /* Check for any differences */ if ((a->soft_byte_limit != b->soft_byte_limit) || (a->soft_packet_limit != b->soft_packet_limit) || (a->hard_byte_limit != b->hard_byte_limit) || (a->hard_packet_limit != b->hard_packet_limit) || (a->soft_add_expires_seconds != b->soft_add_expires_seconds) || (a->hard_add_expires_seconds != b->hard_add_expires_seconds) || (a->soft_use_expires_seconds != b->soft_use_expires_seconds) || (a->hard_use_expires_seconds != b->hard_use_expires_seconds)) return 1; /* The objects are identical */ return 0; } /** @} */ /** * @name Attributes * @{ */ unsigned long long xfrmnl_ltime_cfg_get_soft_bytelimit (struct xfrmnl_ltime_cfg* ltime) { return ltime->soft_byte_limit; } int xfrmnl_ltime_cfg_set_soft_bytelimit (struct xfrmnl_ltime_cfg* ltime, unsigned long long soft_byte_limit) { ltime->soft_byte_limit = soft_byte_limit; return 0; } unsigned long long xfrmnl_ltime_cfg_get_hard_bytelimit (struct xfrmnl_ltime_cfg* ltime) { return ltime->hard_byte_limit; } int xfrmnl_ltime_cfg_set_hard_bytelimit (struct xfrmnl_ltime_cfg* ltime, unsigned long long hard_byte_limit) { ltime->hard_byte_limit = hard_byte_limit; return 0; } unsigned long long xfrmnl_ltime_cfg_get_soft_packetlimit (struct xfrmnl_ltime_cfg* ltime) { return ltime->soft_packet_limit; } int xfrmnl_ltime_cfg_set_soft_packetlimit (struct xfrmnl_ltime_cfg* ltime, unsigned long long soft_packet_limit) { ltime->soft_packet_limit = soft_packet_limit; return 0; } unsigned long long xfrmnl_ltime_cfg_get_hard_packetlimit (struct xfrmnl_ltime_cfg* ltime) { return ltime->hard_packet_limit; } int xfrmnl_ltime_cfg_set_hard_packetlimit (struct xfrmnl_ltime_cfg* ltime, unsigned long long hard_packet_limit) { ltime->hard_packet_limit = hard_packet_limit; return 0; } unsigned long long xfrmnl_ltime_cfg_get_soft_addexpires (struct xfrmnl_ltime_cfg* ltime) { return ltime->soft_add_expires_seconds; } int xfrmnl_ltime_cfg_set_soft_addexpires (struct xfrmnl_ltime_cfg* ltime, unsigned long long soft_add_expires_seconds) { ltime->soft_add_expires_seconds = soft_add_expires_seconds; return 0; } unsigned long long xfrmnl_ltime_cfg_get_hard_addexpires (struct xfrmnl_ltime_cfg* ltime) { return ltime->hard_add_expires_seconds; } int xfrmnl_ltime_cfg_set_hard_addexpires (struct xfrmnl_ltime_cfg* ltime, unsigned long long hard_add_expires_seconds) { ltime->hard_add_expires_seconds = hard_add_expires_seconds; return 0; } unsigned long long xfrmnl_ltime_cfg_get_soft_useexpires (struct xfrmnl_ltime_cfg* ltime) { return ltime->soft_use_expires_seconds; } int xfrmnl_ltime_cfg_set_soft_useexpires (struct xfrmnl_ltime_cfg* ltime, unsigned long long soft_use_expires_seconds) { ltime->soft_use_expires_seconds = soft_use_expires_seconds; return 0; } unsigned long long xfrmnl_ltime_cfg_get_hard_useexpires (struct xfrmnl_ltime_cfg* ltime) { return ltime->hard_use_expires_seconds; } int xfrmnl_ltime_cfg_set_hard_useexpires (struct xfrmnl_ltime_cfg* ltime, unsigned long long hard_use_expires_seconds) { ltime->hard_use_expires_seconds = hard_use_expires_seconds; return 0; } /** @} */ libnl-3.2.29/lib/xfrm/sa.c0000644000175000017500000020606213023014600012114 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * @ingroup xfrmnl * @defgroup sa Security Association * @brief */ #include #include #include #include #include #include #include /** @cond SKIP */ #define XFRM_SA_ATTR_SEL 0x01 #define XFRM_SA_ATTR_DADDR 0x02 #define XFRM_SA_ATTR_SPI 0x04 #define XFRM_SA_ATTR_PROTO 0x08 #define XFRM_SA_ATTR_SADDR 0x10 #define XFRM_SA_ATTR_LTIME_CFG 0x20 #define XFRM_SA_ATTR_LTIME_CUR 0x40 #define XFRM_SA_ATTR_STATS 0x80 #define XFRM_SA_ATTR_SEQ 0x100 #define XFRM_SA_ATTR_REQID 0x200 #define XFRM_SA_ATTR_FAMILY 0x400 #define XFRM_SA_ATTR_MODE 0x800 #define XFRM_SA_ATTR_REPLAY_WIN 0x1000 #define XFRM_SA_ATTR_FLAGS 0x2000 #define XFRM_SA_ATTR_ALG_AEAD 0x4000 #define XFRM_SA_ATTR_ALG_AUTH 0x8000 #define XFRM_SA_ATTR_ALG_CRYPT 0x10000 #define XFRM_SA_ATTR_ALG_COMP 0x20000 #define XFRM_SA_ATTR_ENCAP 0x40000 #define XFRM_SA_ATTR_TFCPAD 0x80000 #define XFRM_SA_ATTR_COADDR 0x100000 #define XFRM_SA_ATTR_MARK 0x200000 #define XFRM_SA_ATTR_SECCTX 0x400000 #define XFRM_SA_ATTR_REPLAY_MAXAGE 0x800000 #define XFRM_SA_ATTR_REPLAY_MAXDIFF 0x1000000 #define XFRM_SA_ATTR_REPLAY_STATE 0x2000000 #define XFRM_SA_ATTR_EXPIRE 0x4000000 static struct nl_cache_ops xfrmnl_sa_ops; static struct nl_object_ops xfrm_sa_obj_ops; /** @endcond */ static void xfrm_sa_alloc_data(struct nl_object *c) { struct xfrmnl_sa* sa = nl_object_priv (c); if ((sa->sel = xfrmnl_sel_alloc ()) == NULL) return; if ((sa->lft = xfrmnl_ltime_cfg_alloc ()) == NULL) return; } static void xfrm_sa_free_data(struct nl_object *c) { struct xfrmnl_sa* sa = nl_object_priv (c); if (sa == NULL) return; xfrmnl_sel_put (sa->sel); xfrmnl_ltime_cfg_put (sa->lft); nl_addr_put (sa->id.daddr); nl_addr_put (sa->saddr); if (sa->aead) free (sa->aead); if (sa->auth) free (sa->auth); if (sa->crypt) free (sa->crypt); if (sa->comp) free (sa->comp); if (sa->encap) { if (sa->encap->encap_oa) nl_addr_put(sa->encap->encap_oa); free(sa->encap); } if (sa->coaddr) nl_addr_put (sa->coaddr); if (sa->sec_ctx) free (sa->sec_ctx); if (sa->replay_state_esn) free (sa->replay_state_esn); } static int xfrm_sa_clone(struct nl_object *_dst, struct nl_object *_src) { struct xfrmnl_sa* dst = nl_object_priv(_dst); struct xfrmnl_sa* src = nl_object_priv(_src); uint32_t len = 0; if (src->sel) if ((dst->sel = xfrmnl_sel_clone (src->sel)) == NULL) return -NLE_NOMEM; if (src->lft) if ((dst->lft = xfrmnl_ltime_cfg_clone (src->lft)) == NULL) return -NLE_NOMEM; if (src->id.daddr) if ((dst->id.daddr = nl_addr_clone (src->id.daddr)) == NULL) return -NLE_NOMEM; if (src->saddr) if ((dst->saddr = nl_addr_clone (src->saddr)) == NULL) return -NLE_NOMEM; if (src->aead) { len = sizeof (struct xfrmnl_algo_aead) + ((src->aead->alg_key_len + 7) / 8); if ((dst->aead = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->aead, (void *)src->aead, len); } if (src->auth) { len = sizeof (struct xfrmnl_algo_auth) + ((src->auth->alg_key_len + 7) / 8); if ((dst->auth = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->auth, (void *)src->auth, len); } if (src->crypt) { len = sizeof (struct xfrmnl_algo) + ((src->crypt->alg_key_len + 7) / 8); if ((dst->crypt = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->crypt, (void *)src->crypt, len); } if (src->comp) { len = sizeof (struct xfrmnl_algo) + ((src->comp->alg_key_len + 7) / 8); if ((dst->comp = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->comp, (void *)src->comp, len); } if (src->encap) { len = sizeof (struct xfrmnl_encap_tmpl); if ((dst->encap = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->encap, (void *)src->encap, len); } if (src->coaddr) if ((dst->coaddr = nl_addr_clone (src->coaddr)) == NULL) return -NLE_NOMEM; if (src->sec_ctx) { len = sizeof (*src->sec_ctx) + src->sec_ctx->ctx_len; if ((dst->sec_ctx = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->sec_ctx, (void *)src->sec_ctx, len); } if (src->replay_state_esn) { len = sizeof (struct xfrmnl_replay_state_esn) + (src->replay_state_esn->bmp_len * sizeof (uint32_t)); if ((dst->replay_state_esn = calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy ((void *)dst->replay_state_esn, (void *)src->replay_state_esn, len); } return 0; } static uint64_t xfrm_sa_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct xfrmnl_sa* a = (struct xfrmnl_sa *) _a; struct xfrmnl_sa* b = (struct xfrmnl_sa *) _b; uint64_t diff = 0; int found = 0; #define XFRM_SA_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, XFRM_SA_ATTR_##ATTR, a, b, EXPR) diff |= XFRM_SA_DIFF(SEL, xfrmnl_sel_cmp(a->sel, b->sel)); diff |= XFRM_SA_DIFF(DADDR, nl_addr_cmp(a->id.daddr, b->id.daddr)); diff |= XFRM_SA_DIFF(SPI, a->id.spi != b->id.spi); diff |= XFRM_SA_DIFF(PROTO, a->id.proto != b->id.proto); diff |= XFRM_SA_DIFF(SADDR, nl_addr_cmp(a->saddr, b->saddr)); diff |= XFRM_SA_DIFF(LTIME_CFG, xfrmnl_ltime_cfg_cmp(a->lft, b->lft)); diff |= XFRM_SA_DIFF(REQID, a->reqid != b->reqid); diff |= XFRM_SA_DIFF(FAMILY,a->family != b->family); diff |= XFRM_SA_DIFF(MODE,a->mode != b->mode); diff |= XFRM_SA_DIFF(REPLAY_WIN,a->replay_window != b->replay_window); diff |= XFRM_SA_DIFF(FLAGS,a->flags != b->flags); diff |= XFRM_SA_DIFF(ALG_AEAD,(strcmp(a->aead->alg_name, b->aead->alg_name) || (a->aead->alg_key_len != b->aead->alg_key_len) || (a->aead->alg_icv_len != b->aead->alg_icv_len) || memcmp(a->aead->alg_key, b->aead->alg_key, ((a->aead->alg_key_len + 7)/8)))); diff |= XFRM_SA_DIFF(ALG_AUTH,(strcmp(a->auth->alg_name, b->auth->alg_name) || (a->auth->alg_key_len != b->auth->alg_key_len) || (a->auth->alg_trunc_len != b->auth->alg_trunc_len) || memcmp(a->auth->alg_key, b->auth->alg_key, ((a->auth->alg_key_len + 7)/8)))); diff |= XFRM_SA_DIFF(ALG_CRYPT,(strcmp(a->crypt->alg_name, b->crypt->alg_name) || (a->crypt->alg_key_len != b->crypt->alg_key_len) || memcmp(a->crypt->alg_key, b->crypt->alg_key, ((a->crypt->alg_key_len + 7)/8)))); diff |= XFRM_SA_DIFF(ALG_COMP,(strcmp(a->comp->alg_name, b->comp->alg_name) || (a->comp->alg_key_len != b->comp->alg_key_len) || memcmp(a->comp->alg_key, b->comp->alg_key, ((a->comp->alg_key_len + 7)/8)))); diff |= XFRM_SA_DIFF(ENCAP,((a->encap->encap_type != b->encap->encap_type) || (a->encap->encap_sport != b->encap->encap_sport) || (a->encap->encap_dport != b->encap->encap_dport) || nl_addr_cmp(a->encap->encap_oa, b->encap->encap_oa))); diff |= XFRM_SA_DIFF(TFCPAD,a->tfcpad != b->tfcpad); diff |= XFRM_SA_DIFF(COADDR,nl_addr_cmp(a->coaddr, b->coaddr)); diff |= XFRM_SA_DIFF(MARK,(a->mark.m != b->mark.m) || (a->mark.v != b->mark.v)); diff |= XFRM_SA_DIFF(SECCTX,((a->sec_ctx->ctx_doi != b->sec_ctx->ctx_doi) || (a->sec_ctx->ctx_alg != b->sec_ctx->ctx_alg) || (a->sec_ctx->ctx_len != b->sec_ctx->ctx_len) || strcmp(a->sec_ctx->ctx, b->sec_ctx->ctx))); diff |= XFRM_SA_DIFF(REPLAY_MAXAGE,a->replay_maxage != b->replay_maxage); diff |= XFRM_SA_DIFF(REPLAY_MAXDIFF,a->replay_maxdiff != b->replay_maxdiff); diff |= XFRM_SA_DIFF(EXPIRE,a->hard != b->hard); /* Compare replay states */ found = AVAILABLE_MISMATCH (a, b, XFRM_SA_ATTR_REPLAY_STATE); if (found == 0) // attribute exists in both objects { if (((a->replay_state_esn != NULL) && (b->replay_state_esn == NULL)) || ((a->replay_state_esn == NULL) && (b->replay_state_esn != NULL))) found |= 1; if (found == 0) // same replay type. compare actual values { if (a->replay_state_esn) { if (a->replay_state_esn->bmp_len != b->replay_state_esn->bmp_len) diff |= 1; else { uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (a->replay_state_esn->bmp_len * sizeof (uint32_t)); diff |= memcmp (a->replay_state_esn, b->replay_state_esn, len); } } else { if ((a->replay_state.oseq != b->replay_state.oseq) || (a->replay_state.seq != b->replay_state.seq) || (a->replay_state.bitmap != b->replay_state.bitmap)) diff |= 1; } } } #undef XFRM_SA_DIFF return diff; } /** * @name XFRM SA Attribute Translations * @{ */ static const struct trans_tbl sa_attrs[] = { __ADD(XFRM_SA_ATTR_SEL, selector), __ADD(XFRM_SA_ATTR_DADDR, daddr), __ADD(XFRM_SA_ATTR_SPI, spi), __ADD(XFRM_SA_ATTR_PROTO, proto), __ADD(XFRM_SA_ATTR_SADDR, saddr), __ADD(XFRM_SA_ATTR_LTIME_CFG, lifetime_cfg), __ADD(XFRM_SA_ATTR_LTIME_CUR, lifetime_cur), __ADD(XFRM_SA_ATTR_STATS, stats), __ADD(XFRM_SA_ATTR_SEQ, seqnum), __ADD(XFRM_SA_ATTR_REQID, reqid), __ADD(XFRM_SA_ATTR_FAMILY, family), __ADD(XFRM_SA_ATTR_MODE, mode), __ADD(XFRM_SA_ATTR_REPLAY_WIN, replay_window), __ADD(XFRM_SA_ATTR_FLAGS, flags), __ADD(XFRM_SA_ATTR_ALG_AEAD, alg_aead), __ADD(XFRM_SA_ATTR_ALG_AUTH, alg_auth), __ADD(XFRM_SA_ATTR_ALG_CRYPT, alg_crypto), __ADD(XFRM_SA_ATTR_ALG_COMP, alg_comp), __ADD(XFRM_SA_ATTR_ENCAP, encap), __ADD(XFRM_SA_ATTR_TFCPAD, tfcpad), __ADD(XFRM_SA_ATTR_COADDR, coaddr), __ADD(XFRM_SA_ATTR_MARK, mark), __ADD(XFRM_SA_ATTR_SECCTX, sec_ctx), __ADD(XFRM_SA_ATTR_REPLAY_MAXAGE, replay_maxage), __ADD(XFRM_SA_ATTR_REPLAY_MAXDIFF, replay_maxdiff), __ADD(XFRM_SA_ATTR_REPLAY_STATE, replay_state), __ADD(XFRM_SA_ATTR_EXPIRE, expire), }; static char* xfrm_sa_attrs2str(int attrs, char *buf, size_t len) { return __flags2str (attrs, buf, len, sa_attrs, ARRAY_SIZE(sa_attrs)); } /** @} */ /** * @name XFRM SA Flags Translations * @{ */ static const struct trans_tbl sa_flags[] = { __ADD(XFRM_STATE_NOECN, no ecn), __ADD(XFRM_STATE_DECAP_DSCP, decap dscp), __ADD(XFRM_STATE_NOPMTUDISC, no pmtu discovery), __ADD(XFRM_STATE_WILDRECV, wild receive), __ADD(XFRM_STATE_ICMP, icmp), __ADD(XFRM_STATE_AF_UNSPEC, unspecified), __ADD(XFRM_STATE_ALIGN4, align4), __ADD(XFRM_STATE_ESN, esn), }; char* xfrmnl_sa_flags2str(int flags, char *buf, size_t len) { return __flags2str (flags, buf, len, sa_flags, ARRAY_SIZE(sa_flags)); } int xfrmnl_sa_str2flag(const char *name) { return __str2flags (name, sa_flags, ARRAY_SIZE(sa_flags)); } /** @} */ /** * @name XFRM SA Mode Translations * @{ */ static const struct trans_tbl sa_modes[] = { __ADD(XFRM_MODE_TRANSPORT, transport), __ADD(XFRM_MODE_TUNNEL, tunnel), __ADD(XFRM_MODE_ROUTEOPTIMIZATION, route optimization), __ADD(XFRM_MODE_IN_TRIGGER, in trigger), __ADD(XFRM_MODE_BEET, beet), }; char* xfrmnl_sa_mode2str(int mode, char *buf, size_t len) { return __type2str (mode, buf, len, sa_modes, ARRAY_SIZE(sa_modes)); } int xfrmnl_sa_str2mode(const char *name) { return __str2type (name, sa_modes, ARRAY_SIZE(sa_modes)); } /** @} */ static void xfrm_sa_dump_line(struct nl_object *a, struct nl_dump_params *p) { char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5]; struct xfrmnl_sa* sa = (struct xfrmnl_sa *) a; char flags[128], mode[128]; time_t add_time, use_time; struct tm *add_time_tm, *use_time_tm; nl_dump_line(p, "src %s dst %s family: %s\n", nl_addr2str(sa->saddr, src, sizeof(src)), nl_addr2str(sa->id.daddr, dst, sizeof(dst)), nl_af2str (sa->family, flags, sizeof (flags))); nl_dump_line(p, "\tproto %s spi 0x%x reqid %u\n", nl_ip_proto2str (sa->id.proto, flags, sizeof(flags)), sa->id.spi, sa->reqid); xfrmnl_sa_flags2str(sa->flags, flags, sizeof (flags)); xfrmnl_sa_mode2str(sa->mode, mode, sizeof (mode)); nl_dump_line(p, "\tmode: %s flags: %s (0x%x) seq: %u replay window: %u\n", mode, flags, sa->flags, sa->seq, sa->replay_window); nl_dump_line(p, "\tlifetime configuration: \n"); if (sa->lft->soft_byte_limit == XFRM_INF) sprintf (flags, "INF"); else sprintf (flags, "%" PRIu64, sa->lft->soft_byte_limit); if (sa->lft->soft_packet_limit == XFRM_INF) sprintf (mode, "INF"); else sprintf (mode, "%" PRIu64, sa->lft->soft_packet_limit); nl_dump_line(p, "\t\tsoft limit: %s (bytes), %s (packets)\n", flags, mode); if (sa->lft->hard_byte_limit == XFRM_INF) sprintf (flags, "INF"); else sprintf (flags, "%" PRIu64, sa->lft->hard_byte_limit); if (sa->lft->hard_packet_limit == XFRM_INF) sprintf (mode, "INF"); else sprintf (mode, "%" PRIu64, sa->lft->hard_packet_limit); nl_dump_line(p, "\t\thard limit: %s (bytes), %s (packets)\n", flags, mode); nl_dump_line(p, "\t\tsoft add_time: %llu (seconds), soft use_time: %llu (seconds) \n", sa->lft->soft_add_expires_seconds, sa->lft->soft_use_expires_seconds); nl_dump_line(p, "\t\thard add_time: %llu (seconds), hard use_time: %llu (seconds) \n", sa->lft->hard_add_expires_seconds, sa->lft->hard_use_expires_seconds); nl_dump_line(p, "\tlifetime current: \n"); nl_dump_line(p, "\t\t%llu bytes, %llu packets\n", sa->curlft.bytes, sa->curlft.packets); if (sa->curlft.add_time != 0) { add_time = sa->curlft.add_time; add_time_tm = gmtime (&add_time); strftime (flags, 128, "%Y-%m-%d %H-%M-%S", add_time_tm); } else { sprintf (flags, "%s", "-"); } if (sa->curlft.use_time != 0) { use_time = sa->curlft.use_time; use_time_tm = gmtime (&use_time); strftime (mode, 128, "%Y-%m-%d %H-%M-%S", use_time_tm); } else { sprintf (mode, "%s", "-"); } nl_dump_line(p, "\t\tadd_time: %s, use_time: %s\n", flags, mode); if (sa->aead) { nl_dump_line(p, "\tAEAD Algo: \n"); nl_dump_line(p, "\t\tName: %s Key len(bits): %u ICV Len(bits): %u\n", sa->aead->alg_name, sa->aead->alg_key_len, sa->aead->alg_icv_len); } if (sa->auth) { nl_dump_line(p, "\tAuth Algo: \n"); nl_dump_line(p, "\t\tName: %s Key len(bits): %u Trunc len(bits): %u\n", sa->auth->alg_name, sa->auth->alg_key_len, sa->auth->alg_trunc_len); } if (sa->crypt) { nl_dump_line(p, "\tEncryption Algo: \n"); nl_dump_line(p, "\t\tName: %s Key len(bits): %u\n", sa->crypt->alg_name, sa->crypt->alg_key_len); } if (sa->comp) { nl_dump_line(p, "\tCompression Algo: \n"); nl_dump_line(p, "\t\tName: %s Key len(bits): %u\n", sa->comp->alg_name, sa->comp->alg_key_len); } if (sa->encap) { nl_dump_line(p, "\tEncapsulation template: \n"); nl_dump_line(p, "\t\tType: %d Src port: %d Dst port: %d Encap addr: %s\n", sa->encap->encap_type, sa->encap->encap_sport, sa->encap->encap_dport, nl_addr2str (sa->encap->encap_oa, dst, sizeof (dst))); } if (sa->ce_mask & XFRM_SA_ATTR_TFCPAD) nl_dump_line(p, "\tTFC Pad: %u\n", sa->tfcpad); if (sa->ce_mask & XFRM_SA_ATTR_COADDR) nl_dump_line(p, "\tCO Address: %s\n", nl_addr2str (sa->coaddr, dst, sizeof (dst))); if (sa->ce_mask & XFRM_SA_ATTR_MARK) nl_dump_line(p, "\tMark mask: 0x%x Mark value: 0x%x\n", sa->mark.m, sa->mark.v); if (sa->ce_mask & XFRM_SA_ATTR_SECCTX) nl_dump_line(p, "\tDOI: %d Algo: %d Len: %u ctx: %s\n", sa->sec_ctx->ctx_doi, sa->sec_ctx->ctx_alg, sa->sec_ctx->ctx_len, sa->sec_ctx->ctx); nl_dump_line(p, "\treplay info: \n"); nl_dump_line(p, "\t\tmax age %u max diff %u \n", sa->replay_maxage, sa->replay_maxdiff); if (sa->ce_mask & XFRM_SA_ATTR_REPLAY_STATE) { nl_dump_line(p, "\treplay state info: \n"); if (sa->replay_state_esn) { nl_dump_line(p, "\t\toseq %u seq %u oseq_hi %u seq_hi %u replay window: %u \n", sa->replay_state_esn->oseq, sa->replay_state_esn->seq, sa->replay_state_esn->oseq_hi, sa->replay_state_esn->seq_hi, sa->replay_state_esn->replay_window); } else { nl_dump_line(p, "\t\toseq %u seq %u bitmap: %u \n", sa->replay_state.oseq, sa->replay_state.seq, sa->replay_state.bitmap); } } nl_dump_line(p, "\tselector info: \n"); xfrmnl_sel_dump (sa->sel, p); nl_dump_line(p, "\tHard: %d\n", sa->hard); nl_dump(p, "\n"); } static void xfrm_sa_dump_stats(struct nl_object *a, struct nl_dump_params *p) { struct xfrmnl_sa* sa = (struct xfrmnl_sa*)a; nl_dump_line(p, "\tstats: \n"); nl_dump_line(p, "\t\treplay window: %u replay: %u integrity failed: %u \n", sa->stats.replay_window, sa->stats.replay, sa->stats.integrity_failed); return; } static void xfrm_sa_dump_details(struct nl_object *a, struct nl_dump_params *p) { xfrm_sa_dump_line(a, p); xfrm_sa_dump_stats (a, p); } /** * @name XFRM SA Object Allocation/Freeage * @{ */ struct xfrmnl_sa* xfrmnl_sa_alloc(void) { return (struct xfrmnl_sa*) nl_object_alloc(&xfrm_sa_obj_ops); } void xfrmnl_sa_put(struct xfrmnl_sa* sa) { nl_object_put((struct nl_object *) sa); } /** @} */ /** * @name SA Cache Managament * @{ */ /** * Build a SA cache including all SAs currently configured in the kernel. * @arg sock Netlink socket. * @arg result Pointer to store resulting cache. * * Allocates a new SA cache, initializes it properly and updates it * to include all SAs currently configured in the kernel. * * @return 0 on success or a negative error code. */ int xfrmnl_sa_alloc_cache(struct nl_sock *sock, struct nl_cache **result) { return nl_cache_alloc_and_fill(&xfrmnl_sa_ops, sock, result); } /** * Look up a SA by destination address, SPI, protocol * @arg cache SA cache * @arg daddr destination address of the SA * @arg spi SPI * @arg proto protocol * @return sa handle or NULL if no match was found. */ struct xfrmnl_sa* xfrmnl_sa_get(struct nl_cache* cache, struct nl_addr* daddr, unsigned int spi, unsigned int proto) { struct xfrmnl_sa *sa; //nl_list_for_each_entry(sa, &cache->c_items, ce_list) { for (sa = (struct xfrmnl_sa*)nl_cache_get_first (cache); sa != NULL; sa = (struct xfrmnl_sa*)nl_cache_get_next ((struct nl_object*)sa)) { if (sa->id.proto == proto && sa->id.spi == spi && !nl_addr_cmp(sa->id.daddr, daddr)) { nl_object_get((struct nl_object *) sa); return sa; } } return NULL; } /** @} */ static struct nla_policy xfrm_sa_policy[XFRMA_MAX+1] = { [XFRMA_SA] = { .minlen = sizeof(struct xfrm_usersa_info)}, [XFRMA_ALG_AUTH_TRUNC] = { .minlen = sizeof(struct xfrm_algo_auth)}, [XFRMA_ALG_AEAD] = { .minlen = sizeof(struct xfrm_algo_aead) }, [XFRMA_ALG_AUTH] = { .minlen = sizeof(struct xfrm_algo) }, [XFRMA_ALG_CRYPT] = { .minlen = sizeof(struct xfrm_algo) }, [XFRMA_ALG_COMP] = { .minlen = sizeof(struct xfrm_algo) }, [XFRMA_ENCAP] = { .minlen = sizeof(struct xfrm_encap_tmpl) }, [XFRMA_TMPL] = { .minlen = sizeof(struct xfrm_user_tmpl) }, [XFRMA_SEC_CTX] = { .minlen = sizeof(struct xfrm_sec_ctx) }, [XFRMA_LTIME_VAL] = { .minlen = sizeof(struct xfrm_lifetime_cur) }, [XFRMA_REPLAY_VAL] = { .minlen = sizeof(struct xfrm_replay_state) }, [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 }, [XFRMA_ETIMER_THRESH] = { .type = NLA_U32 }, [XFRMA_SRCADDR] = { .minlen = sizeof(xfrm_address_t) }, [XFRMA_COADDR] = { .minlen = sizeof(xfrm_address_t) }, [XFRMA_MARK] = { .minlen = sizeof(struct xfrm_mark) }, [XFRMA_TFCPAD] = { .type = NLA_U32 }, [XFRMA_REPLAY_ESN_VAL] = { .minlen = sizeof(struct xfrm_replay_state_esn) }, }; static int xfrm_sa_request_update(struct nl_cache *c, struct nl_sock *h) { struct xfrm_id sa_id; memset (&sa_id, 0, sizeof (sa_id)); return nl_send_simple (h, XFRM_MSG_GETSA, NLM_F_DUMP, &sa_id, sizeof (sa_id)); } int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result) { struct xfrmnl_sa* sa; struct nlattr *tb[XFRMA_MAX + 1]; struct xfrm_usersa_info* sa_info; struct xfrm_user_expire* ue; int len, err; struct nl_addr* addr; sa = xfrmnl_sa_alloc(); if (!sa) { err = -NLE_NOMEM; goto errout; } sa->ce_msgtype = n->nlmsg_type; if (n->nlmsg_type == XFRM_MSG_EXPIRE) { ue = nlmsg_data(n); sa_info = &ue->state; sa->hard = ue->hard; sa->ce_mask |= XFRM_SA_ATTR_EXPIRE; } else if (n->nlmsg_type == XFRM_MSG_DELSA) { sa_info = (struct xfrm_usersa_info*)(nlmsg_data(n) + sizeof (struct xfrm_usersa_id) + NLA_HDRLEN); } else { sa_info = nlmsg_data(n); } err = nlmsg_parse(n, sizeof(struct xfrm_usersa_info), tb, XFRMA_MAX, xfrm_sa_policy); if (err < 0) goto errout; if (sa_info->sel.family == AF_INET) addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.daddr.a4, sizeof (sa_info->sel.daddr.a4)); else addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.daddr.a6, sizeof (sa_info->sel.daddr.a6)); nl_addr_set_prefixlen (addr, sa_info->sel.prefixlen_d); xfrmnl_sel_set_daddr (sa->sel, addr); xfrmnl_sel_set_prefixlen_d (sa->sel, sa_info->sel.prefixlen_d); if (sa_info->sel.family == AF_INET) addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.saddr.a4, sizeof (sa_info->sel.saddr.a4)); else addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.saddr.a6, sizeof (sa_info->sel.saddr.a6)); nl_addr_set_prefixlen (addr, sa_info->sel.prefixlen_s); xfrmnl_sel_set_saddr (sa->sel, addr); xfrmnl_sel_set_prefixlen_s (sa->sel, sa_info->sel.prefixlen_s); xfrmnl_sel_set_dport (sa->sel, ntohs(sa_info->sel.dport)); xfrmnl_sel_set_dportmask (sa->sel, ntohs(sa_info->sel.dport_mask)); xfrmnl_sel_set_sport (sa->sel, ntohs(sa_info->sel.sport)); xfrmnl_sel_set_sportmask (sa->sel, ntohs(sa_info->sel.sport_mask)); xfrmnl_sel_set_family (sa->sel, sa_info->sel.family); xfrmnl_sel_set_proto (sa->sel, sa_info->sel.proto); xfrmnl_sel_set_ifindex (sa->sel, sa_info->sel.ifindex); xfrmnl_sel_set_userid (sa->sel, sa_info->sel.user); sa->ce_mask |= XFRM_SA_ATTR_SEL; if (sa_info->family == AF_INET) sa->id.daddr = nl_addr_build (sa_info->family, &sa_info->id.daddr.a4, sizeof (sa_info->id.daddr.a4)); else sa->id.daddr = nl_addr_build (sa_info->family, &sa_info->id.daddr.a6, sizeof (sa_info->id.daddr.a6)); sa->id.spi = ntohl(sa_info->id.spi); sa->id.proto = sa_info->id.proto; sa->ce_mask |= (XFRM_SA_ATTR_DADDR | XFRM_SA_ATTR_SPI | XFRM_SA_ATTR_PROTO); if (sa_info->family == AF_INET) sa->saddr = nl_addr_build (sa_info->family, &sa_info->saddr.a4, sizeof (sa_info->saddr.a4)); else sa->saddr = nl_addr_build (sa_info->family, &sa_info->saddr.a6, sizeof (sa_info->saddr.a6)); sa->ce_mask |= XFRM_SA_ATTR_SADDR; sa->lft->soft_byte_limit = sa_info->lft.soft_byte_limit; sa->lft->hard_byte_limit = sa_info->lft.hard_byte_limit; sa->lft->soft_packet_limit = sa_info->lft.soft_packet_limit; sa->lft->hard_packet_limit = sa_info->lft.hard_packet_limit; sa->lft->soft_add_expires_seconds = sa_info->lft.soft_add_expires_seconds; sa->lft->hard_add_expires_seconds = sa_info->lft.hard_add_expires_seconds; sa->lft->soft_use_expires_seconds = sa_info->lft.soft_use_expires_seconds; sa->lft->hard_use_expires_seconds = sa_info->lft.hard_use_expires_seconds; sa->ce_mask |= XFRM_SA_ATTR_LTIME_CFG; sa->curlft.bytes = sa_info->curlft.bytes; sa->curlft.packets = sa_info->curlft.packets; sa->curlft.add_time = sa_info->curlft.add_time; sa->curlft.use_time = sa_info->curlft.use_time; sa->ce_mask |= XFRM_SA_ATTR_LTIME_CUR; sa->stats.replay_window = sa_info->stats.replay_window; sa->stats.replay = sa_info->stats.replay; sa->stats.integrity_failed = sa_info->stats.integrity_failed; sa->ce_mask |= XFRM_SA_ATTR_STATS; sa->seq = sa_info->seq; sa->reqid = sa_info->reqid; sa->family = sa_info->family; sa->mode = sa_info->mode; sa->replay_window = sa_info->replay_window; sa->flags = sa_info->flags; sa->ce_mask |= (XFRM_SA_ATTR_SEQ | XFRM_SA_ATTR_REQID | XFRM_SA_ATTR_FAMILY | XFRM_SA_ATTR_MODE | XFRM_SA_ATTR_REPLAY_WIN | XFRM_SA_ATTR_FLAGS); if (tb[XFRMA_ALG_AEAD]) { struct xfrm_algo_aead* aead = nla_data(tb[XFRMA_ALG_AEAD]); len = sizeof (struct xfrmnl_algo_aead) + ((aead->alg_key_len + 7) / 8); if ((sa->aead = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } memcpy ((void *)sa->aead, (void *)aead, len); sa->ce_mask |= XFRM_SA_ATTR_ALG_AEAD; } if (tb[XFRMA_ALG_AUTH_TRUNC]) { struct xfrm_algo_auth* auth = nla_data(tb[XFRMA_ALG_AUTH_TRUNC]); len = sizeof (struct xfrmnl_algo_auth) + ((auth->alg_key_len + 7) / 8); if ((sa->auth = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } memcpy ((void *)sa->auth, (void *)auth, len); sa->ce_mask |= XFRM_SA_ATTR_ALG_AUTH; } if (tb[XFRMA_ALG_AUTH] && !sa->auth) { struct xfrm_algo* auth = nla_data(tb[XFRMA_ALG_AUTH]); len = sizeof (struct xfrmnl_algo_auth) + ((auth->alg_key_len + 7) / 8); if ((sa->auth = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } strcpy(sa->auth->alg_name, auth->alg_name); memcpy(sa->auth->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8); sa->auth->alg_key_len = auth->alg_key_len; sa->ce_mask |= XFRM_SA_ATTR_ALG_AUTH; } if (tb[XFRMA_ALG_CRYPT]) { struct xfrm_algo* crypt = nla_data(tb[XFRMA_ALG_CRYPT]); len = sizeof (struct xfrmnl_algo) + ((crypt->alg_key_len + 7) / 8); if ((sa->crypt = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } memcpy ((void *)sa->crypt, (void *)crypt, len); sa->ce_mask |= XFRM_SA_ATTR_ALG_CRYPT; } if (tb[XFRMA_ALG_COMP]) { struct xfrm_algo* comp = nla_data(tb[XFRMA_ALG_COMP]); len = sizeof (struct xfrmnl_algo) + ((comp->alg_key_len + 7) / 8); if ((sa->comp = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } memcpy ((void *)sa->comp, (void *)comp, len); sa->ce_mask |= XFRM_SA_ATTR_ALG_COMP; } if (tb[XFRMA_ENCAP]) { struct xfrm_encap_tmpl* encap = nla_data(tb[XFRMA_ENCAP]); len = sizeof (struct xfrmnl_encap_tmpl); if ((sa->encap = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } sa->encap->encap_type = encap->encap_type; sa->encap->encap_sport = ntohs(encap->encap_sport); sa->encap->encap_dport = ntohs(encap->encap_dport); if (sa_info->family == AF_INET) sa->encap->encap_oa = nl_addr_build (sa_info->family, &encap->encap_oa.a4, sizeof (encap->encap_oa.a4)); else sa->encap->encap_oa = nl_addr_build (sa_info->family, &encap->encap_oa.a6, sizeof (encap->encap_oa.a6)); sa->ce_mask |= XFRM_SA_ATTR_ENCAP; } if (tb[XFRMA_TFCPAD]) { sa->tfcpad = *(uint32_t*)nla_data(tb[XFRMA_TFCPAD]); sa->ce_mask |= XFRM_SA_ATTR_TFCPAD; } if (tb[XFRMA_COADDR]) { if (sa_info->family == AF_INET) { sa->coaddr = nl_addr_build(sa_info->family, nla_data(tb[XFRMA_COADDR]), sizeof (uint32_t)); } else { sa->coaddr = nl_addr_build(sa_info->family, nla_data(tb[XFRMA_COADDR]), sizeof (uint32_t) * 4); } sa->ce_mask |= XFRM_SA_ATTR_COADDR; } if (tb[XFRMA_MARK]) { struct xfrm_mark* m = nla_data(tb[XFRMA_MARK]); sa->mark.m = m->m; sa->mark.v = m->v; sa->ce_mask |= XFRM_SA_ATTR_MARK; } if (tb[XFRMA_SEC_CTX]) { struct xfrm_user_sec_ctx* sec_ctx = nla_data(tb[XFRMA_SEC_CTX]); len = sizeof (struct xfrmnl_user_sec_ctx) + sec_ctx->ctx_len; if ((sa->sec_ctx = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } memcpy (sa->sec_ctx, sec_ctx, len); sa->ce_mask |= XFRM_SA_ATTR_SECCTX; } if (tb[XFRMA_ETIMER_THRESH]) { sa->replay_maxage = *(uint32_t*)nla_data(tb[XFRMA_ETIMER_THRESH]); sa->ce_mask |= XFRM_SA_ATTR_REPLAY_MAXAGE; } if (tb[XFRMA_REPLAY_THRESH]) { sa->replay_maxdiff = *(uint32_t*)nla_data(tb[XFRMA_REPLAY_THRESH]); sa->ce_mask |= XFRM_SA_ATTR_REPLAY_MAXDIFF; } if (tb[XFRMA_REPLAY_ESN_VAL]) { struct xfrm_replay_state_esn* esn = nla_data (tb[XFRMA_REPLAY_ESN_VAL]); len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * esn->bmp_len); if ((sa->replay_state_esn = calloc (1, len)) == NULL) { err = -NLE_NOMEM; goto errout; } memcpy ((void *)sa->replay_state_esn, (void *)esn, len); sa->ce_mask |= XFRM_SA_ATTR_REPLAY_STATE; } else if (tb[XFRMA_REPLAY_VAL]) { struct xfrm_replay_state* replay_state = nla_data (tb[XFRMA_REPLAY_VAL]); sa->replay_state.oseq = replay_state->oseq; sa->replay_state.seq = replay_state->seq; sa->replay_state.bitmap = replay_state->bitmap; sa->ce_mask |= XFRM_SA_ATTR_REPLAY_STATE; sa->replay_state_esn = NULL; } *result = sa; return 0; errout: xfrmnl_sa_put(sa); return err; } static int xfrm_sa_update_cache (struct nl_cache *cache, struct nl_object *obj, change_func_t change_cb, change_func_v2_t change_cb_v2, void *data) { struct nl_object* old_sa; struct xfrmnl_sa* sa = (struct xfrmnl_sa*)obj; if (nl_object_get_msgtype (obj) == XFRM_MSG_EXPIRE) { /* On hard expiry, the SA gets deleted too from the kernel state without any * further delete event. On Expire message, we are only updating the cache with * the SA object's new state. In absence of the explicit delete event, the cache will * be out of sync with the kernel state. To get around this, expiry messages cache * operations are handled here (installed with NL_ACT_UNSPEC action) instead of * in Libnl Cache module. */ /* Do we already have this object in the cache? */ old_sa = nl_cache_search(cache, obj); if (old_sa) { /* Found corresponding SA object in cache. Delete it */ nl_cache_remove (old_sa); } /* Handle the expiry event now */ if (sa->hard == 0) { /* Soft expiry event: Save the new object to the * cache and notify application of the expiry event. */ nl_cache_move (cache, obj); if (old_sa == NULL) { /* Application CB present, no previous instance of SA object present. * Notify application CB as a NEW event */ if (change_cb_v2) change_cb_v2(cache, NULL, obj, 0, NL_ACT_NEW, data); else if (change_cb) change_cb(cache, obj, NL_ACT_NEW, data); } else if (old_sa) { uint64_t diff = 0; if (change_cb || change_cb_v2) diff = nl_object_diff64(old_sa, obj); /* Application CB present, a previous instance of SA object present. * Notify application CB as a CHANGE1 event */ if (diff) { if (change_cb_v2) { change_cb_v2(cache, old_sa, obj, diff, NL_ACT_CHANGE, data); } else if (change_cb) change_cb(cache, obj, NL_ACT_CHANGE, data); } nl_object_put (old_sa); } } else { /* Hard expiry event: Delete the object from the * cache and notify application of the expiry event. */ if (change_cb_v2) change_cb_v2(cache, obj, NULL, 0, NL_ACT_DEL, data); else if (change_cb) change_cb (cache, obj, NL_ACT_DEL, data); nl_object_put (old_sa); } /* Done handling expire message */ return 0; } else { /* All other messages other than Expire, let the standard Libnl cache * module handle it. */ if (change_cb_v2) return nl_cache_include_v2(cache, obj, change_cb_v2, data); else return nl_cache_include (cache, obj, change_cb, data); } } static int xfrm_sa_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct xfrmnl_sa* sa; int err; if ((err = xfrmnl_sa_parse(n, &sa)) < 0) return err; err = pp->pp_cb((struct nl_object *) sa, pp); xfrmnl_sa_put(sa); return err; } /** * @name XFRM SA Get * @{ */ int xfrmnl_sa_build_get_request(struct nl_addr* daddr, unsigned int spi, unsigned int protocol, unsigned int mark_v, unsigned int mark_m, struct nl_msg **result) { struct nl_msg *msg; struct xfrm_usersa_id sa_id; struct xfrm_mark mark; if (!daddr || !spi) { fprintf(stderr, "APPLICATION BUG: %s:%d:%s: A valid destination address, spi must be specified\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); assert(0); return -NLE_MISSING_ATTR; } memset(&sa_id, 0, sizeof(sa_id)); memcpy (&sa_id.daddr, nl_addr_get_binary_addr (daddr), sizeof (uint8_t) * nl_addr_get_len (daddr)); sa_id.family = nl_addr_get_family (daddr); sa_id.spi = htonl(spi); sa_id.proto = protocol; if (!(msg = nlmsg_alloc_simple(XFRM_MSG_GETSA, 0))) return -NLE_NOMEM; if (nlmsg_append(msg, &sa_id, sizeof(sa_id), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if ((mark_m & mark_v) != 0) { memset(&mark, 0, sizeof(struct xfrm_mark)); mark.m = mark_m; mark.v = mark_v; NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrm_mark), &mark); } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } int xfrmnl_sa_get_kernel(struct nl_sock* sock, struct nl_addr* daddr, unsigned int spi, unsigned int protocol, unsigned int mark_v, unsigned int mark_m, struct xfrmnl_sa** result) { struct nl_msg *msg = NULL; struct nl_object *obj; int err; if ((err = xfrmnl_sa_build_get_request(daddr, spi, protocol, mark_m, mark_v, &msg)) < 0) return err; err = nl_send_auto(sock, msg); nlmsg_free(msg); if (err < 0) return err; if ((err = nl_pickup(sock, &xfrm_sa_msg_parser, &obj)) < 0) return err; /* We have used xfrm_sa_msg_parser(), object is definitely a xfrm sa */ *result = (struct xfrmnl_sa *) obj; /* If an object has been returned, we also need to wait for the ACK */ if (err == 0 && obj) nl_wait_for_ack(sock); return 0; } /** @} */ static int build_xfrm_sa_message(struct xfrmnl_sa *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg* msg; struct xfrm_usersa_info sa_info; uint32_t len; struct nl_addr* addr; if (!(tmpl->ce_mask & XFRM_SA_ATTR_DADDR) || !(tmpl->ce_mask & XFRM_SA_ATTR_SPI) || !(tmpl->ce_mask & XFRM_SA_ATTR_PROTO)) return -NLE_MISSING_ATTR; memset ((void*)&sa_info, 0, sizeof (sa_info)); if (tmpl->ce_mask & XFRM_SA_ATTR_SEL) { addr = xfrmnl_sel_get_daddr (tmpl->sel); memcpy ((void*)&sa_info.sel.daddr, (void*)nl_addr_get_binary_addr (addr), sizeof (uint8_t) * nl_addr_get_len (addr)); addr = xfrmnl_sel_get_saddr (tmpl->sel); memcpy ((void*)&sa_info.sel.saddr, (void*)nl_addr_get_binary_addr (addr), sizeof (uint8_t) * nl_addr_get_len (addr)); sa_info.sel.dport = htons (xfrmnl_sel_get_dport (tmpl->sel)); sa_info.sel.dport_mask = htons (xfrmnl_sel_get_dportmask (tmpl->sel)); sa_info.sel.sport = htons (xfrmnl_sel_get_sport (tmpl->sel)); sa_info.sel.sport_mask = htons (xfrmnl_sel_get_sportmask (tmpl->sel)); sa_info.sel.family = xfrmnl_sel_get_family (tmpl->sel); sa_info.sel.prefixlen_d = xfrmnl_sel_get_prefixlen_d (tmpl->sel); sa_info.sel.prefixlen_s = xfrmnl_sel_get_prefixlen_s (tmpl->sel); sa_info.sel.proto = xfrmnl_sel_get_proto (tmpl->sel); sa_info.sel.ifindex = xfrmnl_sel_get_ifindex (tmpl->sel); sa_info.sel.user = xfrmnl_sel_get_userid (tmpl->sel); } memcpy (&sa_info.id.daddr, nl_addr_get_binary_addr (tmpl->id.daddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->id.daddr)); sa_info.id.spi = htonl(tmpl->id.spi); sa_info.id.proto = tmpl->id.proto; if (tmpl->ce_mask & XFRM_SA_ATTR_SADDR) memcpy (&sa_info.saddr, nl_addr_get_binary_addr (tmpl->saddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->saddr)); if (tmpl->ce_mask & XFRM_SA_ATTR_LTIME_CFG) { sa_info.lft.soft_byte_limit = xfrmnl_ltime_cfg_get_soft_bytelimit (tmpl->lft); sa_info.lft.hard_byte_limit = xfrmnl_ltime_cfg_get_hard_bytelimit (tmpl->lft); sa_info.lft.soft_packet_limit = xfrmnl_ltime_cfg_get_soft_packetlimit (tmpl->lft); sa_info.lft.hard_packet_limit = xfrmnl_ltime_cfg_get_hard_packetlimit (tmpl->lft); sa_info.lft.soft_add_expires_seconds = xfrmnl_ltime_cfg_get_soft_addexpires (tmpl->lft); sa_info.lft.hard_add_expires_seconds = xfrmnl_ltime_cfg_get_hard_addexpires (tmpl->lft); sa_info.lft.soft_use_expires_seconds = xfrmnl_ltime_cfg_get_soft_useexpires (tmpl->lft); sa_info.lft.hard_use_expires_seconds = xfrmnl_ltime_cfg_get_hard_useexpires (tmpl->lft); } //Skip current lifetime: cur lifetime can be updated only via AE //Skip stats: stats cant be updated //Skip seq: seq cant be updated if (tmpl->ce_mask & XFRM_SA_ATTR_REQID) sa_info.reqid = tmpl->reqid; if (tmpl->ce_mask & XFRM_SA_ATTR_FAMILY) sa_info.family = tmpl->family; if (tmpl->ce_mask & XFRM_SA_ATTR_MODE) sa_info.mode = tmpl->mode; if (tmpl->ce_mask & XFRM_SA_ATTR_REPLAY_WIN) sa_info.replay_window = tmpl->replay_window; if (tmpl->ce_mask & XFRM_SA_ATTR_FLAGS) sa_info.flags = tmpl->flags; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &sa_info, sizeof(sa_info), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tmpl->ce_mask & XFRM_SA_ATTR_ALG_AEAD) { len = sizeof (struct xfrm_algo_aead) + ((tmpl->aead->alg_key_len + 7) / 8); NLA_PUT (msg, XFRMA_ALG_AEAD, len, tmpl->aead); } if (tmpl->ce_mask & XFRM_SA_ATTR_ALG_AUTH) { /* kernel prefers XFRMA_ALG_AUTH_TRUNC over XFRMA_ALG_AUTH, so only * one of the attributes needs to be present */ if (tmpl->auth->alg_trunc_len) { len = sizeof (struct xfrm_algo_auth) + ((tmpl->auth->alg_key_len + 7) / 8); NLA_PUT (msg, XFRMA_ALG_AUTH_TRUNC, len, tmpl->auth); } else { struct xfrm_algo *auth; len = sizeof (struct xfrm_algo) + ((tmpl->auth->alg_key_len + 7) / 8); auth = malloc(len); if (!auth) { nlmsg_free(msg); return -NLE_NOMEM; } strncpy(auth->alg_name, tmpl->auth->alg_name, sizeof(auth->alg_name)); auth->alg_key_len = tmpl->auth->alg_key_len; memcpy(auth->alg_key, tmpl->auth->alg_key, (tmpl->auth->alg_key_len + 7) / 8); if (nla_put(msg, XFRMA_ALG_AUTH, len, auth) < 0) { free(auth); goto nla_put_failure; } free(auth); } } if (tmpl->ce_mask & XFRM_SA_ATTR_ALG_CRYPT) { len = sizeof (struct xfrm_algo) + ((tmpl->crypt->alg_key_len + 7) / 8); NLA_PUT (msg, XFRMA_ALG_CRYPT, len, tmpl->crypt); } if (tmpl->ce_mask & XFRM_SA_ATTR_ALG_COMP) { len = sizeof (struct xfrm_algo) + ((tmpl->comp->alg_key_len + 7) / 8); NLA_PUT (msg, XFRMA_ALG_COMP, len, tmpl->comp); } if (tmpl->ce_mask & XFRM_SA_ATTR_ENCAP) { struct xfrm_encap_tmpl* encap_tmpl; struct nlattr* encap_attr; len = sizeof (struct xfrm_encap_tmpl); encap_attr = nla_reserve(msg, XFRMA_ENCAP, len); if (!encap_attr) goto nla_put_failure; encap_tmpl = nla_data (encap_attr); encap_tmpl->encap_type = tmpl->encap->encap_type; encap_tmpl->encap_sport = htons (tmpl->encap->encap_sport); encap_tmpl->encap_dport = htons (tmpl->encap->encap_dport); memcpy (&encap_tmpl->encap_oa, nl_addr_get_binary_addr (tmpl->encap->encap_oa), sizeof (uint8_t) * nl_addr_get_len (tmpl->encap->encap_oa)); } if (tmpl->ce_mask & XFRM_SA_ATTR_TFCPAD) { NLA_PUT_U32 (msg, XFRMA_TFCPAD, tmpl->tfcpad); } if (tmpl->ce_mask & XFRM_SA_ATTR_COADDR) { NLA_PUT (msg, XFRMA_COADDR, sizeof (xfrm_address_t), tmpl->coaddr); } if (tmpl->ce_mask & XFRM_SA_ATTR_MARK) { NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrm_mark), &tmpl->mark); } if (tmpl->ce_mask & XFRM_SA_ATTR_SECCTX) { len = sizeof (struct xfrm_sec_ctx) + tmpl->sec_ctx->ctx_len; NLA_PUT (msg, XFRMA_SEC_CTX, len, tmpl->sec_ctx); } if (tmpl->ce_mask & XFRM_SA_ATTR_REPLAY_MAXAGE) { NLA_PUT_U32 (msg, XFRMA_ETIMER_THRESH, tmpl->replay_maxage); } if (tmpl->ce_mask & XFRM_SA_ATTR_REPLAY_MAXDIFF) { NLA_PUT_U32 (msg, XFRMA_REPLAY_THRESH, tmpl->replay_maxdiff); } if (tmpl->ce_mask & XFRM_SA_ATTR_REPLAY_STATE) { if (tmpl->replay_state_esn) { len = sizeof (struct xfrm_replay_state_esn) + (sizeof (uint32_t) * tmpl->replay_state_esn->bmp_len); NLA_PUT (msg, XFRMA_REPLAY_ESN_VAL, len, tmpl->replay_state_esn); } else { NLA_PUT (msg, XFRMA_REPLAY_VAL, sizeof (struct xfrm_replay_state), &tmpl->replay_state); } } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * @name XFRM SA Add * @{ */ int xfrmnl_sa_build_add_request(struct xfrmnl_sa* tmpl, int flags, struct nl_msg **result) { return build_xfrm_sa_message (tmpl, XFRM_MSG_NEWSA, flags, result); } int xfrmnl_sa_add(struct nl_sock* sk, struct xfrmnl_sa* tmpl, int flags) { int err; struct nl_msg *msg; if ((err = xfrmnl_sa_build_add_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); } /** * @name XFRM SA Update * @{ */ int xfrmnl_sa_build_update_request(struct xfrmnl_sa* tmpl, int flags, struct nl_msg **result) { return build_xfrm_sa_message (tmpl, XFRM_MSG_UPDSA, flags, result); } int xfrmnl_sa_update(struct nl_sock* sk, struct xfrmnl_sa* tmpl, int flags) { int err; struct nl_msg *msg; if ((err = xfrmnl_sa_build_update_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); } /** @} */ static int build_xfrm_sa_delete_message(struct xfrmnl_sa *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg* msg; struct xfrm_usersa_id sa_id; if (!(tmpl->ce_mask & XFRM_SA_ATTR_DADDR) || !(tmpl->ce_mask & XFRM_SA_ATTR_SPI) || !(tmpl->ce_mask & XFRM_SA_ATTR_PROTO)) return -NLE_MISSING_ATTR; memcpy (&sa_id.daddr, nl_addr_get_binary_addr (tmpl->id.daddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->id.daddr)); sa_id.family = nl_addr_get_family (tmpl->id.daddr); sa_id.spi = htonl(tmpl->id.spi); sa_id.proto = tmpl->id.proto; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &sa_id, sizeof(sa_id), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tmpl->ce_mask & XFRM_SA_ATTR_MARK) { NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrm_mark), &tmpl->mark); } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * @name XFRM SA Delete * @{ */ int xfrmnl_sa_build_delete_request(struct xfrmnl_sa* tmpl, int flags, struct nl_msg **result) { return build_xfrm_sa_delete_message (tmpl, XFRM_MSG_DELSA, flags, result); } int xfrmnl_sa_delete(struct nl_sock* sk, struct xfrmnl_sa* tmpl, int flags) { int err; struct nl_msg *msg; if ((err = xfrmnl_sa_build_delete_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); } /** @} */ /** * @name Attributes * @{ */ struct xfrmnl_sel* xfrmnl_sa_get_sel (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_SEL) return sa->sel; else return NULL; } int xfrmnl_sa_set_sel (struct xfrmnl_sa* sa, struct xfrmnl_sel* sel) { /* Release any previously held selector object from the SA */ if (sa->sel) xfrmnl_sel_put (sa->sel); /* Increment ref count on new selector and save it in the SA */ xfrmnl_sel_get (sel); sa->sel = sel; sa->ce_mask |= XFRM_SA_ATTR_SEL; return 0; } static inline int __assign_addr(struct xfrmnl_sa* sa, struct nl_addr **pos, struct nl_addr *new, int flag, int nocheck) { if (!nocheck) { if (sa->ce_mask & XFRM_SA_ATTR_FAMILY) { if (nl_addr_get_family (new) != sa->family) return -NLE_AF_MISMATCH; } } if (*pos) nl_addr_put(*pos); nl_addr_get(new); *pos = new; sa->ce_mask |= flag; return 0; } struct nl_addr* xfrmnl_sa_get_daddr (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_DADDR) return sa->id.daddr; else return NULL; } int xfrmnl_sa_set_daddr (struct xfrmnl_sa* sa, struct nl_addr* addr) { return __assign_addr(sa, &sa->id.daddr, addr, XFRM_SA_ATTR_DADDR, 0); } int xfrmnl_sa_get_spi (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_SPI) return sa->id.spi; else return -1; } int xfrmnl_sa_set_spi (struct xfrmnl_sa* sa, unsigned int spi) { sa->id.spi = spi; sa->ce_mask |= XFRM_SA_ATTR_SPI; return 0; } int xfrmnl_sa_get_proto (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_PROTO) return sa->id.proto; else return -1; } int xfrmnl_sa_set_proto (struct xfrmnl_sa* sa, unsigned int protocol) { sa->id.proto = protocol; sa->ce_mask |= XFRM_SA_ATTR_PROTO; return 0; } struct nl_addr* xfrmnl_sa_get_saddr (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_SADDR) return sa->saddr; else return NULL; } int xfrmnl_sa_set_saddr (struct xfrmnl_sa* sa, struct nl_addr* addr) { return __assign_addr(sa, &sa->saddr, addr, XFRM_SA_ATTR_SADDR, 1); } struct xfrmnl_ltime_cfg* xfrmnl_sa_get_lifetime_cfg (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_LTIME_CFG) return sa->lft; else return NULL; } int xfrmnl_sa_set_lifetime_cfg (struct xfrmnl_sa* sa, struct xfrmnl_ltime_cfg* ltime) { /* Release any previously held lifetime cfg object from the SA */ if (sa->lft) xfrmnl_ltime_cfg_put (sa->lft); /* Increment ref count on new lifetime object and save it in the SA */ xfrmnl_ltime_cfg_get (ltime); sa->lft = ltime; sa->ce_mask |= XFRM_SA_ATTR_LTIME_CFG; return 0; } int xfrmnl_sa_get_curlifetime (struct xfrmnl_sa* sa, unsigned long long int* curr_bytes, unsigned long long int* curr_packets, unsigned long long int* curr_add_time, unsigned long long int* curr_use_time) { if (sa == NULL || curr_bytes == NULL || curr_packets == NULL || curr_add_time == NULL || curr_use_time == NULL) return -1; if (sa->ce_mask & XFRM_SA_ATTR_LTIME_CUR) { *curr_bytes = sa->curlft.bytes; *curr_packets = sa->curlft.packets; *curr_add_time = sa->curlft.add_time; *curr_use_time = sa->curlft.use_time; } else return -1; return 0; } int xfrmnl_sa_get_stats (struct xfrmnl_sa* sa, unsigned long long int* replay_window, unsigned long long int* replay, unsigned long long int* integrity_failed) { if (sa == NULL || replay_window == NULL || replay == NULL || integrity_failed == NULL) return -1; if (sa->ce_mask & XFRM_SA_ATTR_STATS) { *replay_window = sa->stats.replay_window; *replay = sa->stats.replay; *integrity_failed = sa->stats.integrity_failed; } else return -1; return 0; } int xfrmnl_sa_get_seq (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_SEQ) return sa->seq; else return -1; } int xfrmnl_sa_get_reqid (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_REQID) return sa->reqid; else return -1; } int xfrmnl_sa_set_reqid (struct xfrmnl_sa* sa, unsigned int reqid) { sa->reqid = reqid; sa->ce_mask |= XFRM_SA_ATTR_REQID; return 0; } int xfrmnl_sa_get_family (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_FAMILY) return sa->family; else return -1; } int xfrmnl_sa_set_family (struct xfrmnl_sa* sa, unsigned int family) { sa->family = family; sa->ce_mask |= XFRM_SA_ATTR_FAMILY; return 0; } int xfrmnl_sa_get_mode (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_MODE) return sa->mode; else return -1; } int xfrmnl_sa_set_mode (struct xfrmnl_sa* sa, unsigned int mode) { sa->mode = mode; sa->ce_mask |= XFRM_SA_ATTR_MODE; return 0; } int xfrmnl_sa_get_replay_window (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_REPLAY_WIN) return sa->replay_window; else return -1; } int xfrmnl_sa_set_replay_window (struct xfrmnl_sa* sa, unsigned int replay_window) { sa->replay_window = replay_window; sa->ce_mask |= XFRM_SA_ATTR_REPLAY_WIN; return 0; } int xfrmnl_sa_get_flags (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_FLAGS) return sa->flags; else return -1; } int xfrmnl_sa_set_flags (struct xfrmnl_sa* sa, unsigned int flags) { sa->flags = flags; sa->ce_mask |= XFRM_SA_ATTR_FLAGS; return 0; } /** * Get the aead-params * @arg sa the xfrmnl_sa object * @arg alg_name an optional output buffer for the algorithm name. Must be at least 64 bytes. * @arg key_len an optional output value for the key length in bits. * @arg icv_len an optional output value for the alt-icv-len. * @arg key an optional buffer large enough for the key. It must contain at least * ((@key_len + 7) / 8) bytes. * * Warning: you must ensure that @key is large enough. If you don't know the key_len before-hand, * call xfrmnl_sa_get_aead_params() without @key argument to query only the required buffer size. * This modified API is available in all versions of libnl3 that support the capability * @def NL_CAPABILITY_XFRM_SA_KEY_SIZE (@see nl_has_capability for further information). * * @return 0 on success or a negative error code. */ int xfrmnl_sa_get_aead_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int* key_len, unsigned int* icv_len, char* key) { if (sa->ce_mask & XFRM_SA_ATTR_ALG_AEAD) { if (alg_name) strcpy (alg_name, sa->aead->alg_name); if (key_len) *key_len = sa->aead->alg_key_len; if (icv_len) *icv_len = sa->aead->alg_icv_len; if (key) memcpy (key, sa->aead->alg_key, ((sa->aead->alg_key_len + 7)/8)); } else return -1; return 0; } int xfrmnl_sa_set_aead_params (struct xfrmnl_sa* sa, const char* alg_name, unsigned int key_len, unsigned int icv_len, const char* key) { size_t keysize = sizeof (uint8_t) * ((key_len + 7)/8); uint32_t newlen = sizeof (struct xfrmnl_algo_aead) + keysize; /* Free up the old key and allocate memory to hold new key */ if (sa->aead) free (sa->aead); if (strlen (alg_name) >= sizeof (sa->aead->alg_name) || (sa->aead = calloc (1, newlen)) == NULL) return -1; /* Save the new info */ strcpy (sa->aead->alg_name, alg_name); sa->aead->alg_key_len = key_len; sa->aead->alg_icv_len = icv_len; memcpy (sa->aead->alg_key, key, keysize); sa->ce_mask |= XFRM_SA_ATTR_ALG_AEAD; return 0; } /** * Get the auth-params * @arg sa the xfrmnl_sa object * @arg alg_name an optional output buffer for the algorithm name. Must be at least 64 bytes. * @arg key_len an optional output value for the key length in bits. * @arg trunc_len an optional output value for the alg-trunc-len. * @arg key an optional buffer large enough for the key. It must contain at least * ((@key_len + 7) / 8) bytes. * * Warning: you must ensure that @key is large enough. If you don't know the key_len before-hand, * call xfrmnl_sa_get_auth_params() without @key argument to query only the required buffer size. * This modified API is available in all versions of libnl3 that support the capability * @def NL_CAPABILITY_XFRM_SA_KEY_SIZE (@see nl_has_capability for further information). * * @return 0 on success or a negative error code. */ int xfrmnl_sa_get_auth_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int* key_len, unsigned int* trunc_len, char* key) { if (sa->ce_mask & XFRM_SA_ATTR_ALG_AUTH) { if (alg_name) strcpy (alg_name, sa->auth->alg_name); if (key_len) *key_len = sa->auth->alg_key_len; if (trunc_len) *trunc_len = sa->auth->alg_trunc_len; if (key) memcpy (key, sa->auth->alg_key, (sa->auth->alg_key_len + 7)/8); } else return -1; return 0; } int xfrmnl_sa_set_auth_params (struct xfrmnl_sa* sa, const char* alg_name, unsigned int key_len, unsigned int trunc_len, const char* key) { size_t keysize = sizeof (uint8_t) * ((key_len + 7)/8); uint32_t newlen = sizeof (struct xfrmnl_algo_auth) + keysize; /* Free up the old auth data and allocate new one */ if (sa->auth) free (sa->auth); if (strlen (alg_name) >= sizeof (sa->auth->alg_name) || (sa->auth = calloc (1, newlen)) == NULL) return -1; /* Save the new info */ strcpy (sa->auth->alg_name, alg_name); sa->auth->alg_key_len = key_len; sa->auth->alg_trunc_len = trunc_len; memcpy (sa->auth->alg_key, key, keysize); sa->ce_mask |= XFRM_SA_ATTR_ALG_AUTH; return 0; } /** * Get the crypto-params * @arg sa the xfrmnl_sa object * @arg alg_name an optional output buffer for the algorithm name. Must be at least 64 bytes. * @arg key_len an optional output value for the key length in bits. * @arg key an optional buffer large enough for the key. It must contain at least * ((@key_len + 7) / 8) bytes. * * Warning: you must ensure that @key is large enough. If you don't know the key_len before-hand, * call xfrmnl_sa_get_crypto_params() without @key argument to query only the required buffer size. * This modified API is available in all versions of libnl3 that support the capability * @def NL_CAPABILITY_XFRM_SA_KEY_SIZE (@see nl_has_capability for further information). * * @return 0 on success or a negative error code. */ int xfrmnl_sa_get_crypto_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int* key_len, char* key) { if (sa->ce_mask & XFRM_SA_ATTR_ALG_CRYPT) { if (alg_name) strcpy (alg_name, sa->crypt->alg_name); if (key_len) *key_len = sa->crypt->alg_key_len; if (key) memcpy (key, sa->crypt->alg_key, ((sa->crypt->alg_key_len + 7)/8)); } else return -1; return 0; } int xfrmnl_sa_set_crypto_params (struct xfrmnl_sa* sa, const char* alg_name, unsigned int key_len, const char* key) { size_t keysize = sizeof (uint8_t) * ((key_len + 7)/8); uint32_t newlen = sizeof (struct xfrmnl_algo) + keysize; /* Free up the old crypto and allocate new one */ if (sa->crypt) free (sa->crypt); if (strlen (alg_name) >= sizeof (sa->crypt->alg_name) || (sa->crypt = calloc (1, newlen)) == NULL) return -1; /* Save the new info */ strcpy (sa->crypt->alg_name, alg_name); sa->crypt->alg_key_len = key_len; memcpy (sa->crypt->alg_key, key, keysize); sa->ce_mask |= XFRM_SA_ATTR_ALG_CRYPT; return 0; } /** * Get the comp-params * @arg sa the xfrmnl_sa object * @arg alg_name an optional output buffer for the algorithm name. Must be at least 64 bytes. * @arg key_len an optional output value for the key length in bits. * @arg key an optional buffer large enough for the key. It must contain at least * ((@key_len + 7) / 8) bytes. * * Warning: you must ensure that @key is large enough. If you don't know the key_len before-hand, * call xfrmnl_sa_get_comp_params() without @key argument to query only the required buffer size. * This modified API is available in all versions of libnl3 that support the capability * @def NL_CAPABILITY_XFRM_SA_KEY_SIZE (@see nl_has_capability for further information). * * @return 0 on success or a negative error code. */ int xfrmnl_sa_get_comp_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int* key_len, char* key) { if (sa->ce_mask & XFRM_SA_ATTR_ALG_COMP) { if (alg_name) strcpy (alg_name, sa->comp->alg_name); if (key_len) *key_len = sa->comp->alg_key_len; if (key) memcpy (key, sa->comp->alg_key, ((sa->comp->alg_key_len + 7)/8)); } else return -1; return 0; } int xfrmnl_sa_set_comp_params (struct xfrmnl_sa* sa, const char* alg_name, unsigned int key_len, const char* key) { size_t keysize = sizeof (uint8_t) * ((key_len + 7)/8); uint32_t newlen = sizeof (struct xfrmnl_algo) + keysize; /* Free up the old compression algo params and allocate new one */ if (sa->comp) free (sa->comp); if (strlen (alg_name) >= sizeof (sa->comp->alg_name) || (sa->comp = calloc (1, newlen)) == NULL) return -1; /* Save the new info */ strcpy (sa->comp->alg_name, alg_name); sa->comp->alg_key_len = key_len; memcpy (sa->comp->alg_key, key, keysize); sa->ce_mask |= XFRM_SA_ATTR_ALG_COMP; return 0; } int xfrmnl_sa_get_encap_tmpl (struct xfrmnl_sa* sa, unsigned int* encap_type, unsigned int* encap_sport, unsigned int* encap_dport, struct nl_addr** encap_oa) { if (sa->ce_mask & XFRM_SA_ATTR_ENCAP) { *encap_type = sa->encap->encap_type; *encap_sport = sa->encap->encap_sport; *encap_dport = sa->encap->encap_dport; *encap_oa = nl_addr_clone (sa->encap->encap_oa); } else return -1; return 0; } int xfrmnl_sa_set_encap_tmpl (struct xfrmnl_sa* sa, unsigned int encap_type, unsigned int encap_sport, unsigned int encap_dport, struct nl_addr* encap_oa) { if (sa->encap) { /* Free up the old encap OA */ if (sa->encap->encap_oa) nl_addr_put(sa->encap->encap_oa); memset(sa->encap, 0, sizeof (*sa->encap)); } else if ((sa->encap = calloc(1, sizeof(*sa->encap))) == NULL) return -1; /* Save the new info */ sa->encap->encap_type = encap_type; sa->encap->encap_sport = encap_sport; sa->encap->encap_dport = encap_dport; nl_addr_get (encap_oa); sa->encap->encap_oa = encap_oa; sa->ce_mask |= XFRM_SA_ATTR_ENCAP; return 0; } int xfrmnl_sa_get_tfcpad (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_TFCPAD) return sa->tfcpad; else return -1; } int xfrmnl_sa_set_tfcpad (struct xfrmnl_sa* sa, unsigned int tfcpad) { sa->tfcpad = tfcpad; sa->ce_mask |= XFRM_SA_ATTR_TFCPAD; return 0; } struct nl_addr* xfrmnl_sa_get_coaddr (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_COADDR) return sa->coaddr; else return NULL; } int xfrmnl_sa_set_coaddr (struct xfrmnl_sa* sa, struct nl_addr* coaddr) { /* Free up the old coaddr */ if (sa->coaddr) nl_addr_put (sa->coaddr); /* Save the new info */ nl_addr_get (coaddr); sa->coaddr = coaddr; sa->ce_mask |= XFRM_SA_ATTR_COADDR; return 0; } int xfrmnl_sa_get_mark (struct xfrmnl_sa* sa, unsigned int* mark_mask, unsigned int* mark_value) { if (mark_mask == NULL || mark_value == NULL) return -1; if (sa->ce_mask & XFRM_SA_ATTR_MARK) { *mark_mask = sa->mark.m; *mark_value = sa->mark.v; return 0; } else return -1; } int xfrmnl_sa_set_mark (struct xfrmnl_sa* sa, unsigned int value, unsigned int mask) { sa->mark.v = value; sa->mark.m = mask; sa->ce_mask |= XFRM_SA_ATTR_MARK; return 0; } /** * Get the security context. * * @arg sa The xfrmnl_sa object. * @arg doi An optional output value for the security context domain of interpretation. * @arg alg An optional output value for the security context algorithm. * @arg len An optional output value for the security context length, including the * terminating null byte ('\0'). * @arg sid Unused parameter. * @arg ctx_str An optional buffer large enough for the security context string. It must * contain at least @len bytes. * * Warning: you must ensure that @ctx_str is large enough. If you don't know the length before-hand, * call xfrmnl_sa_get_sec_ctx() without @ctx_str argument to query only the required buffer size. * This modified API is available in all versions of libnl3 that support the capability * @def NL_CAPABILITY_XFRM_SEC_CTX_LEN (@see nl_has_capability for further information). * * @return 0 on success or a negative error code. */ int xfrmnl_sa_get_sec_ctx (struct xfrmnl_sa* sa, unsigned int* doi, unsigned int* alg, unsigned int* len, unsigned int* sid, char* ctx_str) { if (sa->ce_mask & XFRM_SA_ATTR_SECCTX) { if (doi) *doi = sa->sec_ctx->ctx_doi; if (alg) *alg = sa->sec_ctx->ctx_alg; if (len) *len = sa->sec_ctx->ctx_len; if (ctx_str) memcpy (ctx_str, sa->sec_ctx->ctx, sa->sec_ctx->ctx_len); } else return -1; return 0; } /** * Set the security context. * * @arg sa The xfrmnl_sa object. * @arg doi Parameter for the security context domain of interpretation. * @arg alg Parameter for the security context algorithm. * @arg len Parameter for the length of the security context string containing * the terminating null byte ('\0'). * @arg sid Unused parameter. * @arg ctx_str Buffer containing the security context string. * * @return 0 on success or a negative error code. */ int xfrmnl_sa_set_sec_ctx (struct xfrmnl_sa* sa, unsigned int doi, unsigned int alg, unsigned int len, unsigned int sid, const char* ctx_str) { /* Free up the old context string and allocate new one */ if (sa->sec_ctx) free (sa->sec_ctx); if ((sa->sec_ctx = calloc(1, sizeof (struct xfrmnl_user_sec_ctx) + len)) == NULL) return -1; /* Save the new info */ sa->sec_ctx->len = sizeof(struct xfrmnl_user_sec_ctx) + len; sa->sec_ctx->exttype = XFRMA_SEC_CTX; sa->sec_ctx->ctx_alg = alg; sa->sec_ctx->ctx_doi = doi; sa->sec_ctx->ctx_len = len; memcpy (sa->sec_ctx->ctx, ctx_str, len); sa->ce_mask |= XFRM_SA_ATTR_SECCTX; return 0; } int xfrmnl_sa_get_replay_maxage (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_REPLAY_MAXAGE) return sa->replay_maxage; else return -1; } int xfrmnl_sa_set_replay_maxage (struct xfrmnl_sa* sa, unsigned int replay_maxage) { sa->replay_maxage = replay_maxage; sa->ce_mask |= XFRM_SA_ATTR_REPLAY_MAXAGE; return 0; } int xfrmnl_sa_get_replay_maxdiff (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_REPLAY_MAXDIFF) return sa->replay_maxdiff; else return -1; } int xfrmnl_sa_set_replay_maxdiff (struct xfrmnl_sa* sa, unsigned int replay_maxdiff) { sa->replay_maxdiff = replay_maxdiff; sa->ce_mask |= XFRM_SA_ATTR_REPLAY_MAXDIFF; return 0; } int xfrmnl_sa_get_replay_state (struct xfrmnl_sa* sa, unsigned int* oseq, unsigned int* seq, unsigned int* bmp) { if (sa->ce_mask & XFRM_SA_ATTR_REPLAY_STATE) { if (sa->replay_state_esn == NULL) { *oseq = sa->replay_state.oseq; *seq = sa->replay_state.seq; *bmp = sa->replay_state.bitmap; return 0; } else { return -1; } } else return -1; } int xfrmnl_sa_set_replay_state (struct xfrmnl_sa* sa, unsigned int oseq, unsigned int seq, unsigned int bitmap) { sa->replay_state.oseq = oseq; sa->replay_state.seq = seq; sa->replay_state.bitmap = bitmap; sa->ce_mask |= XFRM_SA_ATTR_REPLAY_STATE; return 0; } int xfrmnl_sa_get_replay_state_esn (struct xfrmnl_sa* sa, unsigned int* oseq, unsigned int* seq, unsigned int* oseq_hi, unsigned int* seq_hi, unsigned int* replay_window, unsigned int* bmp_len, unsigned int* bmp) { if (sa->ce_mask & XFRM_SA_ATTR_REPLAY_STATE) { if (sa->replay_state_esn) { *oseq = sa->replay_state_esn->oseq; *seq = sa->replay_state_esn->seq; *oseq_hi= sa->replay_state_esn->oseq_hi; *seq_hi = sa->replay_state_esn->seq_hi; *replay_window = sa->replay_state_esn->replay_window; *bmp_len = sa->replay_state_esn->bmp_len; // In number of 32 bit words memcpy (bmp, sa->replay_state_esn->bmp, sa->replay_state_esn->bmp_len * sizeof (uint32_t)); return 0; } else { return -1; } } else return -1; } int xfrmnl_sa_set_replay_state_esn (struct xfrmnl_sa* sa, unsigned int oseq, unsigned int seq, unsigned int oseq_hi, unsigned int seq_hi, unsigned int replay_window, unsigned int bmp_len, unsigned int* bmp) { /* Free the old replay state and allocate space to hold new one */ if (sa->replay_state_esn) free (sa->replay_state_esn); if ((sa->replay_state_esn = calloc (1, sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * bmp_len))) == NULL) return -1; sa->replay_state_esn->oseq = oseq; sa->replay_state_esn->seq = seq; sa->replay_state_esn->oseq_hi = oseq_hi; sa->replay_state_esn->seq_hi = seq_hi; sa->replay_state_esn->replay_window = replay_window; sa->replay_state_esn->bmp_len = bmp_len; // In number of 32 bit words memcpy (sa->replay_state_esn->bmp, bmp, bmp_len * sizeof (uint32_t)); sa->ce_mask |= XFRM_SA_ATTR_REPLAY_STATE; return 0; } int xfrmnl_sa_is_hardexpiry_reached (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_EXPIRE) return (sa->hard > 0 ? 1: 0); else return 0; } int xfrmnl_sa_is_expiry_reached (struct xfrmnl_sa* sa) { if (sa->ce_mask & XFRM_SA_ATTR_EXPIRE) return 1; else return 0; } /** @} */ static struct nl_object_ops xfrm_sa_obj_ops = { .oo_name = "xfrm/sa", .oo_size = sizeof(struct xfrmnl_sa), .oo_constructor = xfrm_sa_alloc_data, .oo_free_data = xfrm_sa_free_data, .oo_clone = xfrm_sa_clone, .oo_dump = { [NL_DUMP_LINE] = xfrm_sa_dump_line, [NL_DUMP_DETAILS] = xfrm_sa_dump_details, [NL_DUMP_STATS] = xfrm_sa_dump_stats, }, .oo_compare = xfrm_sa_compare, .oo_attrs2str = xfrm_sa_attrs2str, .oo_id_attrs = (XFRM_SA_ATTR_DADDR | XFRM_SA_ATTR_SPI | XFRM_SA_ATTR_PROTO), }; static struct nl_af_group xfrm_sa_groups[] = { { AF_UNSPEC, XFRMNLGRP_SA }, { AF_UNSPEC, XFRMNLGRP_EXPIRE }, { END_OF_GROUP_LIST }, }; static struct nl_cache_ops xfrmnl_sa_ops = { .co_name = "xfrm/sa", .co_hdrsize = sizeof(struct xfrm_usersa_info), .co_msgtypes = { { XFRM_MSG_NEWSA, NL_ACT_NEW, "new" }, { XFRM_MSG_DELSA, NL_ACT_DEL, "del" }, { XFRM_MSG_GETSA, NL_ACT_GET, "get" }, { XFRM_MSG_EXPIRE, NL_ACT_UNSPEC, "expire"}, { XFRM_MSG_UPDSA, NL_ACT_NEW, "update"}, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_XFRM, .co_groups = xfrm_sa_groups, .co_request_update = xfrm_sa_request_update, .co_msg_parser = xfrm_sa_msg_parser, .co_obj_ops = &xfrm_sa_obj_ops, .co_include_event = &xfrm_sa_update_cache }; /** * @name XFRM SA Cache Managament * @{ */ static void __attribute__ ((constructor)) xfrm_sa_init(void) { nl_cache_mngt_register(&xfrmnl_sa_ops); } static void __attribute__ ((destructor)) xfrm_sa_exit(void) { nl_cache_mngt_unregister(&xfrmnl_sa_ops); } /** @} */ libnl-3.2.29/lib/xfrm/ae.c0000644000175000017500000006622013023014600012076 00000000000000/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * @ingroup xfrmnl * @defgroup ae Attribute Element * @brief * * The AE interface allows a user to retrieve and update various * Security Association (SA) attributes such as lifetime, replay state etc. * * @par AE Flags * @code * XFRM_AE_UNSPEC * XFRM_AE_RTHR=1 * XFRM_AE_RVAL=2 * XFRM_AE_LVAL=4 * XFRM_AE_ETHR=8 * XFRM_AE_CR=16 * XFRM_AE_CE=32 * XFRM_AE_CU=64 * @endcode * * @par AE Identification * An AE is uniquely identified by the attributes listed below, whenever * you refer to an existing AE all of the attributes must be set. There is * no cache support for AE since you can retrieve the AE for any given combination * of attributes mentioned below, but not all at once since they just characterize * an SA. * - destination address (xfrmnl_ae_set_daddr()) * - SPI (xfrmnl_ae_set_spi) * - protocol (xfrmnl_ae_set_proto) * - mark (xfrmnl_ae_set_mark) * * @par Changeable Attributes * \anchor ae_changeable * - current lifetime (xfrmnl_ae_set_curlifetime()) * - replay properties (xfrmnl_ae_set_replay_maxage(), xfrmnl_ae_set_replay_maxdiff()) * - replay state (xfrmnl_ae_set_replay_state(), xfrmnl_ae_set_replay_state_esn)) * * @par Required Caches for Dumping * None * * @par TODO * None * * @par 1) Retrieving AE information for a given SA tuple * @code * // Create a netlink socket and connect it to XFRM subsystem in * the kernel to be able to send/receive info from userspace. * struct nl_sock* sk = nl_socket_alloc (); * nl_connect (sk, NETLINK_XFRM); * * // AEs can then be looked up by the SA tuple, destination address, * SPI, protocol, mark: * struct xfrmnl_ae *ae; * xfrmnl_ae_get_kernel(sk, dst_addr, spi, proto,mark_mask, mark_value, &ae); * * // After successful usage, the object must be freed * xfrmnl_ae_put(ae); * @endcode * * @par 2) Updating AE * @code * // Allocate an empty AE handle to be filled out with the attributes * // of the new AE. * struct xfrmnl_ae *ae = xfrmnl_ae_alloc(); * * // Fill out the attributes of the new AE * xfrmnl_ae_set_daddr(ae, dst_addr); * xfrmnl_ae_set_spi(ae, 0xDEADBEEF); * xfrmnl_ae_set_proto(ae, 50); * xfrmnl_ae_set_mark(ae, 0x0); * xfrmnl_ae_set_saddr(ae, src_addr); * xfrmnl_ae_set_curlifetime(ae, 540, 10, 0xAABB1122, 0x0); * * // Build the netlink message and send it to the kernel, the operation will * // block until the operation has been completed. Alternatively, a netlink message * // can be built using xfrmnl_ae_build_get_request () API and be sent using * // nl_send_auto(). Further the result from the kernel can be parsed using * // xfrmnl_ae_parse() API. * xfrmnl_ae_set(sk, ae, NLM_F_REPLACE); * * // Free the memory * xfrmnl_ae_put(ae); * @endcode * * @{ */ #include #include #include #include #include /** @cond SKIP */ #define XFRM_AE_ATTR_DADDR 0x01 #define XFRM_AE_ATTR_SPI 0x02 #define XFRM_AE_ATTR_PROTO 0x04 #define XFRM_AE_ATTR_SADDR 0x08 #define XFRM_AE_ATTR_FLAGS 0x10 #define XFRM_AE_ATTR_REQID 0x20 #define XFRM_AE_ATTR_MARK 0x40 #define XFRM_AE_ATTR_LIFETIME 0x80 #define XFRM_AE_ATTR_REPLAY_MAXAGE 0x100 #define XFRM_AE_ATTR_REPLAY_MAXDIFF 0x200 #define XFRM_AE_ATTR_REPLAY_STATE 0x400 #define XFRM_AE_ATTR_FAMILY 0x800 static struct nl_object_ops xfrm_ae_obj_ops; /** @endcond */ static void xfrm_ae_free_data(struct nl_object *c) { struct xfrmnl_ae* ae = nl_object_priv (c); if (ae == NULL) return; nl_addr_put (ae->sa_id.daddr); nl_addr_put (ae->saddr); if (ae->replay_state_esn) free (ae->replay_state_esn); } static int xfrm_ae_clone(struct nl_object *_dst, struct nl_object *_src) { struct xfrmnl_ae* dst = nl_object_priv(_dst); struct xfrmnl_ae* src = nl_object_priv(_src); if (src->sa_id.daddr) if ((dst->sa_id.daddr = nl_addr_clone (src->sa_id.daddr)) == NULL) return -NLE_NOMEM; if (src->saddr) if ((dst->saddr = nl_addr_clone (src->saddr)) == NULL) return -NLE_NOMEM; if (src->replay_state_esn) { uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * src->replay_state_esn->bmp_len); if ((dst->replay_state_esn = (struct xfrmnl_replay_state_esn*)calloc (1, len)) == NULL) return -NLE_NOMEM; memcpy (dst->replay_state_esn, dst->replay_state_esn, len); } return 0; } static uint64_t xfrm_ae_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct xfrmnl_ae* a = (struct xfrmnl_ae *) _a; struct xfrmnl_ae* b = (struct xfrmnl_ae *) _b; uint64_t diff = 0; int found = 0; #define XFRM_AE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, XFRM_AE_ATTR_##ATTR, a, b, EXPR) diff |= XFRM_AE_DIFF(DADDR, nl_addr_cmp(a->sa_id.daddr, b->sa_id.daddr)); diff |= XFRM_AE_DIFF(SPI, a->sa_id.spi != b->sa_id.spi); diff |= XFRM_AE_DIFF(PROTO, a->sa_id.proto != b->sa_id.proto); diff |= XFRM_AE_DIFF(SADDR, nl_addr_cmp(a->saddr, b->saddr)); diff |= XFRM_AE_DIFF(FLAGS, a->flags != b->flags); diff |= XFRM_AE_DIFF(REQID, a->reqid != b->reqid); diff |= XFRM_AE_DIFF(MARK, (a->mark.v & a->mark.m) != (b->mark.v & b->mark.m)); diff |= XFRM_AE_DIFF(REPLAY_MAXAGE, a->replay_maxage != b->replay_maxage); diff |= XFRM_AE_DIFF(REPLAY_MAXDIFF, a->replay_maxdiff != b->replay_maxdiff); /* Compare replay states */ found = AVAILABLE_MISMATCH (a, b, XFRM_AE_ATTR_REPLAY_STATE); if (found == 0) // attribute exists in both objects { if (((a->replay_state_esn != NULL) && (b->replay_state_esn == NULL)) || ((a->replay_state_esn == NULL) && (b->replay_state_esn != NULL))) found |= 1; if (found == 0) // same replay type. compare actual values { if (a->replay_state_esn) { if (a->replay_state_esn->bmp_len != b->replay_state_esn->bmp_len) diff |= 1; else { uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * a->replay_state_esn->bmp_len); diff |= memcmp (a->replay_state_esn, b->replay_state_esn, len); } } else { if ((a->replay_state.oseq != b->replay_state.oseq) || (a->replay_state.seq != b->replay_state.seq) || (a->replay_state.bitmap != b->replay_state.bitmap)) diff |= 1; } } } #undef XFRM_AE_DIFF return diff; } /** * @name XFRM AE Attribute Translations * @{ */ static const struct trans_tbl ae_attrs[] = { __ADD(XFRM_AE_ATTR_DADDR, daddr), __ADD(XFRM_AE_ATTR_SPI, spi), __ADD(XFRM_AE_ATTR_PROTO, protocol), __ADD(XFRM_AE_ATTR_SADDR, saddr), __ADD(XFRM_AE_ATTR_FLAGS, flags), __ADD(XFRM_AE_ATTR_REQID, reqid), __ADD(XFRM_AE_ATTR_MARK, mark), __ADD(XFRM_AE_ATTR_LIFETIME, cur_lifetime), __ADD(XFRM_AE_ATTR_REPLAY_MAXAGE, replay_maxage), __ADD(XFRM_AE_ATTR_REPLAY_MAXDIFF, replay_maxdiff), __ADD(XFRM_AE_ATTR_REPLAY_STATE, replay_state), }; static char* xfrm_ae_attrs2str (int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, ae_attrs, ARRAY_SIZE(ae_attrs)); } /** @} */ /** * @name XFRM AE Flags Translations * @{ */ static const struct trans_tbl ae_flags[] = { __ADD(XFRM_AE_UNSPEC, unspecified), __ADD(XFRM_AE_RTHR, replay threshold), __ADD(XFRM_AE_RVAL, replay value), __ADD(XFRM_AE_LVAL, lifetime value), __ADD(XFRM_AE_ETHR, expiry time threshold), __ADD(XFRM_AE_CR, replay update event), __ADD(XFRM_AE_CE, timer expiry event), __ADD(XFRM_AE_CU, policy update event), }; char* xfrmnl_ae_flags2str(int flags, char *buf, size_t len) { return __flags2str (flags, buf, len, ae_flags, ARRAY_SIZE(ae_flags)); } int xfrmnl_ae_str2flag(const char *name) { return __str2flags(name, ae_flags, ARRAY_SIZE(ae_flags)); } /** @} */ static void xfrm_ae_dump_line(struct nl_object *a, struct nl_dump_params *p) { char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5]; struct xfrmnl_ae* ae = (struct xfrmnl_ae *) a; char flags[128], buf[128]; time_t add_time, use_time; struct tm *add_time_tm, *use_time_tm; nl_dump_line(p, "src %s dst %s \n", nl_addr2str(ae->saddr, src, sizeof(src)), nl_addr2str(ae->sa_id.daddr, dst, sizeof(dst))); nl_dump_line(p, "\tproto %s spi 0x%x reqid %u ", nl_ip_proto2str (ae->sa_id.proto, buf, sizeof (buf)), ae->sa_id.spi, ae->reqid); xfrmnl_ae_flags2str(ae->flags, flags, sizeof (flags)); nl_dump_line(p, "flags %s(0x%x) mark mask/value 0x%x/0x%x \n", flags, ae->flags, ae->mark.m, ae->mark.v); nl_dump_line(p, "\tlifetime current: \n"); nl_dump_line(p, "\t\tbytes %llu packets %llu \n", ae->lifetime_cur.bytes, ae->lifetime_cur.packets); if (ae->lifetime_cur.add_time != 0) { add_time = ae->lifetime_cur.add_time; add_time_tm = gmtime (&add_time); strftime (flags, 128, "%Y-%m-%d %H-%M-%S", add_time_tm); } else { sprintf (flags, "%s", "-"); } if (ae->lifetime_cur.use_time != 0) { use_time = ae->lifetime_cur.use_time; use_time_tm = gmtime (&use_time); strftime (buf, 128, "%Y-%m-%d %H-%M-%S", use_time_tm); } else { sprintf (buf, "%s", "-"); } nl_dump_line(p, "\t\tadd_time: %s, use_time: %s\n", flags, buf); nl_dump_line(p, "\treplay info: \n"); nl_dump_line(p, "\t\tmax age %u max diff %u \n", ae->replay_maxage, ae->replay_maxdiff); nl_dump_line(p, "\treplay state info: \n"); if (ae->replay_state_esn) { nl_dump_line(p, "\t\toseq %u seq %u oseq_hi %u seq_hi %u replay window: %u \n", ae->replay_state_esn->oseq, ae->replay_state_esn->seq, ae->replay_state_esn->oseq_hi, ae->replay_state_esn->seq_hi, ae->replay_state_esn->replay_window); } else { nl_dump_line(p, "\t\toseq %u seq %u bitmap: %u \n", ae->replay_state.oseq, ae->replay_state.seq, ae->replay_state.bitmap); } nl_dump(p, "\n"); } static void xfrm_ae_dump_details(struct nl_object *a, struct nl_dump_params *p) { xfrm_ae_dump_line(a, p); } static void xfrm_ae_dump_stats(struct nl_object *a, struct nl_dump_params *p) { xfrm_ae_dump_details(a, p); } static int build_xfrm_ae_message(struct xfrmnl_ae *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg* msg; struct xfrm_aevent_id ae_id; if (!(tmpl->ce_mask & XFRM_AE_ATTR_DADDR) || !(tmpl->ce_mask & XFRM_AE_ATTR_SPI) || !(tmpl->ce_mask & XFRM_AE_ATTR_PROTO)) return -NLE_MISSING_ATTR; memcpy (&ae_id.sa_id.daddr, nl_addr_get_binary_addr (tmpl->sa_id.daddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->sa_id.daddr)); ae_id.sa_id.spi = htonl(tmpl->sa_id.spi); ae_id.sa_id.family = tmpl->sa_id.family; ae_id.sa_id.proto = tmpl->sa_id.proto; if (tmpl->ce_mask & XFRM_AE_ATTR_SADDR) memcpy (&ae_id.saddr, nl_addr_get_binary_addr (tmpl->saddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->saddr)); if (tmpl->ce_mask & XFRM_AE_ATTR_FLAGS) ae_id.flags = tmpl->flags; if (tmpl->ce_mask & XFRM_AE_ATTR_REQID) ae_id.reqid = tmpl->reqid; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &ae_id, sizeof(ae_id), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tmpl->ce_mask & XFRM_AE_ATTR_MARK) NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrmnl_mark), &tmpl->mark); if (tmpl->ce_mask & XFRM_AE_ATTR_LIFETIME) NLA_PUT (msg, XFRMA_LTIME_VAL, sizeof (struct xfrmnl_lifetime_cur), &tmpl->lifetime_cur); if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXAGE) NLA_PUT_U32 (msg, XFRMA_ETIMER_THRESH, tmpl->replay_maxage); if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXDIFF) NLA_PUT_U32 (msg, XFRMA_REPLAY_THRESH, tmpl->replay_maxdiff); if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_STATE) { if (tmpl->replay_state_esn) { uint32_t len = sizeof (struct xfrm_replay_state_esn) + (sizeof (uint32_t) * tmpl->replay_state_esn->bmp_len); NLA_PUT (msg, XFRMA_REPLAY_ESN_VAL, len, tmpl->replay_state_esn); } else { NLA_PUT (msg, XFRMA_REPLAY_VAL, sizeof (struct xfrmnl_replay_state), &tmpl->replay_state); } } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * @name XFRM AE Update * @{ */ int xfrmnl_ae_set(struct nl_sock* sk, struct xfrmnl_ae* ae, int flags) { int err; struct nl_msg *msg; if ((err = build_xfrm_ae_message(ae, XFRM_MSG_NEWAE, flags|NLM_F_REPLACE, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); } /** @} */ /** * @name XFRM AE Object Allocation/Freeage * @{ */ struct xfrmnl_ae* xfrmnl_ae_alloc(void) { return (struct xfrmnl_ae*) nl_object_alloc(&xfrm_ae_obj_ops); } void xfrmnl_ae_put(struct xfrmnl_ae* ae) { nl_object_put((struct nl_object *) ae); } /** @} */ static struct nla_policy xfrm_ae_policy[XFRMA_MAX+1] = { [XFRMA_LTIME_VAL] = { .minlen = sizeof(struct xfrm_lifetime_cur) }, [XFRMA_REPLAY_VAL] = { .minlen = sizeof(struct xfrm_replay_state) }, [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 }, [XFRMA_ETIMER_THRESH] = { .type = NLA_U32 }, [XFRMA_SRCADDR] = { .minlen = sizeof(xfrm_address_t) }, [XFRMA_MARK] = { .minlen = sizeof(struct xfrm_mark) }, [XFRMA_REPLAY_ESN_VAL] = { .minlen = sizeof(struct xfrm_replay_state_esn) }, }; int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result) { struct xfrmnl_ae* ae; struct nlattr *tb[XFRMA_MAX + 1]; struct xfrm_aevent_id* ae_id; int err; ae = xfrmnl_ae_alloc(); if (!ae) { err = -NLE_NOMEM; goto errout; } ae->ce_msgtype = n->nlmsg_type; ae_id = nlmsg_data(n); err = nlmsg_parse(n, sizeof(struct xfrm_aevent_id), tb, XFRMA_MAX, xfrm_ae_policy); if (err < 0) goto errout; ae->sa_id.daddr = nl_addr_build(ae_id->sa_id.family, &ae_id->sa_id.daddr, sizeof (ae_id->sa_id.daddr)); ae->sa_id.family= ae_id->sa_id.family; ae->sa_id.spi = ntohl(ae_id->sa_id.spi); ae->sa_id.proto = ae_id->sa_id.proto; ae->saddr = nl_addr_build(ae_id->sa_id.family, &ae_id->saddr, sizeof (ae_id->saddr)); ae->reqid = ae_id->reqid; ae->flags = ae_id->flags; ae->ce_mask |= (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_FAMILY | XFRM_AE_ATTR_SPI | XFRM_AE_ATTR_PROTO | XFRM_AE_ATTR_SADDR | XFRM_AE_ATTR_REQID | XFRM_AE_ATTR_FLAGS); if (tb[XFRMA_MARK]) { struct xfrm_mark* m = nla_data(tb[XFRMA_MARK]); ae->mark.m = m->m; ae->mark.v = m->v; ae->ce_mask |= XFRM_AE_ATTR_MARK; } if (tb[XFRMA_LTIME_VAL]) { struct xfrm_lifetime_cur* cur = nla_data(tb[XFRMA_LTIME_VAL]); ae->lifetime_cur.bytes = cur->bytes; ae->lifetime_cur.packets = cur->packets; ae->lifetime_cur.add_time = cur->add_time; ae->lifetime_cur.use_time = cur->use_time; ae->ce_mask |= XFRM_AE_ATTR_LIFETIME; } if (tb[XFRM_AE_ETHR]) { ae->replay_maxage = *(uint32_t*)nla_data(tb[XFRM_AE_ETHR]); ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXAGE; } if (tb[XFRM_AE_RTHR]) { ae->replay_maxdiff = *(uint32_t*)nla_data(tb[XFRM_AE_RTHR]); ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXDIFF; } if (tb[XFRMA_REPLAY_ESN_VAL]) { struct xfrm_replay_state_esn* esn = nla_data (tb[XFRMA_REPLAY_ESN_VAL]); uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * esn->bmp_len); if ((ae->replay_state_esn = calloc (1, len)) == NULL) { err = -ENOMEM; goto errout; } ae->replay_state_esn->oseq = esn->oseq; ae->replay_state_esn->seq = esn->seq; ae->replay_state_esn->oseq_hi = esn->oseq_hi; ae->replay_state_esn->seq_hi = esn->seq_hi; ae->replay_state_esn->replay_window = esn->replay_window; ae->replay_state_esn->bmp_len = esn->bmp_len; memcpy (ae->replay_state_esn->bmp, esn->bmp, sizeof (uint32_t) * esn->bmp_len); ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE; } else { struct xfrm_replay_state* replay_state = nla_data (tb[XFRMA_REPLAY_VAL]); ae->replay_state.oseq = replay_state->oseq; ae->replay_state.seq = replay_state->seq; ae->replay_state.bitmap = replay_state->bitmap; ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE; ae->replay_state_esn = NULL; } *result = ae; return 0; errout: xfrmnl_ae_put(ae); return err; } static int xfrm_ae_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct xfrmnl_ae* ae; int err; if ((err = xfrmnl_ae_parse(n, &ae)) < 0) return err; err = pp->pp_cb((struct nl_object *) ae, pp); xfrmnl_ae_put(ae); return err; } /** * @name XFRM AE Get * @{ */ int xfrmnl_ae_build_get_request(struct nl_addr* daddr, unsigned int spi, unsigned int protocol, unsigned int mark_mask, unsigned int mark_value, struct nl_msg **result) { struct nl_msg *msg; struct xfrm_aevent_id ae_id; struct xfrmnl_mark mark; if (!daddr || !spi) { fprintf(stderr, "APPLICATION BUG: %s:%d:%s: A valid destination address, spi must be specified\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); assert(0); return -NLE_MISSING_ATTR; } memset(&ae_id, 0, sizeof(ae_id)); memcpy (&ae_id.sa_id.daddr, nl_addr_get_binary_addr (daddr), sizeof (uint8_t) * nl_addr_get_len (daddr)); ae_id.sa_id.spi = htonl(spi); ae_id.sa_id.family = nl_addr_get_family (daddr); ae_id.sa_id.proto = protocol; if (!(msg = nlmsg_alloc_simple(XFRM_MSG_GETAE, 0))) return -NLE_NOMEM; if (nlmsg_append(msg, &ae_id, sizeof(ae_id), NLMSG_ALIGNTO) < 0) goto nla_put_failure; mark.m = mark_mask; mark.v = mark_value; NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrmnl_mark), &mark); *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } int xfrmnl_ae_get_kernel(struct nl_sock* sock, struct nl_addr* daddr, unsigned int spi, unsigned int protocol, unsigned int mark_mask, unsigned int mark_value, struct xfrmnl_ae** result) { struct nl_msg *msg = NULL; struct nl_object *obj; int err; if ((err = xfrmnl_ae_build_get_request(daddr, spi, protocol, mark_mask, mark_value, &msg)) < 0) return err; err = nl_send_auto(sock, msg); nlmsg_free(msg); if (err < 0) return err; if ((err = nl_pickup(sock, &xfrm_ae_msg_parser, &obj)) < 0) return err; /* We have used xfrm_ae_msg_parser(), object is definitely a xfrm ae */ *result = (struct xfrmnl_ae *) obj; /* If an object has been returned, we also need to wait for the ACK */ if (err == 0 && obj) nl_wait_for_ack(sock); return 0; } /** @} */ /** * @name Attributes * @{ */ static inline int __assign_addr(struct xfrmnl_ae* ae, struct nl_addr **pos, struct nl_addr *new, int flag, int nocheck) { if (!nocheck) { if (ae->ce_mask & XFRM_AE_ATTR_FAMILY) { if (nl_addr_get_family (new) != ae->sa_id.family) return -NLE_AF_MISMATCH; } else { ae->sa_id.family = nl_addr_get_family (new); ae->ce_mask |= XFRM_AE_ATTR_FAMILY; } } if (*pos) nl_addr_put(*pos); nl_addr_get(new); *pos = new; ae->ce_mask |= flag; return 0; } struct nl_addr* xfrmnl_ae_get_daddr (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_DADDR) return ae->sa_id.daddr; else return NULL; } int xfrmnl_ae_set_daddr (struct xfrmnl_ae* ae, struct nl_addr* addr) { return __assign_addr(ae, &ae->sa_id.daddr, addr, XFRM_AE_ATTR_DADDR, 0); } int xfrmnl_ae_get_spi (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_SPI) return ae->sa_id.spi; else return -1; } int xfrmnl_ae_set_spi (struct xfrmnl_ae* ae, unsigned int spi) { ae->sa_id.spi = spi; ae->ce_mask |= XFRM_AE_ATTR_SPI; return 0; } int xfrmnl_ae_get_family (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_FAMILY) return ae->sa_id.family; else return -1; } int xfrmnl_ae_set_family (struct xfrmnl_ae* ae, unsigned int family) { ae->sa_id.family = family; ae->ce_mask |= XFRM_AE_ATTR_FAMILY; return 0; } int xfrmnl_ae_get_proto (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_PROTO) return ae->sa_id.proto; else return -1; } int xfrmnl_ae_set_proto (struct xfrmnl_ae* ae, unsigned int protocol) { ae->sa_id.proto = protocol; ae->ce_mask |= XFRM_AE_ATTR_PROTO; return 0; } struct nl_addr* xfrmnl_ae_get_saddr (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_SADDR) return ae->saddr; else return NULL; } int xfrmnl_ae_set_saddr (struct xfrmnl_ae* ae, struct nl_addr* addr) { return __assign_addr(ae, &ae->saddr, addr, XFRM_AE_ATTR_SADDR, 1); } int xfrmnl_ae_get_flags (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_FLAGS) return ae->flags; else return -1; } int xfrmnl_ae_set_flags (struct xfrmnl_ae* ae, unsigned int flags) { ae->flags = flags; ae->ce_mask |= XFRM_AE_ATTR_FLAGS; return 0; } int xfrmnl_ae_get_reqid (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_REQID) return ae->reqid; else return -1; } int xfrmnl_ae_set_reqid (struct xfrmnl_ae* ae, unsigned int reqid) { ae->reqid = reqid; ae->ce_mask |= XFRM_AE_ATTR_REQID; return 0; } int xfrmnl_ae_get_mark (struct xfrmnl_ae* ae, unsigned int* mark_mask, unsigned int* mark_value) { if (mark_mask == NULL || mark_value == NULL) return -1; if (ae->ce_mask & XFRM_AE_ATTR_MARK) { *mark_mask = ae->mark.m; *mark_value = ae->mark.v; return 0; } else return -1; } int xfrmnl_ae_set_mark (struct xfrmnl_ae* ae, unsigned int value, unsigned int mask) { ae->mark.v = value; ae->mark.m = mask; ae->ce_mask |= XFRM_AE_ATTR_MARK; return 0; } int xfrmnl_ae_get_curlifetime (struct xfrmnl_ae* ae, unsigned long long int* curr_bytes, unsigned long long int* curr_packets, unsigned long long int* curr_add_time, unsigned long long int* curr_use_time) { if (curr_bytes == NULL || curr_packets == NULL || curr_add_time == NULL || curr_use_time == NULL) return -1; if (ae->ce_mask & XFRM_AE_ATTR_LIFETIME) { *curr_bytes = ae->lifetime_cur.bytes; *curr_packets = ae->lifetime_cur.packets; *curr_add_time = ae->lifetime_cur.add_time; *curr_use_time = ae->lifetime_cur.use_time; return 0; } else return -1; } int xfrmnl_ae_set_curlifetime (struct xfrmnl_ae* ae, unsigned long long int curr_bytes, unsigned long long int curr_packets, unsigned long long int curr_add_time, unsigned long long int curr_use_time) { ae->lifetime_cur.bytes = curr_bytes; ae->lifetime_cur.packets = curr_packets; ae->lifetime_cur.add_time = curr_add_time; ae->lifetime_cur.use_time = curr_use_time; ae->ce_mask |= XFRM_AE_ATTR_LIFETIME; return 0; } int xfrmnl_ae_get_replay_maxage (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_MAXAGE) return ae->replay_maxage; else return -1; } int xfrmnl_ae_set_replay_maxage (struct xfrmnl_ae* ae, unsigned int replay_maxage) { ae->replay_maxage = replay_maxage; ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXAGE; return 0; } int xfrmnl_ae_get_replay_maxdiff (struct xfrmnl_ae* ae) { if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_MAXDIFF) return ae->replay_maxdiff; else return -1; } int xfrmnl_ae_set_replay_maxdiff (struct xfrmnl_ae* ae, unsigned int replay_maxdiff) { ae->replay_maxdiff = replay_maxdiff; ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXDIFF; return 0; } int xfrmnl_ae_get_replay_state (struct xfrmnl_ae* ae, unsigned int* oseq, unsigned int* seq, unsigned int* bmp) { if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_STATE) { if (ae->replay_state_esn == NULL) { *oseq = ae->replay_state.oseq; *seq = ae->replay_state.seq; *bmp = ae->replay_state.bitmap; return 0; } else { return -1; } } else return -1; } int xfrmnl_ae_set_replay_state (struct xfrmnl_ae* ae, unsigned int oseq, unsigned int seq, unsigned int bitmap) { ae->replay_state.oseq = oseq; ae->replay_state.seq = seq; ae->replay_state.bitmap = bitmap; ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE; return 0; } int xfrmnl_ae_get_replay_state_esn(struct xfrmnl_ae* ae, unsigned int* oseq, unsigned int* seq, unsigned int* oseq_hi, unsigned int* seq_hi, unsigned int* replay_window, unsigned int* bmp_len, unsigned int* bmp) { if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_STATE) { if (ae->replay_state_esn) { *oseq = ae->replay_state_esn->oseq; *seq = ae->replay_state_esn->seq; *oseq_hi= ae->replay_state_esn->oseq_hi; *seq_hi = ae->replay_state_esn->seq_hi; *replay_window = ae->replay_state_esn->replay_window; *bmp_len = ae->replay_state_esn->bmp_len; // In number of 32 bit words memcpy (bmp, ae->replay_state_esn->bmp, ae->replay_state_esn->bmp_len * sizeof (uint32_t)); return 0; } else { return -1; } } else return -1; } int xfrmnl_ae_set_replay_state_esn(struct xfrmnl_ae* ae, unsigned int oseq, unsigned int seq, unsigned int oseq_hi, unsigned int seq_hi, unsigned int replay_window, unsigned int bmp_len, unsigned int* bmp) { /* Free the old replay ESN state and allocate new one */ if (ae->replay_state_esn) free (ae->replay_state_esn); if ((ae->replay_state_esn = calloc (1, sizeof (struct xfrmnl_replay_state_esn) + sizeof (uint32_t) * bmp_len)) == NULL) return -1; ae->replay_state_esn->oseq = oseq; ae->replay_state_esn->seq = seq; ae->replay_state_esn->oseq_hi = oseq_hi; ae->replay_state_esn->seq_hi = seq_hi; ae->replay_state_esn->replay_window = replay_window; ae->replay_state_esn->bmp_len = bmp_len; // In number of 32 bit words memcpy (ae->replay_state_esn->bmp, bmp, bmp_len * sizeof (uint32_t)); ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE; return 0; } /** @} */ static struct nl_object_ops xfrm_ae_obj_ops = { .oo_name = "xfrm/ae", .oo_size = sizeof(struct xfrmnl_ae), .oo_free_data = xfrm_ae_free_data, .oo_clone = xfrm_ae_clone, .oo_dump = { [NL_DUMP_LINE] = xfrm_ae_dump_line, [NL_DUMP_DETAILS] = xfrm_ae_dump_details, [NL_DUMP_STATS] = xfrm_ae_dump_stats, }, .oo_compare = xfrm_ae_compare, .oo_attrs2str = xfrm_ae_attrs2str, .oo_id_attrs = (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_SPI | XFRM_AE_ATTR_PROTO), }; /** @} */ libnl-3.2.29/lib/cache.c0000644000175000017500000007614513023014600011607 00000000000000/* * lib/cache.c Caching Module * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup cache_mngt * @defgroup cache Cache * * @code * Cache Management | | Type Specific Cache Operations * * | | +----------------+ +------------+ * | request update | | msg_parser | * | | +----------------+ +------------+ * +- - - - -^- - - - - - - -^- -|- - - - * nl_cache_update: | | | | * 1) --------- co_request_update ------+ | | * | | | * 2) destroy old cache +----------- pp_cb ---------|---+ * | | | * 3) ---------- nl_recvmsgs ----------+ +- cb_valid -+ * +--------------+ | | | | * | nl_cache_add |<-----+ + - - -v- -|- - - - - - - - - - - * +--------------+ | | +-------------+ * | nl_recvmsgs | * | | +-----|-^-----+ * +---v-|---+ * | | | nl_recv | * +---------+ * | | Core Netlink * @endcode * * Related sections in the development guide: * - @core_doc{core_cache, Caching System} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include #include #include /** * @name Access Functions * @{ */ /** * Return the number of items in the cache * @arg cache cache handle */ int nl_cache_nitems(struct nl_cache *cache) { return cache->c_nitems; } /** * Return the number of items matching a filter in the cache * @arg cache Cache object. * @arg filter Filter object. */ int nl_cache_nitems_filter(struct nl_cache *cache, struct nl_object *filter) { struct nl_object *obj; int nitems = 0; if (cache->c_ops == NULL) BUG(); nl_list_for_each_entry(obj, &cache->c_items, ce_list) { if (filter && !nl_object_match_filter(obj, filter)) continue; nitems++; } return nitems; } /** * Returns \b true if the cache is empty. * @arg cache Cache to check * @return \a true if the cache is empty, otherwise \b false is returned. */ int nl_cache_is_empty(struct nl_cache *cache) { return nl_list_empty(&cache->c_items); } /** * Return the operations set of the cache * @arg cache cache handle */ struct nl_cache_ops *nl_cache_get_ops(struct nl_cache *cache) { return cache->c_ops; } /** * Return the first element in the cache * @arg cache cache handle */ struct nl_object *nl_cache_get_first(struct nl_cache *cache) { if (nl_list_empty(&cache->c_items)) return NULL; return nl_list_entry(cache->c_items.next, struct nl_object, ce_list); } /** * Return the last element in the cache * @arg cache cache handle */ struct nl_object *nl_cache_get_last(struct nl_cache *cache) { if (nl_list_empty(&cache->c_items)) return NULL; return nl_list_entry(cache->c_items.prev, struct nl_object, ce_list); } /** * Return the next element in the cache * @arg obj current object */ struct nl_object *nl_cache_get_next(struct nl_object *obj) { if (nl_list_at_tail(obj, &obj->ce_cache->c_items, ce_list)) return NULL; else return nl_list_entry(obj->ce_list.next, struct nl_object, ce_list); } /** * Return the previous element in the cache * @arg obj current object */ struct nl_object *nl_cache_get_prev(struct nl_object *obj) { if (nl_list_at_head(obj, &obj->ce_cache->c_items, ce_list)) return NULL; else return nl_list_entry(obj->ce_list.prev, struct nl_object, ce_list); } /** @} */ /** * @name Cache Allocation/Deletion * @{ */ /** * Allocate new cache * @arg ops Cache operations * * Allocate and initialize a new cache based on the cache operations * provided. * * @return Allocated cache or NULL if allocation failed. */ struct nl_cache *nl_cache_alloc(struct nl_cache_ops *ops) { struct nl_cache *cache; cache = calloc(1, sizeof(*cache)); if (!cache) return NULL; nl_init_list_head(&cache->c_items); cache->c_ops = ops; cache->c_flags |= ops->co_flags; cache->c_refcnt = 1; /* * If object type provides a hash keygen * functions, allocate a hash table for the * cache objects for faster lookups */ if (ops->co_obj_ops->oo_keygen) { int hashtable_size; if (ops->co_hash_size) hashtable_size = ops->co_hash_size; else hashtable_size = NL_MAX_HASH_ENTRIES; cache->hashtable = nl_hash_table_alloc(hashtable_size); } NL_DBG(2, "Allocated cache %p <%s>.\n", cache, nl_cache_name(cache)); return cache; } /** * Allocate new cache and fill it * @arg ops Cache operations * @arg sock Netlink socket * @arg result Result pointer * * Allocate new cache and fill it. Equivalent to calling: * @code * cache = nl_cache_alloc(ops); * nl_cache_refill(sock, cache); * @endcode * * @see nl_cache_alloc * * @return 0 on success or a negative error code. */ int nl_cache_alloc_and_fill(struct nl_cache_ops *ops, struct nl_sock *sock, struct nl_cache **result) { struct nl_cache *cache; int err; if (!(cache = nl_cache_alloc(ops))) return -NLE_NOMEM; if (sock && (err = nl_cache_refill(sock, cache)) < 0) { nl_cache_free(cache); return err; } *result = cache; return 0; } /** * Allocate new cache based on type name * @arg kind Name of cache type * @arg result Result pointer * * Lookup cache ops via nl_cache_ops_lookup() and allocate the cache * by calling nl_cache_alloc(). Stores the allocated cache in the * result pointer provided. * * @see nl_cache_alloc * * @return 0 on success or a negative error code. */ int nl_cache_alloc_name(const char *kind, struct nl_cache **result) { struct nl_cache_ops *ops; struct nl_cache *cache; ops = nl_cache_ops_lookup_safe(kind); if (!ops) return -NLE_NOCACHE; cache = nl_cache_alloc(ops); nl_cache_ops_put(ops); if (!cache) return -NLE_NOMEM; *result = cache; return 0; } /** * Allocate new cache containing a subset of an existing cache * @arg orig Original cache to base new cache on * @arg filter Filter defining the subset to be filled into the new cache * * Allocates a new cache matching the type of the cache specified by * \p orig. Iterates over the \p orig cache applying the specified * \p filter and copies all objects that match to the new cache. * * The copied objects are clones but do not contain a reference to each * other. Later modifications to objects in the original cache will * not affect objects in the new cache. * * @return A newly allocated cache or NULL. */ struct nl_cache *nl_cache_subset(struct nl_cache *orig, struct nl_object *filter) { struct nl_cache *cache; struct nl_object *obj; if (!filter) BUG(); cache = nl_cache_alloc(orig->c_ops); if (!cache) return NULL; NL_DBG(2, "Filling subset of cache %p <%s> with filter %p into %p\n", orig, nl_cache_name(orig), filter, cache); nl_list_for_each_entry(obj, &orig->c_items, ce_list) { if (!nl_object_match_filter(obj, filter)) continue; nl_cache_add(cache, obj); } return cache; } /** * Allocate new cache and copy the contents of an existing cache * @arg cache Original cache to base new cache on * * Allocates a new cache matching the type of the cache specified by * \p cache. Iterates over the \p cache cache and copies all objects * to the new cache. * * The copied objects are clones but do not contain a reference to each * other. Later modifications to objects in the original cache will * not affect objects in the new cache. * * @return A newly allocated cache or NULL. */ struct nl_cache *nl_cache_clone(struct nl_cache *cache) { struct nl_cache_ops *ops = nl_cache_get_ops(cache); struct nl_cache *clone; struct nl_object *obj; clone = nl_cache_alloc(ops); if (!clone) return NULL; NL_DBG(2, "Cloning %p into %p\n", cache, clone); nl_list_for_each_entry(obj, &cache->c_items, ce_list) nl_cache_add(clone, obj); return clone; } /** * Remove all objects of a cache. * @arg cache Cache to clear * * The objects are unliked/removed from the cache by calling * nl_cache_remove() on each object in the cache. If any of the objects * to not contain any further references to them, those objects will * be freed. * * Unlike with nl_cache_free(), the cache is not freed just emptied. */ void nl_cache_clear(struct nl_cache *cache) { struct nl_object *obj, *tmp; NL_DBG(2, "Clearing cache %p <%s>...\n", cache, nl_cache_name(cache)); nl_list_for_each_entry_safe(obj, tmp, &cache->c_items, ce_list) nl_cache_remove(obj); } static void __nl_cache_free(struct nl_cache *cache) { nl_cache_clear(cache); if (cache->hashtable) nl_hash_table_free(cache->hashtable); NL_DBG(2, "Freeing cache %p <%s>...\n", cache, nl_cache_name(cache)); free(cache); } /** * Increase reference counter of cache * @arg cache Cache */ void nl_cache_get(struct nl_cache *cache) { cache->c_refcnt++; NL_DBG(3, "Incremented cache %p <%s> reference count to %d\n", cache, nl_cache_name(cache), cache->c_refcnt); } /** * Free a cache. * @arg cache Cache to free. * * Calls nl_cache_clear() to remove all objects associated with the * cache and frees the cache afterwards. * * @see nl_cache_clear() */ void nl_cache_free(struct nl_cache *cache) { if (!cache) return; cache->c_refcnt--; NL_DBG(3, "Decremented cache %p <%s> reference count, %d remaining\n", cache, nl_cache_name(cache), cache->c_refcnt); if (cache->c_refcnt <= 0) __nl_cache_free(cache); } void nl_cache_put(struct nl_cache *cache) { return nl_cache_free(cache); } /** @} */ /** * @name Cache Modifications * @{ */ static int __cache_add(struct nl_cache *cache, struct nl_object *obj) { int ret; obj->ce_cache = cache; if (cache->hashtable) { ret = nl_hash_table_add(cache->hashtable, obj); if (ret < 0) { obj->ce_cache = NULL; return ret; } } nl_list_add_tail(&obj->ce_list, &cache->c_items); cache->c_nitems++; NL_DBG(3, "Added object %p to cache %p <%s>, nitems %d\n", obj, cache, nl_cache_name(cache), cache->c_nitems); return 0; } /** * Add object to cache. * @arg cache Cache * @arg obj Object to be added to the cache * * Adds the object \p obj to the specified \p cache. In case the object * is already associated with another cache, the object is cloned before * adding it to the cache. In this case, the sole reference to the object * will be the one of the cache. Therefore clearing/freeing the cache * will result in the object being freed again. * * If the object has not been associated with a cache yet, the reference * counter of the object is incremented to account for the additional * reference. * * The type of the object and cache must match, otherwise an error is * returned (-NLE_OBJ_MISMATCH). * * @see nl_cache_move() * * @return 0 or a negative error code. */ int nl_cache_add(struct nl_cache *cache, struct nl_object *obj) { struct nl_object *new; int ret = 0; if (cache->c_ops->co_obj_ops != obj->ce_ops) return -NLE_OBJ_MISMATCH; if (!nl_list_empty(&obj->ce_list)) { NL_DBG(3, "Object %p already in cache, cloning new object\n", obj); new = nl_object_clone(obj); if (!new) return -NLE_NOMEM; } else { nl_object_get(obj); new = obj; } ret = __cache_add(cache, new); if (ret < 0) nl_object_put(new); return ret; } /** * Move object from one cache to another * @arg cache Cache to move object to. * @arg obj Object subject to be moved * * Removes the the specified object \p obj from its associated cache * and moves it to another cache. * * If the object is not associated with a cache, the function behaves * just like nl_cache_add(). * * The type of the object and cache must match, otherwise an error is * returned (-NLE_OBJ_MISMATCH). * * @see nl_cache_add() * * @return 0 on success or a negative error code. */ int nl_cache_move(struct nl_cache *cache, struct nl_object *obj) { if (cache->c_ops->co_obj_ops != obj->ce_ops) return -NLE_OBJ_MISMATCH; NL_DBG(3, "Moving object %p from cache %p to cache %p\n", obj, obj->ce_cache, cache); /* Acquire reference, if already in a cache this will be * reverted during removal */ nl_object_get(obj); if (!nl_list_empty(&obj->ce_list)) nl_cache_remove(obj); return __cache_add(cache, obj); } /** * Remove object from cache. * @arg obj Object to remove from cache * * Removes the object \c obj from the cache it is associated with. The * reference counter of the object will be decremented. If the reference * to the object was the only one remaining, the object will be freed. * * If no cache is associated with the object, this function is a NOP. */ void nl_cache_remove(struct nl_object *obj) { int ret; struct nl_cache *cache = obj->ce_cache; if (cache == NULL) return; if (cache->hashtable) { ret = nl_hash_table_del(cache->hashtable, obj); if (ret < 0) NL_DBG(2, "Failed to delete %p from cache %p <%s>.\n", obj, cache, nl_cache_name(cache)); } nl_list_del(&obj->ce_list); obj->ce_cache = NULL; nl_object_put(obj); cache->c_nitems--; NL_DBG(2, "Deleted object %p from cache %p <%s>.\n", obj, cache, nl_cache_name(cache)); } /** @} */ /** * @name Synchronization * @{ */ /** * Set synchronization arg1 of cache * @arg cache Cache * @arg arg argument * * Synchronization arguments are used to specify filters when * requesting dumps from the kernel. */ void nl_cache_set_arg1(struct nl_cache *cache, int arg) { cache->c_iarg1 = arg; } /** * Set synchronization arg2 of cache * @arg cache Cache * @arg arg argument * * Synchronization arguments are used to specify filters when * requesting dumps from the kernel. */ void nl_cache_set_arg2(struct nl_cache *cache, int arg) { cache->c_iarg2 = arg; } /** * Set cache flags * @arg cache Cache * @arg flags Flags */ void nl_cache_set_flags(struct nl_cache *cache, unsigned int flags) { cache->c_flags |= flags; } /** * Invoke the request-update operation * @arg sk Netlink socket. * @arg cache Cache * * This function causes the \e request-update function of the cache * operations to be invoked. This usually causes a dump request to * be sent over the netlink socket which triggers the kernel to dump * all objects of a specific type to be dumped onto the netlink * socket for pickup. * * The behaviour of this function depends on the implemenation of * the \e request_update function of each individual type of cache. * * This function will not have any effects on the cache (unless the * request_update implementation of the cache operations does so). * * Use nl_cache_pickup() to pick-up (read) the objects from the socket * and fill them into the cache. * * @see nl_cache_pickup(), nl_cache_resync() * * @return 0 on success or a negative error code. Some implementations * of co_request_update() return a positive number on success that is * the number of bytes sent. Treat any non-negative number as success too. */ static int nl_cache_request_full_dump(struct nl_sock *sk, struct nl_cache *cache) { if (sk->s_proto != cache->c_ops->co_protocol) return -NLE_PROTO_MISMATCH; if (cache->c_ops->co_request_update == NULL) return -NLE_OPNOTSUPP; NL_DBG(2, "Requesting update from kernel for cache %p <%s>\n", cache, nl_cache_name(cache)); return cache->c_ops->co_request_update(cache, sk); } /** @cond SKIP */ struct update_xdata { struct nl_cache_ops *ops; struct nl_parser_param *params; }; static int update_msg_parser(struct nl_msg *msg, void *arg) { struct update_xdata *x = arg; int ret = 0; ret = nl_cache_parse(x->ops, &msg->nm_src, msg->nm_nlh, x->params); if (ret == -NLE_EXIST) return NL_SKIP; else return ret; } /** @endcond */ /** * Pick-up a netlink request-update with your own parser * @arg sk Netlink socket * @arg cache Cache * @arg param Parser parameters */ static int __cache_pickup(struct nl_sock *sk, struct nl_cache *cache, struct nl_parser_param *param) { int err; struct nl_cb *cb; struct update_xdata x = { .ops = cache->c_ops, .params = param, }; NL_DBG(2, "Picking up answer for cache %p <%s>\n", cache, nl_cache_name(cache)); cb = nl_cb_clone(sk->s_cb); if (cb == NULL) return -NLE_NOMEM; nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, update_msg_parser, &x); err = nl_recvmsgs(sk, cb); if (err < 0) NL_DBG(2, "While picking up for %p <%s>, recvmsgs() returned %d: %s\n", cache, nl_cache_name(cache), err, nl_geterror(err)); nl_cb_put(cb); return err; } static int pickup_checkdup_cb(struct nl_object *c, struct nl_parser_param *p) { struct nl_cache *cache = (struct nl_cache *)p->pp_arg; struct nl_object *old; old = nl_cache_search(cache, c); if (old) { if (nl_object_update(old, c) == 0) { nl_object_put(old); return 0; } nl_cache_remove(old); nl_object_put(old); } return nl_cache_add(cache, c); } static int pickup_cb(struct nl_object *c, struct nl_parser_param *p) { struct nl_cache *cache = p->pp_arg; return nl_cache_add(cache, c); } static int __nl_cache_pickup(struct nl_sock *sk, struct nl_cache *cache, int checkdup) { struct nl_parser_param p; p.pp_cb = checkdup ? pickup_checkdup_cb : pickup_cb; p.pp_arg = cache; if (sk->s_proto != cache->c_ops->co_protocol) return -NLE_PROTO_MISMATCH; return __cache_pickup(sk, cache, &p); } /** * Pickup a netlink dump response and put it into a cache. * @arg sk Netlink socket. * @arg cache Cache to put items into. * * Waits for netlink messages to arrive, parses them and puts them into * the specified cache. * * @return 0 on success or a negative error code. */ int nl_cache_pickup_checkdup(struct nl_sock *sk, struct nl_cache *cache) { return __nl_cache_pickup(sk, cache, 1); } /** * Pickup a netlink dump response and put it into a cache. * @arg sk Netlink socket. * @arg cache Cache to put items into. * * Waits for netlink messages to arrive, parses them and puts them into * the specified cache. If an old object with same key attributes is * present in the cache, it is replaced with the new object. * If the old object type supports an update operation, an update is * attempted before a replace. * * @return 0 on success or a negative error code. */ int nl_cache_pickup(struct nl_sock *sk, struct nl_cache *cache) { return __nl_cache_pickup(sk, cache, 0); } static int cache_include(struct nl_cache *cache, struct nl_object *obj, struct nl_msgtype *type, change_func_t cb, change_func_v2_t cb_v2, void *data) { struct nl_object *old; struct nl_object *clone = NULL; uint64_t diff = 0; switch (type->mt_act) { case NL_ACT_NEW: case NL_ACT_DEL: old = nl_cache_search(cache, obj); if (old) { if (cb_v2 && old->ce_ops->oo_update) { clone = nl_object_clone(old); diff = nl_object_diff64(old, obj); } /* * Some objects types might support merging the new * object with the old existing cache object. * Handle them first. */ if (nl_object_update(old, obj) == 0) { if (cb_v2) { cb_v2(cache, clone, obj, diff, NL_ACT_CHANGE, data); nl_object_put(clone); } else if (cb) cb(cache, old, NL_ACT_CHANGE, data); nl_object_put(old); return 0; } nl_object_put(clone); nl_cache_remove(old); if (type->mt_act == NL_ACT_DEL) { if (cb_v2) cb_v2(cache, old, NULL, 0, NL_ACT_DEL, data); else if (cb) cb(cache, old, NL_ACT_DEL, data); nl_object_put(old); } } if (type->mt_act == NL_ACT_NEW) { nl_cache_move(cache, obj); if (old == NULL) { if (cb_v2) { cb_v2(cache, NULL, obj, 0, NL_ACT_NEW, data); } else if (cb) cb(cache, obj, NL_ACT_NEW, data); } else if (old) { diff = 0; if (cb || cb_v2) diff = nl_object_diff64(old, obj); if (diff && cb_v2) { cb_v2(cache, old, obj, diff, NL_ACT_CHANGE, data); } else if (diff && cb) cb(cache, obj, NL_ACT_CHANGE, data); nl_object_put(old); } } break; default: NL_DBG(2, "Unknown action associated to object %p\n", obj); return 0; } return 0; } int nl_cache_include(struct nl_cache *cache, struct nl_object *obj, change_func_t change_cb, void *data) { struct nl_cache_ops *ops = cache->c_ops; int i; if (ops->co_obj_ops != obj->ce_ops) return -NLE_OBJ_MISMATCH; for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) if (ops->co_msgtypes[i].mt_id == obj->ce_msgtype) return cache_include(cache, obj, &ops->co_msgtypes[i], change_cb, NULL, data); NL_DBG(3, "Object %p does not seem to belong to cache %p <%s>\n", obj, cache, nl_cache_name(cache)); return -NLE_MSGTYPE_NOSUPPORT; } int nl_cache_include_v2(struct nl_cache *cache, struct nl_object *obj, change_func_v2_t change_cb, void *data) { struct nl_cache_ops *ops = cache->c_ops; int i; if (ops->co_obj_ops != obj->ce_ops) return -NLE_OBJ_MISMATCH; for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) if (ops->co_msgtypes[i].mt_id == obj->ce_msgtype) return cache_include(cache, obj, &ops->co_msgtypes[i], NULL, change_cb, data); NL_DBG(3, "Object %p does not seem to belong to cache %p <%s>\n", obj, cache, nl_cache_name(cache)); return -NLE_MSGTYPE_NOSUPPORT; } static int resync_cb(struct nl_object *c, struct nl_parser_param *p) { struct nl_cache_assoc *ca = p->pp_arg; if (ca->ca_change_v2) return nl_cache_include_v2(ca->ca_cache, c, ca->ca_change_v2, ca->ca_change_data); else return nl_cache_include(ca->ca_cache, c, ca->ca_change, ca->ca_change_data); } int nl_cache_resync(struct nl_sock *sk, struct nl_cache *cache, change_func_t change_cb, void *data) { struct nl_object *obj, *next; struct nl_af_group *grp; struct nl_cache_assoc ca = { .ca_cache = cache, .ca_change = change_cb, .ca_change_data = data, }; struct nl_parser_param p = { .pp_cb = resync_cb, .pp_arg = &ca, }; int err; if (sk->s_proto != cache->c_ops->co_protocol) return -NLE_PROTO_MISMATCH; NL_DBG(1, "Resyncing cache %p <%s>...\n", cache, nl_cache_name(cache)); /* Mark all objects so we can see if some of them are obsolete */ nl_cache_mark_all(cache); grp = cache->c_ops->co_groups; do { if (grp && grp->ag_group && (cache->c_flags & NL_CACHE_AF_ITER)) nl_cache_set_arg1(cache, grp->ag_family); restart: err = nl_cache_request_full_dump(sk, cache); if (err < 0) goto errout; err = __cache_pickup(sk, cache, &p); if (err == -NLE_DUMP_INTR) goto restart; else if (err < 0) goto errout; if (grp) grp++; } while (grp && grp->ag_group && (cache->c_flags & NL_CACHE_AF_ITER)); nl_list_for_each_entry_safe(obj, next, &cache->c_items, ce_list) { if (nl_object_is_marked(obj)) { nl_object_get(obj); nl_cache_remove(obj); if (change_cb) change_cb(cache, obj, NL_ACT_DEL, data); nl_object_put(obj); } } NL_DBG(1, "Finished resyncing %p <%s>\n", cache, nl_cache_name(cache)); err = 0; errout: return err; } /** @} */ /** * @name Parsing * @{ */ /** @cond SKIP */ int nl_cache_parse(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *params) { int i, err; if (!nlmsg_valid_hdr(nlh, ops->co_hdrsize)) return -NLE_MSG_TOOSHORT; for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) { if (ops->co_msgtypes[i].mt_id == nlh->nlmsg_type) { err = ops->co_msg_parser(ops, who, nlh, params); if (err != -NLE_OPNOTSUPP) goto errout; } } err = -NLE_MSGTYPE_NOSUPPORT; errout: return err; } /** @endcond */ /** * Parse a netlink message and add it to the cache. * @arg cache cache to add element to * @arg msg netlink message * * Parses a netlink message by calling the cache specific message parser * and adds the new element to the cache. If an old object with same key * attributes is present in the cache, it is replaced with the new object. * If the old object type supports an update operation, an update is * attempted before a replace. * * @return 0 or a negative error code. */ int nl_cache_parse_and_add(struct nl_cache *cache, struct nl_msg *msg) { struct nl_parser_param p = { .pp_cb = pickup_cb, .pp_arg = cache, }; return nl_cache_parse(cache->c_ops, NULL, nlmsg_hdr(msg), &p); } /** * (Re)fill a cache with the contents in the kernel. * @arg sk Netlink socket. * @arg cache cache to update * * Clears the specified cache and fills it with the current state in * the kernel. * * @return 0 or a negative error code. */ int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache) { struct nl_af_group *grp; int err; if (sk->s_proto != cache->c_ops->co_protocol) return -NLE_PROTO_MISMATCH; nl_cache_clear(cache); grp = cache->c_ops->co_groups; do { if (grp && grp->ag_group && (cache->c_flags & NL_CACHE_AF_ITER)) nl_cache_set_arg1(cache, grp->ag_family); restart: err = nl_cache_request_full_dump(sk, cache); if (err < 0) return err; NL_DBG(2, "Updating cache %p <%s> for family %u, request sent, waiting for reply\n", cache, nl_cache_name(cache), grp ? grp->ag_family : AF_UNSPEC); err = nl_cache_pickup(sk, cache); if (err == -NLE_DUMP_INTR) { NL_DBG(2, "Dump interrupted, restarting!\n"); goto restart; } else if (err < 0) break; if (grp) grp++; } while (grp && grp->ag_group && (cache->c_flags & NL_CACHE_AF_ITER)); return err; } /** @} */ /** * @name Utillities * @{ */ static struct nl_object *__cache_fast_lookup(struct nl_cache *cache, struct nl_object *needle) { struct nl_object *obj; obj = nl_hash_table_lookup(cache->hashtable, needle); if (obj) { nl_object_get(obj); return obj; } return NULL; } /** * Search object in cache * @arg cache Cache * @arg needle Object to look for. * * Searches the cache for an object which matches the object \p needle. * The function nl_object_identical() is used to determine if the * objects match. If a matching object is found, the reference counter * is incremented and the object is returned. * * Therefore, if an object is returned, the reference to the object * must be returned by calling nl_object_put() after usage. * * @return Reference to object or NULL if not found. */ struct nl_object *nl_cache_search(struct nl_cache *cache, struct nl_object *needle) { struct nl_object *obj; if (cache->hashtable) return __cache_fast_lookup(cache, needle); nl_list_for_each_entry(obj, &cache->c_items, ce_list) { if (nl_object_identical(obj, needle)) { nl_object_get(obj); return obj; } } return NULL; } /** * Find object in cache * @arg cache Cache * @arg filter object acting as a filter * * Searches the cache for an object which matches the object filter. * If the filter attributes matches the object type id attributes, * and the cache supports hash lookups, a faster hashtable lookup * is used to return the object. Else, function nl_object_match_filter() is * used to determine if the objects match. If a matching object is * found, the reference counter is incremented and the object is returned. * * Therefore, if an object is returned, the reference to the object * must be returned by calling nl_object_put() after usage. * * @return Reference to object or NULL if not found. */ struct nl_object *nl_cache_find(struct nl_cache *cache, struct nl_object *filter) { struct nl_object *obj; if (cache->c_ops == NULL) BUG(); if ((nl_object_get_id_attrs(filter) == filter->ce_mask) && cache->hashtable) return __cache_fast_lookup(cache, filter); nl_list_for_each_entry(obj, &cache->c_items, ce_list) { if (nl_object_match_filter(obj, filter)) { nl_object_get(obj); return obj; } } return NULL; } /** * Mark all objects of a cache * @arg cache Cache * * Marks all objects of a cache by calling nl_object_mark() on each * object associated with the cache. */ void nl_cache_mark_all(struct nl_cache *cache) { struct nl_object *obj; NL_DBG(2, "Marking all objects in cache %p <%s>\n", cache, nl_cache_name(cache)); nl_list_for_each_entry(obj, &cache->c_items, ce_list) nl_object_mark(obj); } /** @} */ /** * @name Dumping * @{ */ /** * Dump all elements of a cache. * @arg cache cache to dump * @arg params dumping parameters * * Dumps all elements of the \a cache to the file descriptor \a fd. */ void nl_cache_dump(struct nl_cache *cache, struct nl_dump_params *params) { nl_cache_dump_filter(cache, params, NULL); } /** * Dump all elements of a cache (filtered). * @arg cache cache to dump * @arg params dumping parameters (optional) * @arg filter filter object * * Dumps all elements of the \a cache to the file descriptor \a fd * given they match the given filter \a filter. */ void nl_cache_dump_filter(struct nl_cache *cache, struct nl_dump_params *params, struct nl_object *filter) { int type = params ? params->dp_type : NL_DUMP_DETAILS; struct nl_object_ops *ops; struct nl_object *obj; NL_DBG(2, "Dumping cache %p <%s> with filter %p\n", cache, nl_cache_name(cache), filter); if (type > NL_DUMP_MAX || type < 0) BUG(); if (cache->c_ops == NULL) BUG(); ops = cache->c_ops->co_obj_ops; if (!ops->oo_dump[type]) return; if (params && params->dp_buf) memset(params->dp_buf, 0, params->dp_buflen); nl_list_for_each_entry(obj, &cache->c_items, ce_list) { if (filter && !nl_object_match_filter(obj, filter)) continue; NL_DBG(4, "Dumping object %p...\n", obj); dump_from_ops(obj, params); } } /** @} */ /** * @name Iterators * @{ */ /** * Call a callback on each element of the cache. * @arg cache cache to iterate on * @arg cb callback function * @arg arg argument passed to callback function * * Calls a callback function \a cb on each element of the \a cache. * The argument \a arg is passed on the callback function. */ void nl_cache_foreach(struct nl_cache *cache, void (*cb)(struct nl_object *, void *), void *arg) { nl_cache_foreach_filter(cache, NULL, cb, arg); } /** * Call a callback on each element of the cache (filtered). * @arg cache cache to iterate on * @arg filter filter object * @arg cb callback function * @arg arg argument passed to callback function * * Calls a callback function \a cb on each element of the \a cache * that matches the \a filter. The argument \a arg is passed on * to the callback function. */ void nl_cache_foreach_filter(struct nl_cache *cache, struct nl_object *filter, void (*cb)(struct nl_object *, void *), void *arg) { struct nl_object *obj, *tmp; if (cache->c_ops == NULL) BUG(); nl_list_for_each_entry_safe(obj, tmp, &cache->c_items, ce_list) { if (filter) { int diff = nl_object_match_filter(obj, filter); NL_DBG(3, "%p<->%p object difference: %x\n", obj, filter, diff); if (!diff) continue; } /* Caller may hold obj for a long time */ nl_object_get(obj); cb(obj, arg); nl_object_put(obj); } } /** @} */ /** @} */ libnl-3.2.29/lib/msg.c0000644000175000017500000005251313023014600011323 00000000000000/* * lib/msg.c Netlink Messages Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup core * @defgroup msg Message Construction & Parsing * Netlink Message Construction/Parsing Interface * * Related sections in the development guide: * - @core_doc{_message_parsing_amp_construction,Message Parsing & Construction} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include #include #include #include static size_t default_msg_size; static void __init init_msg_size(void) { default_msg_size = getpagesize(); } /** * @name Size Calculations * @{ */ /** * Calculates size of netlink message based on payload length. * @arg payload Length of payload * * @return size of netlink message without padding. */ int nlmsg_size(int payload) { return NLMSG_HDRLEN + payload; } static int nlmsg_msg_size(int payload) { return nlmsg_size(payload); } /** * Calculates size of netlink message including padding based on payload length * @arg payload Length of payload * * This function is idential to nlmsg_size() + nlmsg_padlen(). * * @return Size of netlink message including padding. */ int nlmsg_total_size(int payload) { return NLMSG_ALIGN(nlmsg_msg_size(payload)); } /** * Size of padding that needs to be added at end of message * @arg payload Length of payload * * Calculates the number of bytes of padding which is required to be added to * the end of the message to ensure that the next netlink message header begins * properly aligned to NLMSG_ALIGNTO. * * @return Number of bytes of padding needed. */ int nlmsg_padlen(int payload) { return nlmsg_total_size(payload) - nlmsg_msg_size(payload); } /** @} */ /** * @name Access to Message Payload * @{ */ /** * Return pointer to message payload * @arg nlh Netlink message header * * @return Pointer to start of message payload. */ void *nlmsg_data(const struct nlmsghdr *nlh) { return (unsigned char *) nlh + NLMSG_HDRLEN; } void *nlmsg_tail(const struct nlmsghdr *nlh) { return (unsigned char *) nlh + NLMSG_ALIGN(nlh->nlmsg_len); } /** * Return length of message payload * @arg nlh Netlink message header * * @return Length of message payload in bytes. */ int nlmsg_datalen(const struct nlmsghdr *nlh) { return nlh->nlmsg_len - NLMSG_HDRLEN; } static int nlmsg_len(const struct nlmsghdr *nlh) { return nlmsg_datalen(nlh); } /** @} */ /** * @name Attribute Access * @{ */ /** * head of attributes data * @arg nlh netlink message header * @arg hdrlen length of family specific header */ struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, int hdrlen) { unsigned char *data = nlmsg_data(nlh); return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen)); } /** * length of attributes data * @arg nlh netlink message header * @arg hdrlen length of family specific header */ int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) { return max_t(int, nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen), 0); } /** @} */ /** * @name Message Parsing * @{ */ int nlmsg_valid_hdr(const struct nlmsghdr *nlh, int hdrlen) { if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) return 0; return 1; } /** * check if the netlink message fits into the remaining bytes * @arg nlh netlink message header * @arg remaining number of bytes remaining in message stream */ int nlmsg_ok(const struct nlmsghdr *nlh, int remaining) { return (remaining >= (int)sizeof(struct nlmsghdr) && nlh->nlmsg_len >= sizeof(struct nlmsghdr) && nlh->nlmsg_len <= remaining); } /** * next netlink message in message stream * @arg nlh netlink message header * @arg remaining number of bytes remaining in message stream * * @returns the next netlink message in the message stream and * decrements remaining by the size of the current message. */ struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining) { int totlen = NLMSG_ALIGN(nlh->nlmsg_len); *remaining -= totlen; return (struct nlmsghdr *) ((unsigned char *) nlh + totlen); } /** * parse attributes of a netlink message * @arg nlh netlink message header * @arg hdrlen length of family specific header * @arg tb destination array with maxtype+1 elements * @arg maxtype maximum attribute type to be expected * @arg policy validation policy * * See nla_parse() */ int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy) { if (!nlmsg_valid_hdr(nlh, hdrlen)) return -NLE_MSG_TOOSHORT; return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), policy); } /** * nlmsg_find_attr - find a specific attribute in a netlink message * @arg nlh netlink message header * @arg hdrlen length of familiy specific header * @arg attrtype type of attribute to look for * * Returns the first attribute which matches the specified type. */ struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype) { return nla_find(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), attrtype); } /** * nlmsg_validate - validate a netlink message including attributes * @arg nlh netlinket message header * @arg hdrlen length of familiy specific header * @arg maxtype maximum attribute type to be expected * @arg policy validation policy */ int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, struct nla_policy *policy) { if (!nlmsg_valid_hdr(nlh, hdrlen)) return -NLE_MSG_TOOSHORT; return nla_validate(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), maxtype, policy); } /** @} */ /** * @name Message Building/Access * @{ */ static struct nl_msg *__nlmsg_alloc(size_t len) { struct nl_msg *nm; if (len < sizeof(struct nlmsghdr)) len = sizeof(struct nlmsghdr); nm = calloc(1, sizeof(*nm)); if (!nm) goto errout; nm->nm_refcnt = 1; nm->nm_nlh = calloc(1, len); if (!nm->nm_nlh) goto errout; nm->nm_protocol = -1; nm->nm_size = len; nm->nm_nlh->nlmsg_len = nlmsg_total_size(0); NL_DBG(2, "msg %p: Allocated new message, maxlen=%zu\n", nm, len); return nm; errout: free(nm); return NULL; } /** * Allocate a new netlink message with the default maximum payload size. * * Allocates a new netlink message without any further payload. The * maximum payload size defaults to PAGESIZE or as otherwise specified * with nlmsg_set_default_size(). * * @return Newly allocated netlink message or NULL. */ struct nl_msg *nlmsg_alloc(void) { return __nlmsg_alloc(default_msg_size); } /** * Allocate a new netlink message with maximum payload size specified. */ struct nl_msg *nlmsg_alloc_size(size_t max) { return __nlmsg_alloc(max); } /** * Allocate a new netlink message and inherit netlink message header * @arg hdr Netlink message header template * * Allocates a new netlink message and inherits the original message * header. If \a hdr is not NULL it will be used as a template for * the netlink message header, otherwise the header is left blank. * * @return Newly allocated netlink message or NULL */ struct nl_msg *nlmsg_inherit(struct nlmsghdr *hdr) { struct nl_msg *nm; nm = nlmsg_alloc(); if (nm && hdr) { struct nlmsghdr *new = nm->nm_nlh; new->nlmsg_type = hdr->nlmsg_type; new->nlmsg_flags = hdr->nlmsg_flags; new->nlmsg_seq = hdr->nlmsg_seq; new->nlmsg_pid = hdr->nlmsg_pid; } return nm; } /** * Allocate a new netlink message * @arg nlmsgtype Netlink message type * @arg flags Message flags. * * @return Newly allocated netlink message or NULL. */ struct nl_msg *nlmsg_alloc_simple(int nlmsgtype, int flags) { struct nl_msg *msg; struct nlmsghdr nlh = { .nlmsg_type = nlmsgtype, .nlmsg_flags = flags, }; msg = nlmsg_inherit(&nlh); if (msg) NL_DBG(2, "msg %p: Allocated new simple message\n", msg); return msg; } /** * Set the default maximum message payload size for allocated messages * @arg max Size of payload in bytes. */ void nlmsg_set_default_size(size_t max) { if (max < nlmsg_total_size(0)) max = nlmsg_total_size(0); default_msg_size = max; } /** * Convert a netlink message received from a netlink socket to a nl_msg * @arg hdr Netlink message received from netlink socket. * * Allocates a new netlink message and copies all of the data pointed to * by \a hdr into the new message object. * * @return Newly allocated netlink message or NULL. */ struct nl_msg *nlmsg_convert(struct nlmsghdr *hdr) { struct nl_msg *nm; nm = __nlmsg_alloc(NLMSG_ALIGN(hdr->nlmsg_len)); if (!nm) return NULL; memcpy(nm->nm_nlh, hdr, hdr->nlmsg_len); return nm; } /** * Reserve room for additional data in a netlink message * @arg n netlink message * @arg len length of additional data to reserve room for * @arg pad number of bytes to align data to * * Reserves room for additional data at the tail of the an * existing netlink message. Eventual padding required will * be zeroed out. * * @return Pointer to start of additional data tailroom or NULL. */ void *nlmsg_reserve(struct nl_msg *n, size_t len, int pad) { void *buf = n->nm_nlh; size_t nlmsg_len = n->nm_nlh->nlmsg_len; size_t tlen; tlen = pad ? ((len + (pad - 1)) & ~(pad - 1)) : len; if ((tlen + nlmsg_len) > n->nm_size) return NULL; buf += nlmsg_len; n->nm_nlh->nlmsg_len += tlen; if (tlen > len) memset(buf + len, 0, tlen - len); NL_DBG(2, "msg %p: Reserved %zu (%zu) bytes, pad=%d, nlmsg_len=%d\n", n, tlen, len, pad, n->nm_nlh->nlmsg_len); return buf; } /** * Append data to tail of a netlink message * @arg n netlink message * @arg data data to add * @arg len length of data * @arg pad Number of bytes to align data to. * * Extends the netlink message as needed and appends the data of given * length to the message. * * @return 0 on success or a negative error code */ int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad) { void *tmp; tmp = nlmsg_reserve(n, len, pad); if (tmp == NULL) return -NLE_NOMEM; memcpy(tmp, data, len); NL_DBG(2, "msg %p: Appended %zu bytes with padding %d\n", n, len, pad); return 0; } /** * Expand maximum payload size of a netlink message * @arg n Netlink message. * @arg newlen New maximum payload size. * * Reallocates the payload section of a netlink message and increases * the maximum payload size of the message. * * @note Any pointers pointing to old payload block will be stale and * need to be refetched. Therfore, do not expand while constructing * nested attributes or while reserved data blocks are held. * * @return 0 on success or a negative error code. */ int nlmsg_expand(struct nl_msg *n, size_t newlen) { void *tmp; if (newlen <= n->nm_size) return -NLE_INVAL; tmp = realloc(n->nm_nlh, newlen); if (tmp == NULL) return -NLE_NOMEM; n->nm_nlh = tmp; n->nm_size = newlen; return 0; } /** * Add a netlink message header to a netlink message * @arg n netlink message * @arg pid netlink process id or NL_AUTO_PID * @arg seq sequence number of message or NL_AUTO_SEQ * @arg type message type * @arg payload length of message payload * @arg flags message flags * * Adds or overwrites the netlink message header in an existing message * object. If \a payload is greater-than zero additional room will be * reserved, f.e. for family specific headers. It can be accesed via * nlmsg_data(). * * @return A pointer to the netlink message header or NULL. */ struct nlmsghdr *nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags) { struct nlmsghdr *nlh; if (n->nm_nlh->nlmsg_len < NLMSG_HDRLEN) BUG(); nlh = (struct nlmsghdr *) n->nm_nlh; nlh->nlmsg_type = type; nlh->nlmsg_flags = flags; nlh->nlmsg_pid = pid; nlh->nlmsg_seq = seq; NL_DBG(2, "msg %p: Added netlink header type=%d, flags=%d, pid=%d, " "seq=%d\n", n, type, flags, pid, seq); if (payload > 0 && nlmsg_reserve(n, payload, NLMSG_ALIGNTO) == NULL) return NULL; return nlh; } /** * Return actual netlink message * @arg n netlink message * * Returns the actual netlink message casted to the type of the netlink * message header. * * @return A pointer to the netlink message. */ struct nlmsghdr *nlmsg_hdr(struct nl_msg *n) { return n->nm_nlh; } /** * Acquire a reference on a netlink message * @arg msg message to acquire reference from */ void nlmsg_get(struct nl_msg *msg) { msg->nm_refcnt++; NL_DBG(4, "New reference to message %p, total %d\n", msg, msg->nm_refcnt); } /** * Release a reference from an netlink message * @arg msg message to release reference from * * Frees memory after the last reference has been released. */ void nlmsg_free(struct nl_msg *msg) { if (!msg) return; msg->nm_refcnt--; NL_DBG(4, "Returned message reference %p, %d remaining\n", msg, msg->nm_refcnt); if (msg->nm_refcnt < 0) BUG(); if (msg->nm_refcnt <= 0) { free(msg->nm_nlh); NL_DBG(2, "msg %p: Freed\n", msg); free(msg); } } /** @} */ /** * @name Attributes * @{ */ void nlmsg_set_proto(struct nl_msg *msg, int protocol) { msg->nm_protocol = protocol; } int nlmsg_get_proto(struct nl_msg *msg) { return msg->nm_protocol; } size_t nlmsg_get_max_size(struct nl_msg *msg) { return msg->nm_size; } void nlmsg_set_src(struct nl_msg *msg, struct sockaddr_nl *addr) { memcpy(&msg->nm_src, addr, sizeof(*addr)); } struct sockaddr_nl *nlmsg_get_src(struct nl_msg *msg) { return &msg->nm_src; } void nlmsg_set_dst(struct nl_msg *msg, struct sockaddr_nl *addr) { memcpy(&msg->nm_dst, addr, sizeof(*addr)); } struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *msg) { return &msg->nm_dst; } void nlmsg_set_creds(struct nl_msg *msg, struct ucred *creds) { memcpy(&msg->nm_creds, creds, sizeof(*creds)); msg->nm_flags |= NL_MSG_CRED_PRESENT; } struct ucred *nlmsg_get_creds(struct nl_msg *msg) { if (msg->nm_flags & NL_MSG_CRED_PRESENT) return &msg->nm_creds; return NULL; } /** @} */ /** * @name Netlink Message Type Translations * @{ */ static const struct trans_tbl nl_msgtypes[] = { __ADD(NLMSG_NOOP,NOOP), __ADD(NLMSG_ERROR,ERROR), __ADD(NLMSG_DONE,DONE), __ADD(NLMSG_OVERRUN,OVERRUN), }; char *nl_nlmsgtype2str(int type, char *buf, size_t size) { return __type2str(type, buf, size, nl_msgtypes, ARRAY_SIZE(nl_msgtypes)); } int nl_str2nlmsgtype(const char *name) { return __str2type(name, nl_msgtypes, ARRAY_SIZE(nl_msgtypes)); } /** @} */ /** * @name Netlink Message Flags Translations * @{ */ char *nl_nlmsg_flags2str(int flags, char *buf, size_t len) { memset(buf, 0, len); #define PRINT_FLAG(f) \ if (flags & NLM_F_##f) { \ flags &= ~NLM_F_##f; \ strncat(buf, #f, len - strlen(buf) - 1); \ if (flags) \ strncat(buf, ",", len - strlen(buf) - 1); \ } PRINT_FLAG(REQUEST); PRINT_FLAG(MULTI); PRINT_FLAG(ACK); PRINT_FLAG(ECHO); PRINT_FLAG(ROOT); PRINT_FLAG(MATCH); PRINT_FLAG(ATOMIC); PRINT_FLAG(REPLACE); PRINT_FLAG(EXCL); PRINT_FLAG(CREATE); PRINT_FLAG(APPEND); if (flags) { char s[32]; snprintf(s, sizeof(s), "0x%x", flags); strncat(buf, s, len - strlen(buf) - 1); } #undef PRINT_FLAG return buf; } /** @} */ /** * @name Direct Parsing * @{ */ /** @cond SKIP */ struct dp_xdata { void (*cb)(struct nl_object *, void *); void *arg; }; /** @endcond */ static int parse_cb(struct nl_object *obj, struct nl_parser_param *p) { struct dp_xdata *x = p->pp_arg; x->cb(obj, x->arg); return 0; } int nl_msg_parse(struct nl_msg *msg, void (*cb)(struct nl_object *, void *), void *arg) { struct nl_cache_ops *ops; struct nl_parser_param p = { .pp_cb = parse_cb }; struct dp_xdata x = { .cb = cb, .arg = arg, }; int err; ops = nl_cache_ops_associate_safe(nlmsg_get_proto(msg), nlmsg_hdr(msg)->nlmsg_type); if (ops == NULL) return -NLE_MSGTYPE_NOSUPPORT; p.pp_arg = &x; err = nl_cache_parse(ops, NULL, nlmsg_hdr(msg), &p); nl_cache_ops_put(ops); return err; } /** @} */ /** * @name Dumping * @{ */ static void prefix_line(FILE *ofd, int prefix) { int i; for (i = 0; i < prefix; i++) fprintf(ofd, " "); } static inline void dump_hex(FILE *ofd, char *start, int len, int prefix) { int i, a, c, limit; char ascii[21] = {0}; limit = 16 - (prefix * 2); prefix_line(ofd, prefix); fprintf(ofd, " "); for (i = 0, a = 0, c = 0; i < len; i++) { int v = *(uint8_t *) (start + i); fprintf(ofd, "%02x ", v); ascii[a++] = isprint(v) ? v : '.'; if (++c >= limit) { fprintf(ofd, "%s\n", ascii); if (i < (len - 1)) { prefix_line(ofd, prefix); fprintf(ofd, " "); } a = c = 0; memset(ascii, 0, sizeof(ascii)); } } if (c != 0) { for (i = 0; i < (limit - c); i++) fprintf(ofd, " "); fprintf(ofd, "%s\n", ascii); } } static void print_hdr(FILE *ofd, struct nl_msg *msg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct nl_cache_ops *ops; struct nl_msgtype *mt; char buf[128]; fprintf(ofd, " .nlmsg_len = %d\n", nlh->nlmsg_len); ops = nl_cache_ops_associate_safe(nlmsg_get_proto(msg), nlh->nlmsg_type); if (ops) { mt = nl_msgtype_lookup(ops, nlh->nlmsg_type); if (!mt) BUG(); snprintf(buf, sizeof(buf), "%s::%s", ops->co_name, mt->mt_name); nl_cache_ops_put(ops); } else nl_nlmsgtype2str(nlh->nlmsg_type, buf, sizeof(buf)); fprintf(ofd, " .type = %d <%s>\n", nlh->nlmsg_type, buf); fprintf(ofd, " .flags = %d <%s>\n", nlh->nlmsg_flags, nl_nlmsg_flags2str(nlh->nlmsg_flags, buf, sizeof(buf))); fprintf(ofd, " .seq = %d\n", nlh->nlmsg_seq); fprintf(ofd, " .port = %d\n", nlh->nlmsg_pid); } static void print_genl_hdr(FILE *ofd, void *start) { struct genlmsghdr *ghdr = start; fprintf(ofd, " [GENERIC NETLINK HEADER] %zu octets\n", GENL_HDRLEN); fprintf(ofd, " .cmd = %u\n", ghdr->cmd); fprintf(ofd, " .version = %u\n", ghdr->version); fprintf(ofd, " .unused = %#x\n", ghdr->reserved); } static void *print_genl_msg(struct nl_msg *msg, FILE *ofd, struct nlmsghdr *hdr, struct nl_cache_ops *ops, int *payloadlen) { void *data = nlmsg_data(hdr); if (*payloadlen < GENL_HDRLEN) return data; print_genl_hdr(ofd, data); *payloadlen -= GENL_HDRLEN; data += GENL_HDRLEN; if (ops) { int hdrsize = ops->co_hdrsize - GENL_HDRLEN; if (hdrsize > 0) { if (*payloadlen < hdrsize) return data; fprintf(ofd, " [HEADER] %d octets\n", hdrsize); dump_hex(ofd, data, hdrsize, 0); *payloadlen -= hdrsize; data += hdrsize; } } return data; } static void dump_attr(FILE *ofd, struct nlattr *attr, int prefix) { int len = nla_len(attr); dump_hex(ofd, nla_data(attr), len, prefix); } static void dump_attrs(FILE *ofd, struct nlattr *attrs, int attrlen, int prefix) { int rem; struct nlattr *nla; nla_for_each_attr(nla, attrs, attrlen, rem) { int padlen, alen = nla_len(nla); prefix_line(ofd, prefix); if (nla->nla_type == 0) fprintf(ofd, " [ATTR PADDING] %d octets\n", alen); else fprintf(ofd, " [ATTR %02d%s] %d octets\n", nla_type(nla), nla_is_nested(nla) ? " NESTED" : "", alen); if (nla_is_nested(nla)) dump_attrs(ofd, nla_data(nla), alen, prefix+1); else dump_attr(ofd, nla, prefix); padlen = nla_padlen(alen); if (padlen > 0) { prefix_line(ofd, prefix); fprintf(ofd, " [PADDING] %d octets\n", padlen); dump_hex(ofd, nla_data(nla) + alen, padlen, prefix); } } if (rem) { prefix_line(ofd, prefix); fprintf(ofd, " [LEFTOVER] %d octets\n", rem); } } static void dump_error_msg(struct nl_msg *msg, FILE *ofd) { struct nlmsghdr *hdr = nlmsg_hdr(msg); struct nlmsgerr *err = nlmsg_data(hdr); fprintf(ofd, " [ERRORMSG] %zu octets\n", sizeof(*err)); if (nlmsg_len(hdr) >= sizeof(*err)) { struct nl_msg *errmsg; fprintf(ofd, " .error = %d \"%s\"\n", err->error, nl_strerror_l(-err->error)); fprintf(ofd, " [ORIGINAL MESSAGE] %zu octets\n", sizeof(*hdr)); errmsg = nlmsg_inherit(&err->msg); print_hdr(ofd, errmsg); nlmsg_free(errmsg); } } static void print_msg(struct nl_msg *msg, FILE *ofd, struct nlmsghdr *hdr) { struct nl_cache_ops *ops; int payloadlen = nlmsg_len(hdr); int attrlen = 0; void *data; data = nlmsg_data(hdr); ops = nl_cache_ops_associate_safe(nlmsg_get_proto(msg), hdr->nlmsg_type); if (ops) { attrlen = nlmsg_attrlen(hdr, ops->co_hdrsize); payloadlen -= attrlen; } if (msg->nm_protocol == NETLINK_GENERIC) data = print_genl_msg(msg, ofd, hdr, ops, &payloadlen); if (payloadlen) { fprintf(ofd, " [PAYLOAD] %d octets\n", payloadlen); dump_hex(ofd, data, payloadlen, 0); } if (attrlen) { struct nlattr *attrs; int attrlen; attrs = nlmsg_attrdata(hdr, ops->co_hdrsize); attrlen = nlmsg_attrlen(hdr, ops->co_hdrsize); dump_attrs(ofd, attrs, attrlen, 0); } if (ops) nl_cache_ops_put(ops); } /** * Dump message in human readable format to file descriptor * @arg msg Message to print * @arg ofd File descriptor. */ void nl_msg_dump(struct nl_msg *msg, FILE *ofd) { struct nlmsghdr *hdr = nlmsg_hdr(msg); fprintf(ofd, "-------------------------- BEGIN NETLINK MESSAGE ---------------------------\n"); fprintf(ofd, " [NETLINK HEADER] %zu octets\n", sizeof(struct nlmsghdr)); print_hdr(ofd, msg); if (hdr->nlmsg_type == NLMSG_ERROR) dump_error_msg(msg, ofd); else if (nlmsg_len(hdr) > 0) print_msg(msg, ofd, hdr); fprintf(ofd, "--------------------------- END NETLINK MESSAGE ---------------------------\n"); } /** @} */ /** @} */ libnl-3.2.29/lib/object.c0000644000175000017500000002677713023014600012020 00000000000000/* * lib/object.c Generic Cacheable Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup core_types * @defgroup object Object (Cacheable) * * Generic object data type, for inheritance purposes to implement cacheable * data types. * * Related sections in the development guide: * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ #include #include #include #include #include static inline struct nl_object_ops *obj_ops(struct nl_object *obj) { if (!obj->ce_ops) BUG(); return obj->ce_ops; } /** * @name Object Creation/Deletion * @{ */ /** * Allocate a new object of kind specified by the operations handle * @arg ops cache operations handle * @return The new object or NULL */ struct nl_object *nl_object_alloc(struct nl_object_ops *ops) { struct nl_object *new; if (ops->oo_size < sizeof(*new)) BUG(); new = calloc(1, ops->oo_size); if (!new) return NULL; new->ce_refcnt = 1; nl_init_list_head(&new->ce_list); new->ce_ops = ops; if (ops->oo_constructor) ops->oo_constructor(new); NL_DBG(4, "Allocated new object %p\n", new); return new; } /** * Allocate new object of kind specified by the name * @arg kind name of object type * @arg result Result pointer * * @return 0 on success or a negative error code. */ int nl_object_alloc_name(const char *kind, struct nl_object **result) { struct nl_cache_ops *ops; ops = nl_cache_ops_lookup_safe(kind); if (!ops) return -NLE_OPNOTSUPP; *result = nl_object_alloc(ops->co_obj_ops); nl_cache_ops_put(ops); if (!*result) return -NLE_NOMEM; return 0; } struct nl_derived_object { NLHDR_COMMON char data; }; /** * Allocate a new object and copy all data from an existing object * @arg obj object to inherite data from * @return The new object or NULL. */ struct nl_object *nl_object_clone(struct nl_object *obj) { struct nl_object *new; struct nl_object_ops *ops; int doff = offsetof(struct nl_derived_object, data); int size; if (!obj) return NULL; ops = obj_ops(obj); new = nl_object_alloc(ops); if (!new) return NULL; size = ops->oo_size - doff; if (size < 0) BUG(); new->ce_ops = obj->ce_ops; new->ce_msgtype = obj->ce_msgtype; new->ce_mask = obj->ce_mask; if (size) memcpy((void *)new + doff, (void *)obj + doff, size); if (ops->oo_clone) { if (ops->oo_clone(new, obj) < 0) { nl_object_free(new); return NULL; } } else if (size && ops->oo_free_data) BUG(); return new; } /** * Merge a cacheable object * @arg dst object to be merged into * @arg src new object to be merged into dst * * @return 0 or a negative error code. */ int nl_object_update(struct nl_object *dst, struct nl_object *src) { struct nl_object_ops *ops = obj_ops(dst); if (ops->oo_update) return ops->oo_update(dst, src); return -NLE_OPNOTSUPP; } /** * Free a cacheable object * @arg obj object to free * * @return 0 or a negative error code. */ void nl_object_free(struct nl_object *obj) { struct nl_object_ops *ops; if (!obj) return; ops = obj_ops(obj); if (obj->ce_refcnt > 0) NL_DBG(1, "Warning: Freeing object in use...\n"); if (obj->ce_cache) nl_cache_remove(obj); if (ops->oo_free_data) ops->oo_free_data(obj); NL_DBG(4, "Freed object %p\n", obj); free(obj); } /** @} */ /** * @name Reference Management * @{ */ /** * Acquire a reference on a object * @arg obj object to acquire reference from */ void nl_object_get(struct nl_object *obj) { obj->ce_refcnt++; NL_DBG(4, "New reference to object %p, total %d\n", obj, obj->ce_refcnt); } /** * Release a reference from an object * @arg obj object to release reference from */ void nl_object_put(struct nl_object *obj) { if (!obj) return; obj->ce_refcnt--; NL_DBG(4, "Returned object reference %p, %d remaining\n", obj, obj->ce_refcnt); if (obj->ce_refcnt < 0) BUG(); if (obj->ce_refcnt <= 0) nl_object_free(obj); } /** * Check whether this object is used by multiple users * @arg obj object to check * @return true or false */ int nl_object_shared(struct nl_object *obj) { return obj->ce_refcnt > 1; } /** @} */ /** * @name Marks * @{ */ /** * Add mark to object * @arg obj Object to mark */ void nl_object_mark(struct nl_object *obj) { obj->ce_flags |= NL_OBJ_MARK; } /** * Remove mark from object * @arg obj Object to unmark */ void nl_object_unmark(struct nl_object *obj) { obj->ce_flags &= ~NL_OBJ_MARK; } /** * Return true if object is marked * @arg obj Object to check * @return true if object is marked, otherwise false */ int nl_object_is_marked(struct nl_object *obj) { return (obj->ce_flags & NL_OBJ_MARK); } /** @} */ /** * @name Utillities * @{ */ /** * Dump this object according to the specified parameters * @arg obj object to dump * @arg params dumping parameters */ void nl_object_dump(struct nl_object *obj, struct nl_dump_params *params) { if (params->dp_buf) memset(params->dp_buf, 0, params->dp_buflen); dump_from_ops(obj, params); } void nl_object_dump_buf(struct nl_object *obj, char *buf, size_t len) { struct nl_dump_params dp = { .dp_buf = buf, .dp_buflen = len, }; return nl_object_dump(obj, &dp); } /** * Check if the identifiers of two objects are identical * @arg a an object * @arg b another object of same type * * @return true if both objects have equal identifiers, otherwise false. */ int nl_object_identical(struct nl_object *a, struct nl_object *b) { struct nl_object_ops *ops = obj_ops(a); uint32_t req_attrs; /* Both objects must be of same type */ if (ops != obj_ops(b)) return 0; if (ops->oo_id_attrs_get) { int req_attrs_a = ops->oo_id_attrs_get(a); int req_attrs_b = ops->oo_id_attrs_get(b); if (req_attrs_a != req_attrs_b) return 0; req_attrs = req_attrs_a; } else if (ops->oo_id_attrs) { req_attrs = ops->oo_id_attrs; } else { req_attrs = 0xFFFFFFFF; } if (req_attrs == 0xFFFFFFFF) req_attrs = a->ce_mask & b->ce_mask; /* Both objects must provide all required attributes to uniquely * identify an object */ if ((a->ce_mask & req_attrs) != req_attrs || (b->ce_mask & req_attrs) != req_attrs) return 0; /* Can't judge unless we can compare */ if (ops->oo_compare == NULL) return 0; return !(ops->oo_compare(a, b, req_attrs, ID_COMPARISON)); } /** * Compute bitmask representing difference in attribute values * @arg a an object * @arg b another object of same type * * The bitmask returned is specific to an object type, each bit set represents * an attribute which mismatches in either of the two objects. Unavailability * of an attribute in one object and presence in the other is regarded a * mismatch as well. * * @return Bitmask describing differences or 0 if they are completely identical. */ uint64_t nl_object_diff64(struct nl_object *a, struct nl_object *b) { struct nl_object_ops *ops = obj_ops(a); if (ops != obj_ops(b) || ops->oo_compare == NULL) return UINT64_MAX; return ops->oo_compare(a, b, ~0, 0); } /** * Compute 32-bit bitmask representing difference in attribute values * @arg a an object * @arg b another object of same type * * The bitmask returned is specific to an object type, each bit set represents * an attribute which mismatches in either of the two objects. Unavailability * of an attribute in one object and presence in the other is regarded a * mismatch as well. * * @return Bitmask describing differences or 0 if they are completely identical. * 32nd bit indicates if higher bits from the 64-bit compare were * different. */ uint32_t nl_object_diff(struct nl_object *a, struct nl_object *b) { uint64_t diff; diff = nl_object_diff64(a, b); return (diff & ~((uint64_t) 0xFFFFFFFF)) ? (uint32_t) diff | (1 << 31) : (uint32_t) diff; } /** * Match a filter against an object * @arg obj object to check * @arg filter object of same type acting as filter * * @return 1 if the object matches the filter or 0 * if no filter procedure is available or if the * filter does not match. */ int nl_object_match_filter(struct nl_object *obj, struct nl_object *filter) { struct nl_object_ops *ops = obj_ops(obj); if (ops != obj_ops(filter) || ops->oo_compare == NULL) return 0; return !(ops->oo_compare(obj, filter, filter->ce_mask, LOOSE_COMPARISON)); } /** * Convert bitmask of attributes to a character string * @arg obj object of same type as attribute bitmask * @arg attrs bitmask of attribute types * @arg buf destination buffer * @arg len length of destination buffer * * Converts the bitmask of attribute types into a list of attribute * names separated by comas. * * @return destination buffer. */ char *nl_object_attrs2str(struct nl_object *obj, uint32_t attrs, char *buf, size_t len) { struct nl_object_ops *ops = obj_ops(obj); if (ops->oo_attrs2str != NULL) return ops->oo_attrs2str(attrs, buf, len); else { memset(buf, 0, len); return buf; } } /** * Return list of attributes present in an object * @arg obj an object * @arg buf destination buffer * @arg len length of destination buffer * * @return destination buffer. */ char *nl_object_attr_list(struct nl_object *obj, char *buf, size_t len) { return nl_object_attrs2str(obj, obj->ce_mask, buf, len); } /** * Generate object hash key * @arg obj the object * @arg hashkey destination buffer to be used for key stream * @arg hashtbl_sz hash table size * * @return hash key in destination buffer */ void nl_object_keygen(struct nl_object *obj, uint32_t *hashkey, uint32_t hashtbl_sz) { struct nl_object_ops *ops = obj_ops(obj); if (ops->oo_keygen) ops->oo_keygen(obj, hashkey, hashtbl_sz); else *hashkey = 0; return; } /** @} */ /** * @name Attributes * @{ */ /** * Return number of references held * @arg obj object * * @return The number of references held to this object */ int nl_object_get_refcnt(struct nl_object *obj) { return obj->ce_refcnt; } /** * Return cache the object is associated with * @arg obj object * * @note The returned pointer is not protected with a reference counter, * it is your responsibility. * * @return Pointer to cache or NULL if not associated with a cache. */ struct nl_cache *nl_object_get_cache(struct nl_object *obj) { return obj->ce_cache; } /** * Return the object's type * @arg obj object * * FIXME: link to list of object types * * @return Name of the object type */ const char *nl_object_get_type(const struct nl_object *obj) { if (!obj->ce_ops) BUG(); return obj->ce_ops->oo_name; } /** * Return the netlink message type the object was derived from * @arg obj object * * @return Netlink message type or 0. */ int nl_object_get_msgtype(const struct nl_object *obj) { return obj->ce_msgtype; } /** * Return object operations structure * @arg obj object * * @return Pointer to the object operations structure */ struct nl_object_ops *nl_object_get_ops(const struct nl_object *obj) { return obj->ce_ops; } /** * Return object id attribute mask * @arg obj object * * @return object id attribute mask */ uint32_t nl_object_get_id_attrs(struct nl_object *obj) { struct nl_object_ops *ops = obj_ops(obj); uint32_t id_attrs; if (!ops) return 0; if (ops->oo_id_attrs_get) id_attrs = ops->oo_id_attrs_get(obj); else id_attrs = ops->oo_id_attrs; return id_attrs; } /** @} */ /** @} */ libnl-3.2.29/lib/nl.c0000644000175000017500000010027313023014600011143 00000000000000/* * lib/nl.c Core Netlink Interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @defgroup core Core Library (libnl) * * Socket handling, connection management, sending and receiving of data, * message construction and parsing, object caching system, ... * * This is the API reference of the core library. It is not meant as a guide * but as a reference. Please refer to the core library guide for detailed * documentation on the library architecture and examples: * * * @ref_asciidoc{core,_,Netlink Core Library Development Guide} * * * @{ */ #include #include #include #include #include #include #include #include #include /** * @defgroup core_types Data Types * * Core library data types * @{ * @} * * @defgroup send_recv Send & Receive Data * * Connection management, sending & receiving of data * * Related sections in the development guide: * - @core_doc{core_send_recv, Sending & Receiving} * - @core_doc{core_sockets, Sockets} * * @{ * * Header * ------ * ~~~~{.c} * #include * ~~~~ */ /** * @name Connection Management * @{ */ /** * Create file descriptor and bind socket. * @arg sk Netlink socket (required) * @arg protocol Netlink protocol to use (required) * * Creates a new Netlink socket using `socket()` and binds the socket to the * protocol and local port specified in the `sk` socket object. Fails if * the socket is already connected. * * @note If available, the `close-on-exec` (`SOCK_CLOEXEC`) feature is enabled * automatically on the new file descriptor. This causes the socket to * be closed automatically if any of the `exec` family functions succeed. * This is essential for multi threaded programs. * * @note The local port (`nl_socket_get_local_port()`) is unspecified after * creating a new socket. It only gets determined when accessing the * port the first time or during `nl_connect()`. When nl_connect() * fails during `bind()` due to `ADDRINUSE`, it will retry with * different ports if the port is unspecified. Unless you want to enforce * the use of a specific local port, don't access the local port (or * reset it to `unspecified` by calling `nl_socket_set_local_port(sk, 0)`). * This capability is indicated by * `%NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE`. * * @note nl_connect() creates and sets the file descriptor. You can setup the file * descriptor yourself by creating and binding it, and then calling * nl_socket_set_fd(). The result will be the same. * * @see nl_socket_alloc() * @see nl_close() * @see nl_socket_set_fd() * * @return 0 on success or a negative error code. * * @retval -NLE_BAD_SOCK Socket is already connected */ int nl_connect(struct nl_sock *sk, int protocol) { int err, flags = 0; int errsv; socklen_t addrlen; struct sockaddr_nl local = { 0 }; int try_bind = 1; #ifdef SOCK_CLOEXEC flags |= SOCK_CLOEXEC; #endif if (sk->s_fd != -1) return -NLE_BAD_SOCK; sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol); if (sk->s_fd < 0) { errsv = errno; NL_DBG(4, "nl_connect(%p): socket() failed with %d (%s)\n", sk, errsv, nl_strerror_l(errsv)); err = -nl_syserr2nlerr(errsv); goto errout; } err = nl_socket_set_buffer_size(sk, 0, 0); if (err < 0) goto errout; if (_nl_socket_is_local_port_unspecified (sk)) { uint32_t port; uint32_t used_ports[32] = { 0 }; int ntries = 0; while (1) { if (ntries++ > 5) { /* try only a few times. We hit this only if many ports are already in * use but allocated *outside* libnl/generate_local_port(). */ _nl_socket_set_local_port_no_release (sk, 0); break; } port = _nl_socket_set_local_port_no_release(sk, 1); if (port == 0) break; err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local, sizeof(sk->s_local)); if (err == 0) { try_bind = 0; break; } errsv = errno; if (errsv == EADDRINUSE) { NL_DBG(4, "nl_connect(%p): local port %u already in use. Retry.\n", sk, (unsigned) port); _nl_socket_used_ports_set(used_ports, port); } else { NL_DBG(4, "nl_connect(%p): bind() for port %u failed with %d (%s)\n", sk, (unsigned) port, errsv, nl_strerror_l(errsv)); _nl_socket_used_ports_release_all(used_ports); err = -nl_syserr2nlerr(errsv); goto errout; } } _nl_socket_used_ports_release_all(used_ports); } if (try_bind) { err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local, sizeof(sk->s_local)); if (err != 0) { errsv = errno; NL_DBG(4, "nl_connect(%p): bind() failed with %d (%s)\n", sk, errsv, nl_strerror_l(errsv)); err = -nl_syserr2nlerr(errsv); goto errout; } } addrlen = sizeof(local); err = getsockname(sk->s_fd, (struct sockaddr *) &local, &addrlen); if (err < 0) { NL_DBG(4, "nl_connect(%p): getsockname() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); err = -nl_syserr2nlerr(errno); goto errout; } if (addrlen != sizeof(local)) { err = -NLE_NOADDR; goto errout; } if (local.nl_family != AF_NETLINK) { err = -NLE_AF_NOSUPPORT; goto errout; } if (sk->s_local.nl_pid != local.nl_pid) { /* The port id is different. That can happen if the port id was zero * and kernel assigned a local port. */ nl_socket_set_local_port (sk, local.nl_pid); } sk->s_local = local; sk->s_proto = protocol; return 0; errout: if (sk->s_fd != -1) { close(sk->s_fd); sk->s_fd = -1; } return err; } /** * Close Netlink socket * @arg sk Netlink socket (required) * * Closes the Netlink socket using `close()`. * * @note The socket is closed automatically if a `struct nl_sock` object is * freed using `nl_socket_free()`. * * @see nl_connect() */ void nl_close(struct nl_sock *sk) { if (sk->s_fd >= 0) { close(sk->s_fd); sk->s_fd = -1; } sk->s_proto = 0; } /** @} */ /** * @name Send * @{ */ /** * Transmit raw data over Netlink socket. * @arg sk Netlink socket (required) * @arg buf Buffer carrying data to send (required) * @arg size Size of buffer (required) * * Transmits "raw" data over the specified Netlink socket. Unlike the other * transmit functions it does not modify the data in any way. It directly * passes the buffer \c buf of \c size to sendto(). * * The message is addressed to the peer as specified in the socket by either * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function. * * @note Because there is no indication on the message boundaries of the data * being sent, the \c NL_CB_MSG_OUT callback handler will not be invoked * for data that is being sent using this function. * * @see nl_socket_set_peer_port() * @see nl_socket_set_peer_groups() * @see nl_sendmsg() * * @return Number of bytes sent or a negative error code. */ int nl_sendto(struct nl_sock *sk, void *buf, size_t size) { int ret; if (!buf) return -NLE_INVAL; if (sk->s_fd < 0) return -NLE_BAD_SOCK; ret = sendto(sk->s_fd, buf, size, 0, (struct sockaddr *) &sk->s_peer, sizeof(sk->s_peer)); if (ret < 0) { NL_DBG(4, "nl_sendto(%p): sendto() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } return ret; } /** * Transmit Netlink message using sendmsg() * @arg sk Netlink socket (required) * @arg msg Netlink message to be sent (required) * @arg hdr sendmsg() message header (required) * * Transmits the message specified in \c hdr over the Netlink socket using the * sendmsg() system call. * * @attention * The `msg` argument will *not* be used to derive the message payload that * is being sent out. The `msg` argument is *only* passed on to the * `NL_CB_MSG_OUT` callback. The caller is responsible to initialize the * `hdr` struct properly and have it point to the message payload and * socket address. * * @note * This function uses `nlmsg_set_src()` to modify the `msg` argument prior to * invoking the `NL_CB_MSG_OUT` callback to provide the local port number. * * @callback This function triggers the `NL_CB_MSG_OUT` callback. * * @attention * Think twice before using this function. It provides a low level access to * the Netlink socket. Among other limitations, it does not add credentials * even if enabled or respect the destination address specified in the `msg` * object. * * @see nl_socket_set_local_port() * @see nl_send_auto() * @see nl_send_iovec() * * @return Number of bytes sent on success or a negative error code. * * @lowlevel */ int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr) { struct nl_cb *cb; int ret; if (sk->s_fd < 0) return -NLE_BAD_SOCK; nlmsg_set_src(msg, &sk->s_local); cb = sk->s_cb; if (cb->cb_set[NL_CB_MSG_OUT]) if ((ret = nl_cb_call(cb, NL_CB_MSG_OUT, msg)) != NL_OK) return ret; ret = sendmsg(sk->s_fd, hdr, 0); if (ret < 0) { NL_DBG(4, "nl_sendmsg(%p): sendmsg() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); return -nl_syserr2nlerr(errno); } NL_DBG(4, "sent %d bytes\n", ret); return ret; } /** * Transmit Netlink message (taking IO vector) * @arg sk Netlink socket (required) * @arg msg Netlink message to be sent (required) * @arg iov IO vector to be sent (required) * @arg iovlen Number of struct iovec to be sent (required) * * This function is identical to nl_send() except that instead of taking a * `struct nl_msg` object it takes an IO vector. Please see the description * of `nl_send()`. * * @callback This function triggers the `NL_CB_MSG_OUT` callback. * * @see nl_send() * * @return Number of bytes sent on success or a negative error code. * * @lowlevel */ int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen) { struct sockaddr_nl *dst; struct ucred *creds; struct msghdr hdr = { .msg_name = (void *) &sk->s_peer, .msg_namelen = sizeof(struct sockaddr_nl), .msg_iov = iov, .msg_iovlen = iovlen, }; char buf[CMSG_SPACE(sizeof(struct ucred))]; /* Overwrite destination if specified in the message itself, defaults * to the peer address of the socket. */ dst = nlmsg_get_dst(msg); if (dst->nl_family == AF_NETLINK) hdr.msg_name = dst; /* Add credentials if present. */ creds = nlmsg_get_creds(msg); if (creds != NULL) { struct cmsghdr *cmsg; hdr.msg_control = buf; hdr.msg_controllen = sizeof(buf); cmsg = CMSG_FIRSTHDR(&hdr); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_CREDENTIALS; cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred)); } return nl_sendmsg(sk, msg, &hdr); } /** * Transmit Netlink message * @arg sk Netlink socket (required) * @arg msg Netlink message (required) * * Transmits the Netlink message `msg` over the Netlink socket using the * `sendmsg()` system call. This function is based on `nl_send_iovec()` but * takes care of initializing a `struct iovec` based on the `msg` object. * * The message is addressed to the peer as specified in the socket by either * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function. * The peer address can be overwritten by specifying an address in the `msg` * object using nlmsg_set_dst(). * * If present in the `msg`, credentials set by the nlmsg_set_creds() function * are added to the control buffer of the message. * * @par Overwriting Capability: * Calls to this function can be overwritten by providing an alternative using * the nl_cb_overwrite_send() function. * * @callback This function triggers the `NL_CB_MSG_OUT` callback. * * @attention * Unlike `nl_send_auto()`, this function does *not* finalize the message in * terms of automatically adding needed flags or filling out port numbers. * * @see nl_send_auto() * @see nl_send_iovec() * @see nl_socket_set_peer_port() * @see nl_socket_set_peer_groups() * @see nlmsg_set_dst() * @see nlmsg_set_creds() * @see nl_cb_overwrite_send() * * @return Number of bytes sent on success or a negative error code. */ int nl_send(struct nl_sock *sk, struct nl_msg *msg) { struct nl_cb *cb = sk->s_cb; if (cb->cb_send_ow) return cb->cb_send_ow(sk, msg); else { struct iovec iov = { .iov_base = (void *) nlmsg_hdr(msg), .iov_len = nlmsg_hdr(msg)->nlmsg_len, }; return nl_send_iovec(sk, msg, &iov, 1); } } /** * Finalize Netlink message * @arg sk Netlink socket (required) * @arg msg Netlink message (required) * * This function finalizes a Netlink message by completing the message with * desirable flags and values depending on the socket configuration. * * - If not yet filled out, the source address of the message (`nlmsg_pid`) * will be set to the local port number of the socket. * - If not yet specified, the next available sequence number is assigned * to the message (`nlmsg_seq`). * - If not yet specified, the protocol field of the message will be set to * the protocol field of the socket. * - The `NLM_F_REQUEST` Netlink message flag will be set. * - The `NLM_F_ACK` flag will be set if Auto-ACK mode is enabled on the * socket. */ void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg) { struct nlmsghdr *nlh; nlh = nlmsg_hdr(msg); if (nlh->nlmsg_pid == NL_AUTO_PORT) nlh->nlmsg_pid = nl_socket_get_local_port(sk); if (nlh->nlmsg_seq == NL_AUTO_SEQ) nlh->nlmsg_seq = sk->s_seq_next++; if (msg->nm_protocol == -1) msg->nm_protocol = sk->s_proto; nlh->nlmsg_flags |= NLM_F_REQUEST; if (!(sk->s_flags & NL_NO_AUTO_ACK)) nlh->nlmsg_flags |= NLM_F_ACK; } /** * Finalize and transmit Netlink message * @arg sk Netlink socket (required) * @arg msg Netlink message (required) * * Finalizes the message by passing it to `nl_complete_msg()` and transmits it * by passing it to `nl_send()`. * * @callback This function triggers the `NL_CB_MSG_OUT` callback. * * @see nl_complete_msg() * @see nl_send() * * @return Number of bytes sent or a negative error code. */ int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg) { nl_complete_msg(sk, msg); return nl_send(sk, msg); } /** * Finalize and transmit Netlink message and wait for ACK or error message * @arg sk Netlink socket (required) * @arg msg Netlink message (required) * * Passes the `msg` to `nl_send_auto()` to finalize and transmit it. Frees the * message and waits (sleeps) for the ACK or error message to be received. * * @attention * Disabling Auto-ACK (nl_socket_disable_auto_ack()) will cause this function * to return immediately after transmitting the message. However, the peer may * still be returning an error message in response to the request. It is the * responsibility of the caller to handle such messages. * * @callback This function triggers the `NL_CB_MSG_OUT` callback. * * @attention * This function frees the `msg` object after transmitting it by calling * `nlmsg_free()`. * * @see nl_send_auto(). * @see nl_wait_for_ack() * * @return 0 on success or a negative error code. */ int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg) { int err; err = nl_send_auto(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** * Construct and transmit a Netlink message * @arg sk Netlink socket (required) * @arg type Netlink message type (required) * @arg flags Netlink message flags (optional) * @arg buf Data buffer (optional) * @arg size Size of data buffer (optional) * * Allocates a new Netlink message based on `type` and `flags`. If `buf` * points to payload of length `size` that payload will be appended to the * message. * * Sends out the message using `nl_send_auto()` and frees the message * afterwards. * * @see nl_send_auto() * * @return Number of characters sent on success or a negative error code. * @retval -NLE_NOMEM Unable to allocate Netlink message */ int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf, size_t size) { int err; struct nl_msg *msg; msg = nlmsg_alloc_simple(type, flags); if (!msg) return -NLE_NOMEM; if (buf && size) { err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO); if (err < 0) goto errout; } err = nl_send_auto(sk, msg); errout: nlmsg_free(msg); return err; } /** @} */ /** * @name Receive * @{ */ /** * Receive data from netlink socket * @arg sk Netlink socket (required) * @arg nla Netlink socket structure to hold address of peer (required) * @arg buf Destination pointer for message content (required) * @arg creds Destination pointer for credentials (optional) * * Receives data from a connected netlink socket using recvmsg() and returns * the number of bytes read. The read data is stored in a newly allocated * buffer that is assigned to \c *buf. The peer's netlink address will be * stored in \c *nla. * * This function blocks until data is available to be read unless the socket * has been put into non-blocking mode using nl_socket_set_nonblocking() in * which case this function will return immediately with a return value of 0. * * The buffer size used when reading from the netlink socket and thus limiting * the maximum size of a netlink message that can be read defaults to the size * of a memory page (getpagesize()). The buffer size can be modified on a per * socket level using the function nl_socket_set_msg_buf_size(). * * If message peeking is enabled using nl_socket_enable_msg_peek() the size of * the message to be read will be determined using the MSG_PEEK flag prior to * performing the actual read. This leads to an additional recvmsg() call for * every read operation which has performance implications and is not * recommended for high throughput protocols. * * An eventual interruption of the recvmsg() system call is automatically * handled by retrying the operation. * * If receiving of credentials has been enabled using the function * nl_socket_set_passcred(), this function will allocate a new struct ucred * filled with the received credentials and assign it to \c *creds. The caller * is responsible for freeing the buffer. * * @note The caller is responsible to free the returned data buffer and if * enabled, the credentials buffer. * * @see nl_socket_set_nonblocking() * @see nl_socket_set_msg_buf_size() * @see nl_socket_enable_msg_peek() * @see nl_socket_set_passcred() * * @return Number of bytes read, 0 on EOF, 0 on no data event (non-blocking * mode), or a negative error code. */ int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla, unsigned char **buf, struct ucred **creds) { ssize_t n; int flags = 0; static int page_size = 0; struct iovec iov; struct msghdr msg = { .msg_name = (void *) nla, .msg_namelen = sizeof(struct sockaddr_nl), .msg_iov = &iov, .msg_iovlen = 1, }; struct ucred* tmpcreds = NULL; int retval = 0; if (!buf || !nla) return -NLE_INVAL; if ( (sk->s_flags & NL_MSG_PEEK) || (!(sk->s_flags & NL_MSG_PEEK_EXPLICIT) && sk->s_bufsize == 0)) flags |= MSG_PEEK | MSG_TRUNC; if (page_size == 0) page_size = getpagesize() * 4; iov.iov_len = sk->s_bufsize ? : page_size; iov.iov_base = malloc(iov.iov_len); if (!iov.iov_base) { retval = -NLE_NOMEM; goto abort; } if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) { msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred)); msg.msg_control = malloc(msg.msg_controllen); if (!msg.msg_control) { retval = -NLE_NOMEM; goto abort; } } retry: n = recvmsg(sk->s_fd, &msg, flags); if (!n) { retval = 0; goto abort; } if (n < 0) { if (errno == EINTR) { NL_DBG(3, "recvmsg() returned EINTR, retrying\n"); goto retry; } NL_DBG(4, "nl_sendmsg(%p): nl_recv() failed with %d (%s)\n", sk, errno, nl_strerror_l(errno)); retval = -nl_syserr2nlerr(errno); goto abort; } if (msg.msg_flags & MSG_CTRUNC) { void *tmp; if (msg.msg_controllen == 0) { retval = -NLE_MSG_TRUNC; NL_DBG(4, "recvmsg(%p): Received unexpected control data", sk); goto abort; } msg.msg_controllen *= 2; tmp = realloc(msg.msg_control, msg.msg_controllen); if (!tmp) { retval = -NLE_NOMEM; goto abort; } msg.msg_control = tmp; goto retry; } if (iov.iov_len < n || (msg.msg_flags & MSG_TRUNC)) { void *tmp; /* respond with error to an incomplete message */ if (flags == 0) { retval = -NLE_MSG_TRUNC; goto abort; } /* Provided buffer is not long enough, enlarge it * to size of n (which should be total length of the message) * and try again. */ iov.iov_len = n; tmp = realloc(iov.iov_base, iov.iov_len); if (!tmp) { retval = -NLE_NOMEM; goto abort; } iov.iov_base = tmp; flags = 0; goto retry; } if (flags != 0) { /* Buffer is big enough, do the actual reading */ flags = 0; goto retry; } if (msg.msg_namelen != sizeof(struct sockaddr_nl)) { retval = -NLE_NOADDR; goto abort; } if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) { struct cmsghdr *cmsg; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) continue; if (cmsg->cmsg_type != SCM_CREDENTIALS) continue; tmpcreds = malloc(sizeof(*tmpcreds)); if (!tmpcreds) { retval = -NLE_NOMEM; goto abort; } memcpy(tmpcreds, CMSG_DATA(cmsg), sizeof(*tmpcreds)); break; } } retval = n; abort: free(msg.msg_control); if (retval <= 0) { free(iov.iov_base); iov.iov_base = NULL; free(tmpcreds); tmpcreds = NULL; } else *buf = iov.iov_base; if (creds) *creds = tmpcreds; return retval; } /** @cond SKIP */ #define NL_CB_CALL(cb, type, msg) \ do { \ err = nl_cb_call(cb, type, msg); \ switch (err) { \ case NL_OK: \ err = 0; \ break; \ case NL_SKIP: \ goto skip; \ case NL_STOP: \ goto stop; \ default: \ goto out; \ } \ } while (0) /** @endcond */ static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb) { int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0; unsigned char *buf = NULL; struct nlmsghdr *hdr; /* nla is passed on to not only to nl_recv() but may also be passed to a function pointer provided by the caller which may or may not initialize the variable. Thomas Graf. */ struct sockaddr_nl nla = {0}; struct nl_msg *msg = NULL; struct ucred *creds = NULL; continue_reading: NL_DBG(3, "Attempting to read from %p\n", sk); if (cb->cb_recv_ow) n = cb->cb_recv_ow(sk, &nla, &buf, &creds); else n = nl_recv(sk, &nla, &buf, &creds); if (n <= 0) return n; NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n); hdr = (struct nlmsghdr *) buf; while (nlmsg_ok(hdr, n)) { NL_DBG(3, "recvmsgs(%p): Processing valid message...\n", sk); nlmsg_free(msg); msg = nlmsg_convert(hdr); if (!msg) { err = -NLE_NOMEM; goto out; } nlmsg_set_proto(msg, sk->s_proto); nlmsg_set_src(msg, &nla); if (creds) nlmsg_set_creds(msg, creds); nrecv++; /* Raw callback is the first, it gives the most control * to the user and he can do his very own parsing. */ if (cb->cb_set[NL_CB_MSG_IN]) NL_CB_CALL(cb, NL_CB_MSG_IN, msg); /* Sequence number checking. The check may be done by * the user, otherwise a very simple check is applied * enforcing strict ordering */ if (cb->cb_set[NL_CB_SEQ_CHECK]) { NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg); /* Only do sequence checking if auto-ack mode is enabled */ } else if (!(sk->s_flags & NL_NO_AUTO_ACK)) { if (hdr->nlmsg_seq != sk->s_seq_expect) { if (cb->cb_set[NL_CB_INVALID]) NL_CB_CALL(cb, NL_CB_INVALID, msg); else { err = -NLE_SEQ_MISMATCH; goto out; } } } if (hdr->nlmsg_type == NLMSG_DONE || hdr->nlmsg_type == NLMSG_ERROR || hdr->nlmsg_type == NLMSG_NOOP || hdr->nlmsg_type == NLMSG_OVERRUN) { /* We can't check for !NLM_F_MULTI since some netlink * users in the kernel are broken. */ sk->s_seq_expect++; NL_DBG(3, "recvmsgs(%p): Increased expected " \ "sequence number to %d\n", sk, sk->s_seq_expect); } if (hdr->nlmsg_flags & NLM_F_MULTI) multipart = 1; if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) { if (cb->cb_set[NL_CB_DUMP_INTR]) NL_CB_CALL(cb, NL_CB_DUMP_INTR, msg); else { /* * We have to continue reading to clear * all messages until a NLMSG_DONE is * received and report the inconsistency. */ interrupted = 1; } } /* Other side wishes to see an ack for this message */ if (hdr->nlmsg_flags & NLM_F_ACK) { if (cb->cb_set[NL_CB_SEND_ACK]) NL_CB_CALL(cb, NL_CB_SEND_ACK, msg); else { /* FIXME: implement */ } } /* messages terminates a multipart message, this is * usually the end of a message and therefore we slip * out of the loop by default. the user may overrule * this action by skipping this packet. */ if (hdr->nlmsg_type == NLMSG_DONE) { multipart = 0; if (cb->cb_set[NL_CB_FINISH]) NL_CB_CALL(cb, NL_CB_FINISH, msg); } /* Message to be ignored, the default action is to * skip this message if no callback is specified. The * user may overrule this action by returning * NL_PROCEED. */ else if (hdr->nlmsg_type == NLMSG_NOOP) { if (cb->cb_set[NL_CB_SKIPPED]) NL_CB_CALL(cb, NL_CB_SKIPPED, msg); else goto skip; } /* Data got lost, report back to user. The default action is to * quit parsing. The user may overrule this action by retuning * NL_SKIP or NL_PROCEED (dangerous) */ else if (hdr->nlmsg_type == NLMSG_OVERRUN) { if (cb->cb_set[NL_CB_OVERRUN]) NL_CB_CALL(cb, NL_CB_OVERRUN, msg); else { err = -NLE_MSG_OVERFLOW; goto out; } } /* Message carries a nlmsgerr */ else if (hdr->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *e = nlmsg_data(hdr); if (hdr->nlmsg_len < nlmsg_size(sizeof(*e))) { /* Truncated error message, the default action * is to stop parsing. The user may overrule * this action by returning NL_SKIP or * NL_PROCEED (dangerous) */ if (cb->cb_set[NL_CB_INVALID]) NL_CB_CALL(cb, NL_CB_INVALID, msg); else { err = -NLE_MSG_TRUNC; goto out; } } else if (e->error) { NL_DBG(4, "recvmsgs(%p): RTNETLINK responded with %d (%s)\n", sk, -e->error, nl_strerror_l(-e->error)); /* Error message reported back from kernel. */ if (cb->cb_err) { err = cb->cb_err(&nla, e, cb->cb_err_arg); if (err < 0) goto out; else if (err == NL_SKIP) goto skip; else if (err == NL_STOP) { err = -nl_syserr2nlerr(e->error); goto out; } } else { err = -nl_syserr2nlerr(e->error); goto out; } } else if (cb->cb_set[NL_CB_ACK]) NL_CB_CALL(cb, NL_CB_ACK, msg); } else { /* Valid message (not checking for MULTIPART bit to * get along with broken kernels. NL_SKIP has no * effect on this. */ if (cb->cb_set[NL_CB_VALID]) NL_CB_CALL(cb, NL_CB_VALID, msg); } skip: err = 0; hdr = nlmsg_next(hdr, &n); } nlmsg_free(msg); free(buf); free(creds); buf = NULL; msg = NULL; creds = NULL; if (multipart) { /* Multipart message not yet complete, continue reading */ goto continue_reading; } stop: err = 0; out: nlmsg_free(msg); free(buf); free(creds); if (interrupted) err = -NLE_DUMP_INTR; if (!err) err = nrecv; return err; } /** * Receive a set of messages from a netlink socket and report parsed messages * @arg sk Netlink socket. * @arg cb set of callbacks to control behaviour. * * This function is identical to nl_recvmsgs() to the point that it will * return the number of parsed messages instead of 0 on success. * * @see nl_recvmsgs() * * @return Number of received messages or a negative error code from nl_recv(). */ int nl_recvmsgs_report(struct nl_sock *sk, struct nl_cb *cb) { if (cb->cb_recvmsgs_ow) return cb->cb_recvmsgs_ow(sk, cb); else return recvmsgs(sk, cb); } /** * Receive a set of messages from a netlink socket. * @arg sk Netlink socket. * @arg cb set of callbacks to control behaviour. * * Repeatedly calls nl_recv() or the respective replacement if provided * by the application (see nl_cb_overwrite_recv()) and parses the * received data as netlink messages. Stops reading if one of the * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code. * * A non-blocking sockets causes the function to return immediately if * no data is available. * * @see nl_recvmsgs_report() * * @return 0 on success or a negative error code from nl_recv(). */ int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb) { int err; if ((err = nl_recvmsgs_report(sk, cb)) > 0) err = 0; return err; } /** * Receive a set of message from a netlink socket using handlers in nl_sock. * @arg sk Netlink socket. * * Calls nl_recvmsgs() with the handlers configured in the netlink socket. */ int nl_recvmsgs_default(struct nl_sock *sk) { return nl_recvmsgs(sk, sk->s_cb); } static int ack_wait_handler(struct nl_msg *msg, void *arg) { return NL_STOP; } /** * Wait for ACK. * @arg sk Netlink socket. * @pre The netlink socket must be in blocking state. * * Waits until an ACK is received for the latest not yet acknowledged * netlink message. */ int nl_wait_for_ack(struct nl_sock *sk) { int err; struct nl_cb *cb; cb = nl_cb_clone(sk->s_cb); if (cb == NULL) return -NLE_NOMEM; nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL); err = nl_recvmsgs(sk, cb); nl_cb_put(cb); return err; } /** @cond SKIP */ struct pickup_param { int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *); struct nl_object *result; int *syserror; }; static int __store_answer(struct nl_object *obj, struct nl_parser_param *p) { struct pickup_param *pp = p->pp_arg; /* * the parser will put() the object at the end, expecting the cache * to take the reference. */ nl_object_get(obj); pp->result = obj; return 0; } static int __pickup_answer(struct nl_msg *msg, void *arg) { struct pickup_param *pp = arg; struct nl_parser_param parse_arg = { .pp_cb = __store_answer, .pp_arg = pp, }; return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg); } static int __pickup_answer_syserr(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg) { *(((struct pickup_param *) arg)->syserror) = nlerr->error; return -nl_syserr2nlerr(nlerr->error); } /** @endcond */ /** * Pickup netlink answer, parse is and return object * @arg sk Netlink socket * @arg parser Parser function to parse answer * @arg result Result pointer to return parsed object * * @return 0 on success or a negative error code. */ int nl_pickup(struct nl_sock *sk, int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result) { return nl_pickup_keep_syserr(sk, parser, result, NULL); } /** * Pickup netlink answer, parse is and return object with preserving system error * @arg sk Netlink socket * @arg parser Parser function to parse answer * @arg result Result pointer to return parsed object * @arg syserr Result pointer for the system error in case of failure * * @return 0 on success or a negative error code. */ int nl_pickup_keep_syserr(struct nl_sock *sk, int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result, int *syserror) { struct nl_cb *cb; int err; struct pickup_param pp = { .parser = parser, }; cb = nl_cb_clone(sk->s_cb); if (cb == NULL) return -NLE_NOMEM; nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp); if (syserror) { *syserror = 0; pp.syserror = syserror; nl_cb_err(cb, NL_CB_CUSTOM, __pickup_answer_syserr, &pp); } err = nl_recvmsgs(sk, cb); if (err < 0) goto errout; *result = pp.result; errout: nl_cb_put(cb); return err; } /** @} */ /** * @name Deprecated * @{ */ /** * @deprecated Please use nl_complete_msg() */ void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg) { nl_complete_msg(sk, msg); } /** * @deprecated Please use nl_send_auto() */ int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg) { return nl_send_auto(sk, msg); } /** @} */ /** @} */ /** @} */ libnl-3.2.29/lib/Makefile.in0000644000175000017500000020255613031473644012462 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- Makefile -*- VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = defs.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(nobase_pkglib_LTLIBRARIES) cli_cls_basic_la_LIBADD = cli_cls_basic_la_SOURCES = cli/cls/basic.c am__dirstamp = $(am__leading_dot)dirstamp cli_cls_basic_la_OBJECTS = cli/cls/basic.lo AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = cli_cls_basic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_cls_basic_la_LDFLAGS) $(LDFLAGS) \ -o $@ @ENABLE_CLI_TRUE@am_cli_cls_basic_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/cls cli_cls_cgroup_la_LIBADD = cli_cls_cgroup_la_SOURCES = cli/cls/cgroup.c cli_cls_cgroup_la_OBJECTS = cli/cls/cgroup.lo cli_cls_cgroup_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_cls_cgroup_la_LDFLAGS) $(LDFLAGS) \ -o $@ @ENABLE_CLI_TRUE@am_cli_cls_cgroup_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/cls cli_qdisc_bfifo_la_LIBADD = cli_qdisc_bfifo_la_SOURCES = cli/qdisc/bfifo.c cli_qdisc_bfifo_la_OBJECTS = cli/qdisc/bfifo.lo cli_qdisc_bfifo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_bfifo_la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_bfifo_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc cli_qdisc_blackhole_la_LIBADD = cli_qdisc_blackhole_la_SOURCES = cli/qdisc/blackhole.c cli_qdisc_blackhole_la_OBJECTS = cli/qdisc/blackhole.lo cli_qdisc_blackhole_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_blackhole_la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_blackhole_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc cli_qdisc_fq_codel_la_LIBADD = cli_qdisc_fq_codel_la_SOURCES = cli/qdisc/fq_codel.c cli_qdisc_fq_codel_la_OBJECTS = cli/qdisc/fq_codel.lo cli_qdisc_fq_codel_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_fq_codel_la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_fq_codel_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc cli_qdisc_hfsc_la_LIBADD = cli_qdisc_hfsc_la_SOURCES = cli/qdisc/hfsc.c cli_qdisc_hfsc_la_OBJECTS = cli/qdisc/hfsc.lo cli_qdisc_hfsc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_hfsc_la_LDFLAGS) $(LDFLAGS) \ -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_hfsc_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc cli_qdisc_htb_la_LIBADD = cli_qdisc_htb_la_SOURCES = cli/qdisc/htb.c cli_qdisc_htb_la_OBJECTS = cli/qdisc/htb.lo cli_qdisc_htb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_htb_la_LDFLAGS) $(LDFLAGS) \ -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_htb_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc cli_qdisc_ingress_la_LIBADD = cli_qdisc_ingress_la_SOURCES = cli/qdisc/ingress.c cli_qdisc_ingress_la_OBJECTS = cli/qdisc/ingress.lo cli_qdisc_ingress_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_ingress_la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_ingress_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc cli_qdisc_pfifo_la_LIBADD = cli_qdisc_pfifo_la_SOURCES = cli/qdisc/pfifo.c cli_qdisc_pfifo_la_OBJECTS = cli/qdisc/pfifo.lo cli_qdisc_pfifo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_pfifo_la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_pfifo_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc cli_qdisc_plug_la_LIBADD = cli_qdisc_plug_la_SOURCES = cli/qdisc/plug.c cli_qdisc_plug_la_OBJECTS = cli/qdisc/plug.lo cli_qdisc_plug_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cli_qdisc_plug_la_LDFLAGS) $(LDFLAGS) \ -o $@ @ENABLE_CLI_TRUE@am_cli_qdisc_plug_la_rpath = -rpath \ @ENABLE_CLI_TRUE@ $(pkglibdir)/cli/qdisc libnl_3_la_LIBADD = am_libnl_3_la_OBJECTS = addr.lo attr.lo cache.lo cache_mngr.lo \ cache_mngt.lo data.lo error.lo handlers.lo msg.lo nl.lo \ object.lo socket.lo utils.lo version.lo hash.lo hashtable.lo libnl_3_la_OBJECTS = $(am_libnl_3_la_OBJECTS) libnl_3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libnl_3_la_LDFLAGS) $(LDFLAGS) -o $@ am_libnl_genl_3_la_OBJECTS = genl/ctrl.lo genl/family.lo genl/genl.lo \ genl/mngt.lo libnl_genl_3_la_OBJECTS = $(am_libnl_genl_3_la_OBJECTS) libnl_genl_3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libnl_genl_3_la_LDFLAGS) $(LDFLAGS) \ -o $@ am_libnl_idiag_3_la_OBJECTS = idiag/idiag_meminfo_obj.lo \ idiag/idiag_vegasinfo_obj.lo idiag/idiag_msg_obj.lo \ idiag/idiag_req_obj.lo idiag/idiag.lo libnl_idiag_3_la_OBJECTS = $(am_libnl_idiag_3_la_OBJECTS) libnl_idiag_3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libnl_idiag_3_la_LDFLAGS) $(LDFLAGS) \ -o $@ am_libnl_nf_3_la_OBJECTS = netfilter/ct.lo netfilter/ct_obj.lo \ netfilter/log.lo netfilter/log_msg.lo netfilter/log_msg_obj.lo \ netfilter/log_obj.lo netfilter/netfilter.lo netfilter/nfnl.lo \ netfilter/queue.lo netfilter/queue_msg.lo \ netfilter/queue_msg_obj.lo netfilter/queue_obj.lo \ netfilter/exp.lo netfilter/exp_obj.lo libnl_nf_3_la_OBJECTS = $(am_libnl_nf_3_la_OBJECTS) libnl_nf_3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libnl_nf_3_la_LDFLAGS) $(LDFLAGS) -o $@ am_libnl_route_3_la_OBJECTS = route/addr.lo route/class.lo \ route/cls.lo route/act.lo route/link.lo route/neigh.lo \ route/neightbl.lo route/nexthop.lo route/qdisc.lo \ route/route.lo route/route_obj.lo route/route_utils.lo \ route/rtnl.lo route/rule.lo route/tc.lo route/classid.lo \ route/link/sriov.lo route/cls/fw.lo route/cls/police.lo \ route/cls/u32.lo route/cls/basic.lo route/cls/cgroup.lo \ route/act/mirred.lo route/act/skbedit.lo route/act/gact.lo \ route/cls/ematch.lo route/cls/ematch/container.lo \ route/cls/ematch/cmp.lo route/cls/ematch/nbyte.lo \ route/cls/ematch/text.lo route/cls/ematch/meta.lo \ route/link/api.lo route/link/vlan.lo route/link/dummy.lo \ route/link/bridge.lo route/link/inet6.lo route/link/inet.lo \ route/link/bonding.lo route/link/can.lo route/link/macvlan.lo \ route/link/vxlan.lo route/link/veth.lo route/link/ipip.lo \ route/link/ipgre.lo route/link/sit.lo route/link/ipvti.lo \ route/link/ip6tnl.lo route/link/ifb.lo route/link/ipvlan.lo \ route/link/vrf.lo route/link/macsec.lo route/link/ppp.lo \ route/qdisc/blackhole.lo route/qdisc/cbq.lo \ route/qdisc/dsmark.lo route/qdisc/fifo.lo route/qdisc/htb.lo \ route/qdisc/netem.lo route/qdisc/prio.lo route/qdisc/red.lo \ route/qdisc/sfq.lo route/qdisc/tbf.lo route/qdisc/plug.lo \ route/qdisc/ingress.lo route/qdisc/fq_codel.lo \ route/qdisc/hfsc.lo fib_lookup/lookup.lo fib_lookup/request.lo \ route/pktloc.lo nodist_libnl_route_3_la_OBJECTS = route/pktloc_syntax.lo \ route/pktloc_grammar.lo route/cls/ematch_syntax.lo \ route/cls/ematch_grammar.lo libnl_route_3_la_OBJECTS = $(am_libnl_route_3_la_OBJECTS) \ $(nodist_libnl_route_3_la_OBJECTS) libnl_route_3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libnl_route_3_la_LDFLAGS) $(LDFLAGS) \ -o $@ am_libnl_xfrm_3_la_OBJECTS = xfrm/ae.lo xfrm/lifetime.lo xfrm/sa.lo \ xfrm/selector.lo xfrm/sp.lo xfrm/template.lo libnl_xfrm_3_la_OBJECTS = $(am_libnl_xfrm_3_la_OBJECTS) libnl_xfrm_3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libnl_xfrm_3_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = cli/cls/basic.c cli/cls/cgroup.c cli/qdisc/bfifo.c \ cli/qdisc/blackhole.c cli/qdisc/fq_codel.c cli/qdisc/hfsc.c \ cli/qdisc/htb.c cli/qdisc/ingress.c cli/qdisc/pfifo.c \ cli/qdisc/plug.c $(libnl_3_la_SOURCES) \ $(libnl_genl_3_la_SOURCES) $(libnl_idiag_3_la_SOURCES) \ $(libnl_nf_3_la_SOURCES) $(libnl_route_3_la_SOURCES) \ $(nodist_libnl_route_3_la_SOURCES) $(libnl_xfrm_3_la_SOURCES) DIST_SOURCES = cli/cls/basic.c cli/cls/cgroup.c cli/qdisc/bfifo.c \ cli/qdisc/blackhole.c cli/qdisc/fq_codel.c cli/qdisc/hfsc.c \ cli/qdisc/htb.c cli/qdisc/ingress.c cli/qdisc/pfifo.c \ cli/qdisc/plug.c $(libnl_3_la_SOURCES) \ $(libnl_genl_3_la_SOURCES) $(libnl_idiag_3_la_SOURCES) \ $(libnl_nf_3_la_SOURCES) $(libnl_route_3_la_SOURCES) \ $(libnl_xfrm_3_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)defs.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/defs.h.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLEX = @FLEX@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNL_VERSION = @LIBNL_VERSION@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_REVISION = @LT_REVISION@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAJ_VERSION = @MAJ_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MIC_VERSION = @MIC_VERSION@ MIN_VERSION = @MIN_VERSION@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = \ -Wall \ -I${top_srcdir}/include/linux-private \ -I${top_srcdir}/include \ -I${top_builddir}/include \ -I${builddir}/route \ -I${builddir}/route/cls \ -D_GNU_SOURCE \ -DSYSCONFDIR=\"$(sysconfdir)/libnl\" AM_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) lib_LTLIBRARIES = \ libnl-3.la libnl-genl-3.la libnl-route-3.la libnl-nf-3.la libnl-idiag-3.la libnl-xfrm-3.la libnl_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-3.sym libnl_3_la_DEPENDENCIES = \ $(top_srcdir)/libnl-3.sym libnl_3_la_SOURCES = \ addr.c attr.c cache.c cache_mngr.c cache_mngt.c data.c \ error.c handlers.c msg.c nl.c object.c socket.c utils.c \ version.c hash.c hashtable.c libnl_idiag_3_la_LIBADD = libnl-3.la libnl_idiag_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-idiag-3.sym libnl_idiag_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-idiag-3.sym libnl_idiag_3_la_SOURCES = \ idiag/idiag_meminfo_obj.c idiag/idiag_vegasinfo_obj.c \ idiag/idiag_msg_obj.c idiag/idiag_req_obj.c idiag/idiag.c libnl_genl_3_la_LIBADD = libnl-3.la libnl_genl_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-genl-3.sym libnl_genl_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-genl-3.sym libnl_genl_3_la_SOURCES = \ genl/ctrl.c genl/family.c genl/genl.c genl/mngt.c libnl_nf_3_la_LIBADD = libnl-route-3.la libnl_nf_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-nf-3.sym libnl_nf_3_la_DEPENDENCIES = \ libnl-route-3.la \ $(top_srcdir)/libnl-nf-3.sym libnl_nf_3_la_SOURCES = \ netfilter/ct.c netfilter/ct_obj.c netfilter/log.c \ netfilter/log_msg.c netfilter/log_msg_obj.c netfilter/log_obj.c \ netfilter/netfilter.c netfilter/nfnl.c netfilter/queue.c \ netfilter/queue_msg.c netfilter/queue_msg_obj.c netfilter/queue_obj.c \ netfilter/exp.c netfilter/exp_obj.c CLEANFILES = \ route/pktloc_grammar.c route/pktloc_grammar.h \ route/pktloc_syntax.c route/pktloc_syntax.h \ route/cls/ematch_grammar.c route/cls/ematch_grammar.h \ route/cls/ematch_syntax.c route/cls/ematch_syntax.h libnl_route_3_la_LIBADD = libnl-3.la libnl_route_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-route-3.sym libnl_route_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-route-3.sym libnl_route_3_la_SOURCES = \ route/addr.c route/class.c route/cls.c route/act.c route/link.c \ route/neigh.c route/neightbl.c route/nexthop.c route/qdisc.c \ route/route.c route/route_obj.c route/route_utils.c route/rtnl.c \ route/rule.c route/tc.c route/classid.c route/link/sriov.c \ \ route/cls/fw.c route/cls/police.c route/cls/u32.c route/cls/basic.c \ route/cls/cgroup.c \ \ route/act/mirred.c \ route/act/skbedit.c \ route/act/gact.c \ \ route/cls/ematch.c \ route/cls/ematch/container.c route/cls/ematch/cmp.c \ route/cls/ematch/nbyte.c route/cls/ematch/text.c \ route/cls/ematch/meta.c \ \ route/link/api.c route/link/vlan.c route/link/dummy.c \ route/link/bridge.c route/link/inet6.c route/link/inet.c \ route/link/bonding.c route/link/can.c route/link/macvlan.c \ route/link/vxlan.c route/link/veth.c route/link/ipip.c \ route/link/ipgre.c route/link/sit.c route/link/ipvti.c \ route/link/ip6tnl.c route/link/ifb.c route/link/ipvlan.c \ route/link/vrf.c route/link/macsec.c route/link/ppp.c \ \ route/qdisc/blackhole.c route/qdisc/cbq.c route/qdisc/dsmark.c \ route/qdisc/fifo.c route/qdisc/htb.c route/qdisc/netem.c \ route/qdisc/prio.c route/qdisc/red.c route/qdisc/sfq.c \ route/qdisc/tbf.c route/qdisc/plug.c route/qdisc/ingress.c \ route/qdisc/fq_codel.c route/qdisc/hfsc.c \ \ fib_lookup/lookup.c fib_lookup/request.c \ \ route/pktloc.c nodist_libnl_route_3_la_SOURCES = \ route/pktloc_syntax.c route/pktloc_syntax.h \ route/pktloc_grammar.c route/pktloc_grammar.h \ route/cls/ematch_syntax.c route/cls/ematch_syntax.h \ route/cls/ematch_grammar.c route/cls/ematch_grammar.h BUILT_SOURCES = \ route/cls/ematch_grammar.c \ route/cls/ematch_syntax.c \ route/pktloc_grammar.c \ route/pktloc_syntax.c EXTRA_DIST = \ route/pktloc_grammar.l \ route/pktloc_syntax.y \ route/cls/ematch_grammar.l \ route/cls/ematch_syntax.y libnl_xfrm_3_la_LIBADD = libnl-3.la libnl_xfrm_3_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -Wl,--version-script=$(top_srcdir)/libnl-xfrm-3.sym libnl_xfrm_3_la_DEPENDENCIES = \ libnl-3.la \ $(top_srcdir)/libnl-xfrm-3.sym libnl_xfrm_3_la_SOURCES = \ xfrm/ae.c \ xfrm/lifetime.c \ xfrm/sa.c \ xfrm/selector.c \ xfrm/sp.c \ xfrm/template.c @ENABLE_CLI_TRUE@nobase_pkglib_LTLIBRARIES = \ @ENABLE_CLI_TRUE@ cli/qdisc/htb.la \ @ENABLE_CLI_TRUE@ cli/qdisc/blackhole.la \ @ENABLE_CLI_TRUE@ cli/qdisc/pfifo.la \ @ENABLE_CLI_TRUE@ cli/qdisc/plug.la \ @ENABLE_CLI_TRUE@ cli/qdisc/bfifo.la \ @ENABLE_CLI_TRUE@ cli/qdisc/ingress.la \ @ENABLE_CLI_TRUE@ cli/qdisc/fq_codel.la \ @ENABLE_CLI_TRUE@ cli/qdisc/hfsc.la \ @ENABLE_CLI_TRUE@ cli/cls/basic.la \ @ENABLE_CLI_TRUE@ cli/cls/cgroup.la @ENABLE_CLI_TRUE@cli_qdisc_htb_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_qdisc_blackhole_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_qdisc_pfifo_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_qdisc_plug_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_qdisc_bfifo_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_qdisc_ingress_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_qdisc_fq_codel_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_qdisc_hfsc_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_cls_basic_la_LDFLAGS = -module -avoid-version @ENABLE_CLI_TRUE@cli_cls_cgroup_la_LDFLAGS = -module -avoid-version all: $(BUILT_SOURCES) defs.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): defs.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/defs.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status lib/defs.h $(srcdir)/defs.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f defs.h stamp-h1 install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-nobase_pkglibLTLIBRARIES: $(nobase_pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(nobase_pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ fi; \ for p in $$list; do if test -f "$$p"; then echo "$$p $$p"; else :; fi; done | \ sed '/ .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { cur = "." } \ { if ($$2 == cur) { files = files " " $$1 } \ else { print cur, files; files = $$1; cur = $$2 } } \ END { print cur, files }' | \ while read dir files; do \ test -z "$$files" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)/$$dir"; }; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$files '$(DESTDIR)$(pkglibdir)/$$dir'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$files "$(DESTDIR)$(pkglibdir)/$$dir" || exit $$?; \ }; \ done uninstall-nobase_pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(nobase_pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ f=$$p; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-nobase_pkglibLTLIBRARIES: -test -z "$(nobase_pkglib_LTLIBRARIES)" || rm -f $(nobase_pkglib_LTLIBRARIES) @list='$(nobase_pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } cli/cls/$(am__dirstamp): @$(MKDIR_P) cli/cls @: > cli/cls/$(am__dirstamp) cli/cls/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) cli/cls/$(DEPDIR) @: > cli/cls/$(DEPDIR)/$(am__dirstamp) cli/cls/basic.lo: cli/cls/$(am__dirstamp) \ cli/cls/$(DEPDIR)/$(am__dirstamp) cli/cls/basic.la: $(cli_cls_basic_la_OBJECTS) $(cli_cls_basic_la_DEPENDENCIES) $(EXTRA_cli_cls_basic_la_DEPENDENCIES) cli/cls/$(am__dirstamp) $(AM_V_CCLD)$(cli_cls_basic_la_LINK) $(am_cli_cls_basic_la_rpath) $(cli_cls_basic_la_OBJECTS) $(cli_cls_basic_la_LIBADD) $(LIBS) cli/cls/cgroup.lo: cli/cls/$(am__dirstamp) \ cli/cls/$(DEPDIR)/$(am__dirstamp) cli/cls/cgroup.la: $(cli_cls_cgroup_la_OBJECTS) $(cli_cls_cgroup_la_DEPENDENCIES) $(EXTRA_cli_cls_cgroup_la_DEPENDENCIES) cli/cls/$(am__dirstamp) $(AM_V_CCLD)$(cli_cls_cgroup_la_LINK) $(am_cli_cls_cgroup_la_rpath) $(cli_cls_cgroup_la_OBJECTS) $(cli_cls_cgroup_la_LIBADD) $(LIBS) cli/qdisc/$(am__dirstamp): @$(MKDIR_P) cli/qdisc @: > cli/qdisc/$(am__dirstamp) cli/qdisc/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) cli/qdisc/$(DEPDIR) @: > cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/bfifo.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/bfifo.la: $(cli_qdisc_bfifo_la_OBJECTS) $(cli_qdisc_bfifo_la_DEPENDENCIES) $(EXTRA_cli_qdisc_bfifo_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_bfifo_la_LINK) $(am_cli_qdisc_bfifo_la_rpath) $(cli_qdisc_bfifo_la_OBJECTS) $(cli_qdisc_bfifo_la_LIBADD) $(LIBS) cli/qdisc/blackhole.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/blackhole.la: $(cli_qdisc_blackhole_la_OBJECTS) $(cli_qdisc_blackhole_la_DEPENDENCIES) $(EXTRA_cli_qdisc_blackhole_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_blackhole_la_LINK) $(am_cli_qdisc_blackhole_la_rpath) $(cli_qdisc_blackhole_la_OBJECTS) $(cli_qdisc_blackhole_la_LIBADD) $(LIBS) cli/qdisc/fq_codel.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/fq_codel.la: $(cli_qdisc_fq_codel_la_OBJECTS) $(cli_qdisc_fq_codel_la_DEPENDENCIES) $(EXTRA_cli_qdisc_fq_codel_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_fq_codel_la_LINK) $(am_cli_qdisc_fq_codel_la_rpath) $(cli_qdisc_fq_codel_la_OBJECTS) $(cli_qdisc_fq_codel_la_LIBADD) $(LIBS) cli/qdisc/hfsc.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/hfsc.la: $(cli_qdisc_hfsc_la_OBJECTS) $(cli_qdisc_hfsc_la_DEPENDENCIES) $(EXTRA_cli_qdisc_hfsc_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_hfsc_la_LINK) $(am_cli_qdisc_hfsc_la_rpath) $(cli_qdisc_hfsc_la_OBJECTS) $(cli_qdisc_hfsc_la_LIBADD) $(LIBS) cli/qdisc/htb.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/htb.la: $(cli_qdisc_htb_la_OBJECTS) $(cli_qdisc_htb_la_DEPENDENCIES) $(EXTRA_cli_qdisc_htb_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_htb_la_LINK) $(am_cli_qdisc_htb_la_rpath) $(cli_qdisc_htb_la_OBJECTS) $(cli_qdisc_htb_la_LIBADD) $(LIBS) cli/qdisc/ingress.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/ingress.la: $(cli_qdisc_ingress_la_OBJECTS) $(cli_qdisc_ingress_la_DEPENDENCIES) $(EXTRA_cli_qdisc_ingress_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_ingress_la_LINK) $(am_cli_qdisc_ingress_la_rpath) $(cli_qdisc_ingress_la_OBJECTS) $(cli_qdisc_ingress_la_LIBADD) $(LIBS) cli/qdisc/pfifo.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/pfifo.la: $(cli_qdisc_pfifo_la_OBJECTS) $(cli_qdisc_pfifo_la_DEPENDENCIES) $(EXTRA_cli_qdisc_pfifo_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_pfifo_la_LINK) $(am_cli_qdisc_pfifo_la_rpath) $(cli_qdisc_pfifo_la_OBJECTS) $(cli_qdisc_pfifo_la_LIBADD) $(LIBS) cli/qdisc/plug.lo: cli/qdisc/$(am__dirstamp) \ cli/qdisc/$(DEPDIR)/$(am__dirstamp) cli/qdisc/plug.la: $(cli_qdisc_plug_la_OBJECTS) $(cli_qdisc_plug_la_DEPENDENCIES) $(EXTRA_cli_qdisc_plug_la_DEPENDENCIES) cli/qdisc/$(am__dirstamp) $(AM_V_CCLD)$(cli_qdisc_plug_la_LINK) $(am_cli_qdisc_plug_la_rpath) $(cli_qdisc_plug_la_OBJECTS) $(cli_qdisc_plug_la_LIBADD) $(LIBS) libnl-3.la: $(libnl_3_la_OBJECTS) $(libnl_3_la_DEPENDENCIES) $(EXTRA_libnl_3_la_DEPENDENCIES) $(AM_V_CCLD)$(libnl_3_la_LINK) -rpath $(libdir) $(libnl_3_la_OBJECTS) $(libnl_3_la_LIBADD) $(LIBS) genl/$(am__dirstamp): @$(MKDIR_P) genl @: > genl/$(am__dirstamp) genl/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) genl/$(DEPDIR) @: > genl/$(DEPDIR)/$(am__dirstamp) genl/ctrl.lo: genl/$(am__dirstamp) genl/$(DEPDIR)/$(am__dirstamp) genl/family.lo: genl/$(am__dirstamp) genl/$(DEPDIR)/$(am__dirstamp) genl/genl.lo: genl/$(am__dirstamp) genl/$(DEPDIR)/$(am__dirstamp) genl/mngt.lo: genl/$(am__dirstamp) genl/$(DEPDIR)/$(am__dirstamp) libnl-genl-3.la: $(libnl_genl_3_la_OBJECTS) $(libnl_genl_3_la_DEPENDENCIES) $(EXTRA_libnl_genl_3_la_DEPENDENCIES) $(AM_V_CCLD)$(libnl_genl_3_la_LINK) -rpath $(libdir) $(libnl_genl_3_la_OBJECTS) $(libnl_genl_3_la_LIBADD) $(LIBS) idiag/$(am__dirstamp): @$(MKDIR_P) idiag @: > idiag/$(am__dirstamp) idiag/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) idiag/$(DEPDIR) @: > idiag/$(DEPDIR)/$(am__dirstamp) idiag/idiag_meminfo_obj.lo: idiag/$(am__dirstamp) \ idiag/$(DEPDIR)/$(am__dirstamp) idiag/idiag_vegasinfo_obj.lo: idiag/$(am__dirstamp) \ idiag/$(DEPDIR)/$(am__dirstamp) idiag/idiag_msg_obj.lo: idiag/$(am__dirstamp) \ idiag/$(DEPDIR)/$(am__dirstamp) idiag/idiag_req_obj.lo: idiag/$(am__dirstamp) \ idiag/$(DEPDIR)/$(am__dirstamp) idiag/idiag.lo: idiag/$(am__dirstamp) idiag/$(DEPDIR)/$(am__dirstamp) libnl-idiag-3.la: $(libnl_idiag_3_la_OBJECTS) $(libnl_idiag_3_la_DEPENDENCIES) $(EXTRA_libnl_idiag_3_la_DEPENDENCIES) $(AM_V_CCLD)$(libnl_idiag_3_la_LINK) -rpath $(libdir) $(libnl_idiag_3_la_OBJECTS) $(libnl_idiag_3_la_LIBADD) $(LIBS) netfilter/$(am__dirstamp): @$(MKDIR_P) netfilter @: > netfilter/$(am__dirstamp) netfilter/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) netfilter/$(DEPDIR) @: > netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/ct.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/ct_obj.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/log.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/log_msg.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/log_msg_obj.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/log_obj.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/netfilter.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/nfnl.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/queue.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/queue_msg.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/queue_msg_obj.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/queue_obj.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/exp.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) netfilter/exp_obj.lo: netfilter/$(am__dirstamp) \ netfilter/$(DEPDIR)/$(am__dirstamp) libnl-nf-3.la: $(libnl_nf_3_la_OBJECTS) $(libnl_nf_3_la_DEPENDENCIES) $(EXTRA_libnl_nf_3_la_DEPENDENCIES) $(AM_V_CCLD)$(libnl_nf_3_la_LINK) -rpath $(libdir) $(libnl_nf_3_la_OBJECTS) $(libnl_nf_3_la_LIBADD) $(LIBS) route/$(am__dirstamp): @$(MKDIR_P) route @: > route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) route/$(DEPDIR) @: > route/$(DEPDIR)/$(am__dirstamp) route/addr.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/class.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/cls.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/act.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/link.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/neigh.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/neightbl.lo: route/$(am__dirstamp) \ route/$(DEPDIR)/$(am__dirstamp) route/nexthop.lo: route/$(am__dirstamp) \ route/$(DEPDIR)/$(am__dirstamp) route/qdisc.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/route.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/route_obj.lo: route/$(am__dirstamp) \ route/$(DEPDIR)/$(am__dirstamp) route/route_utils.lo: route/$(am__dirstamp) \ route/$(DEPDIR)/$(am__dirstamp) route/rtnl.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/rule.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/tc.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/classid.lo: route/$(am__dirstamp) \ route/$(DEPDIR)/$(am__dirstamp) route/link/$(am__dirstamp): @$(MKDIR_P) route/link @: > route/link/$(am__dirstamp) route/link/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) route/link/$(DEPDIR) @: > route/link/$(DEPDIR)/$(am__dirstamp) route/link/sriov.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/cls/$(am__dirstamp): @$(MKDIR_P) route/cls @: > route/cls/$(am__dirstamp) route/cls/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) route/cls/$(DEPDIR) @: > route/cls/$(DEPDIR)/$(am__dirstamp) route/cls/fw.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) route/cls/police.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) route/cls/u32.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) route/cls/basic.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) route/cls/cgroup.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) route/act/$(am__dirstamp): @$(MKDIR_P) route/act @: > route/act/$(am__dirstamp) route/act/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) route/act/$(DEPDIR) @: > route/act/$(DEPDIR)/$(am__dirstamp) route/act/mirred.lo: route/act/$(am__dirstamp) \ route/act/$(DEPDIR)/$(am__dirstamp) route/act/skbedit.lo: route/act/$(am__dirstamp) \ route/act/$(DEPDIR)/$(am__dirstamp) route/act/gact.lo: route/act/$(am__dirstamp) \ route/act/$(DEPDIR)/$(am__dirstamp) route/cls/ematch.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) route/cls/ematch/$(am__dirstamp): @$(MKDIR_P) route/cls/ematch @: > route/cls/ematch/$(am__dirstamp) route/cls/ematch/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) route/cls/ematch/$(DEPDIR) @: > route/cls/ematch/$(DEPDIR)/$(am__dirstamp) route/cls/ematch/container.lo: route/cls/ematch/$(am__dirstamp) \ route/cls/ematch/$(DEPDIR)/$(am__dirstamp) route/cls/ematch/cmp.lo: route/cls/ematch/$(am__dirstamp) \ route/cls/ematch/$(DEPDIR)/$(am__dirstamp) route/cls/ematch/nbyte.lo: route/cls/ematch/$(am__dirstamp) \ route/cls/ematch/$(DEPDIR)/$(am__dirstamp) route/cls/ematch/text.lo: route/cls/ematch/$(am__dirstamp) \ route/cls/ematch/$(DEPDIR)/$(am__dirstamp) route/cls/ematch/meta.lo: route/cls/ematch/$(am__dirstamp) \ route/cls/ematch/$(DEPDIR)/$(am__dirstamp) route/link/api.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/vlan.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/dummy.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/bridge.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/inet6.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/inet.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/bonding.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/can.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/macvlan.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/vxlan.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/veth.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/ipip.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/ipgre.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/sit.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/ipvti.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/ip6tnl.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/ifb.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/ipvlan.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/vrf.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/macsec.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/link/ppp.lo: route/link/$(am__dirstamp) \ route/link/$(DEPDIR)/$(am__dirstamp) route/qdisc/$(am__dirstamp): @$(MKDIR_P) route/qdisc @: > route/qdisc/$(am__dirstamp) route/qdisc/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) route/qdisc/$(DEPDIR) @: > route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/blackhole.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/cbq.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/dsmark.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/fifo.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/htb.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/netem.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/prio.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/red.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/sfq.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/tbf.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/plug.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/ingress.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/fq_codel.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) route/qdisc/hfsc.lo: route/qdisc/$(am__dirstamp) \ route/qdisc/$(DEPDIR)/$(am__dirstamp) fib_lookup/$(am__dirstamp): @$(MKDIR_P) fib_lookup @: > fib_lookup/$(am__dirstamp) fib_lookup/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) fib_lookup/$(DEPDIR) @: > fib_lookup/$(DEPDIR)/$(am__dirstamp) fib_lookup/lookup.lo: fib_lookup/$(am__dirstamp) \ fib_lookup/$(DEPDIR)/$(am__dirstamp) fib_lookup/request.lo: fib_lookup/$(am__dirstamp) \ fib_lookup/$(DEPDIR)/$(am__dirstamp) route/pktloc.lo: route/$(am__dirstamp) route/$(DEPDIR)/$(am__dirstamp) route/pktloc_syntax.lo: route/$(am__dirstamp) \ route/$(DEPDIR)/$(am__dirstamp) route/pktloc_grammar.lo: route/$(am__dirstamp) \ route/$(DEPDIR)/$(am__dirstamp) route/cls/ematch_syntax.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) route/cls/ematch_grammar.lo: route/cls/$(am__dirstamp) \ route/cls/$(DEPDIR)/$(am__dirstamp) libnl-route-3.la: $(libnl_route_3_la_OBJECTS) $(libnl_route_3_la_DEPENDENCIES) $(EXTRA_libnl_route_3_la_DEPENDENCIES) $(AM_V_CCLD)$(libnl_route_3_la_LINK) -rpath $(libdir) $(libnl_route_3_la_OBJECTS) $(libnl_route_3_la_LIBADD) $(LIBS) xfrm/$(am__dirstamp): @$(MKDIR_P) xfrm @: > xfrm/$(am__dirstamp) xfrm/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) xfrm/$(DEPDIR) @: > xfrm/$(DEPDIR)/$(am__dirstamp) xfrm/ae.lo: xfrm/$(am__dirstamp) xfrm/$(DEPDIR)/$(am__dirstamp) xfrm/lifetime.lo: xfrm/$(am__dirstamp) xfrm/$(DEPDIR)/$(am__dirstamp) xfrm/sa.lo: xfrm/$(am__dirstamp) xfrm/$(DEPDIR)/$(am__dirstamp) xfrm/selector.lo: xfrm/$(am__dirstamp) xfrm/$(DEPDIR)/$(am__dirstamp) xfrm/sp.lo: xfrm/$(am__dirstamp) xfrm/$(DEPDIR)/$(am__dirstamp) xfrm/template.lo: xfrm/$(am__dirstamp) xfrm/$(DEPDIR)/$(am__dirstamp) libnl-xfrm-3.la: $(libnl_xfrm_3_la_OBJECTS) $(libnl_xfrm_3_la_DEPENDENCIES) $(EXTRA_libnl_xfrm_3_la_DEPENDENCIES) $(AM_V_CCLD)$(libnl_xfrm_3_la_LINK) -rpath $(libdir) $(libnl_xfrm_3_la_OBJECTS) $(libnl_xfrm_3_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f cli/cls/*.$(OBJEXT) -rm -f cli/cls/*.lo -rm -f cli/qdisc/*.$(OBJEXT) -rm -f cli/qdisc/*.lo -rm -f fib_lookup/*.$(OBJEXT) -rm -f fib_lookup/*.lo -rm -f genl/*.$(OBJEXT) -rm -f genl/*.lo -rm -f idiag/*.$(OBJEXT) -rm -f idiag/*.lo -rm -f netfilter/*.$(OBJEXT) -rm -f netfilter/*.lo -rm -f route/*.$(OBJEXT) -rm -f route/*.lo -rm -f route/act/*.$(OBJEXT) -rm -f route/act/*.lo -rm -f route/cls/*.$(OBJEXT) -rm -f route/cls/*.lo -rm -f route/cls/ematch/*.$(OBJEXT) -rm -f route/cls/ematch/*.lo -rm -f route/link/*.$(OBJEXT) -rm -f route/link/*.lo -rm -f route/qdisc/*.$(OBJEXT) -rm -f route/qdisc/*.lo -rm -f xfrm/*.$(OBJEXT) -rm -f xfrm/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_mngr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_mngt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/handlers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/cls/$(DEPDIR)/basic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/cls/$(DEPDIR)/cgroup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/bfifo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/blackhole.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/fq_codel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/hfsc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/htb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/ingress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/pfifo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cli/qdisc/$(DEPDIR)/plug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@fib_lookup/$(DEPDIR)/lookup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@fib_lookup/$(DEPDIR)/request.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@genl/$(DEPDIR)/ctrl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@genl/$(DEPDIR)/family.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@genl/$(DEPDIR)/genl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@genl/$(DEPDIR)/mngt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@idiag/$(DEPDIR)/idiag.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@idiag/$(DEPDIR)/idiag_meminfo_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@idiag/$(DEPDIR)/idiag_msg_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@idiag/$(DEPDIR)/idiag_req_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@idiag/$(DEPDIR)/idiag_vegasinfo_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/ct.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/ct_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/exp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/exp_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/log.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/log_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/log_msg_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/log_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/netfilter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/nfnl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/queue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/queue_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/queue_msg_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@netfilter/$(DEPDIR)/queue_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/act.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/addr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/class.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/classid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/cls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/link.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/neigh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/neightbl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/nexthop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/pktloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/pktloc_grammar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/pktloc_syntax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/qdisc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/route.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/route_obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/route_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/rtnl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/rule.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/$(DEPDIR)/tc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/act/$(DEPDIR)/gact.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/act/$(DEPDIR)/mirred.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/act/$(DEPDIR)/skbedit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/basic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/cgroup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/ematch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/ematch_grammar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/ematch_syntax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/fw.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/police.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/$(DEPDIR)/u32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/ematch/$(DEPDIR)/cmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/ematch/$(DEPDIR)/container.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/ematch/$(DEPDIR)/meta.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/ematch/$(DEPDIR)/nbyte.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/cls/ematch/$(DEPDIR)/text.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/bonding.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/bridge.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/can.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/dummy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/ifb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/inet.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/inet6.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/ip6tnl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/ipgre.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/ipip.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/ipvlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/ipvti.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/macsec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/macvlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/ppp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/sit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/sriov.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/veth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/vlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/vrf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/link/$(DEPDIR)/vxlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/blackhole.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/cbq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/dsmark.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/fifo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/fq_codel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/hfsc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/htb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/ingress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/netem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/plug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/prio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/red.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/sfq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@route/qdisc/$(DEPDIR)/tbf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@xfrm/$(DEPDIR)/ae.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@xfrm/$(DEPDIR)/lifetime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@xfrm/$(DEPDIR)/sa.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@xfrm/$(DEPDIR)/selector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@xfrm/$(DEPDIR)/sp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@xfrm/$(DEPDIR)/template.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf cli/cls/.libs cli/cls/_libs -rm -rf cli/qdisc/.libs cli/qdisc/_libs -rm -rf fib_lookup/.libs fib_lookup/_libs -rm -rf genl/.libs genl/_libs -rm -rf idiag/.libs idiag/_libs -rm -rf netfilter/.libs netfilter/_libs -rm -rf route/.libs route/_libs -rm -rf route/act/.libs route/act/_libs -rm -rf route/cls/.libs route/cls/_libs -rm -rf route/cls/ematch/.libs route/cls/ematch/_libs -rm -rf route/link/.libs route/link/_libs -rm -rf route/qdisc/.libs route/qdisc/_libs -rm -rf xfrm/.libs xfrm/_libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) defs.h installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f cli/cls/$(DEPDIR)/$(am__dirstamp) -rm -f cli/cls/$(am__dirstamp) -rm -f cli/qdisc/$(DEPDIR)/$(am__dirstamp) -rm -f cli/qdisc/$(am__dirstamp) -rm -f fib_lookup/$(DEPDIR)/$(am__dirstamp) -rm -f fib_lookup/$(am__dirstamp) -rm -f genl/$(DEPDIR)/$(am__dirstamp) -rm -f genl/$(am__dirstamp) -rm -f idiag/$(DEPDIR)/$(am__dirstamp) -rm -f idiag/$(am__dirstamp) -rm -f netfilter/$(DEPDIR)/$(am__dirstamp) -rm -f netfilter/$(am__dirstamp) -rm -f route/$(DEPDIR)/$(am__dirstamp) -rm -f route/$(am__dirstamp) -rm -f route/act/$(DEPDIR)/$(am__dirstamp) -rm -f route/act/$(am__dirstamp) -rm -f route/cls/$(DEPDIR)/$(am__dirstamp) -rm -f route/cls/$(am__dirstamp) -rm -f route/cls/ematch/$(DEPDIR)/$(am__dirstamp) -rm -f route/cls/ematch/$(am__dirstamp) -rm -f route/link/$(DEPDIR)/$(am__dirstamp) -rm -f route/link/$(am__dirstamp) -rm -f route/qdisc/$(DEPDIR)/$(am__dirstamp) -rm -f route/qdisc/$(am__dirstamp) -rm -f xfrm/$(DEPDIR)/$(am__dirstamp) -rm -f xfrm/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-nobase_pkglibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) cli/cls/$(DEPDIR) cli/qdisc/$(DEPDIR) fib_lookup/$(DEPDIR) genl/$(DEPDIR) idiag/$(DEPDIR) netfilter/$(DEPDIR) route/$(DEPDIR) route/act/$(DEPDIR) route/cls/$(DEPDIR) route/cls/ematch/$(DEPDIR) route/link/$(DEPDIR) route/qdisc/$(DEPDIR) xfrm/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES \ install-nobase_pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) cli/cls/$(DEPDIR) cli/qdisc/$(DEPDIR) fib_lookup/$(DEPDIR) genl/$(DEPDIR) idiag/$(DEPDIR) netfilter/$(DEPDIR) route/$(DEPDIR) route/act/$(DEPDIR) route/cls/$(DEPDIR) route/cls/ematch/$(DEPDIR) route/link/$(DEPDIR) route/qdisc/$(DEPDIR) xfrm/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES \ uninstall-nobase_pkglibLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool \ clean-nobase_pkglibLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-hdr \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man \ install-nobase_pkglibLTLIBRARIES install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-nobase_pkglibLTLIBRARIES .PRECIOUS: Makefile # Hack to avoid using ylwrap. It does not function correctly in combination # with --header-file= route/pktloc_grammar.c: route/pktloc_grammar.l $(AM_V_GEN) $(MKDIR_P) route; $(FLEX) --header-file=route/pktloc_grammar.h $(LFLAGS) -o $@ $^ route/pktloc_syntax.c: route/pktloc_syntax.y $(AM_V_GEN) $(MKDIR_P) route; $(YACC) -d $(YFLAGS) -o $@ $^ route/cls/ematch_grammar.c: route/cls/ematch_grammar.l $(AM_V_GEN) $(MKDIR_P) route/cls; $(FLEX) --header-file=route/cls/ematch_grammar.h $(LFLAGS) -o $@ $^ route/cls/ematch_syntax.c: route/cls/ematch_syntax.y $(AM_V_GEN) $(MKDIR_P) route/cls; $(YACC) -d $(YFLAGS) -o $@ $^ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnl-3.2.29/lib/hashtable.c0000644000175000017500000001035113023014600012462 00000000000000/* * netlink/hashtable.c Netlink hashtable Utilities * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Cumulus Networks, Inc */ #include #include #include #include #include /** * @ingroup core_types * @defgroup hashtable Hashtable * @{ */ /** * Allocate hashtable * @arg size Size of hashtable in number of elements * * @return Allocated hashtable or NULL. */ nl_hash_table_t *nl_hash_table_alloc(int size) { nl_hash_table_t *ht; ht = calloc(1, sizeof (*ht)); if (!ht) goto errout; ht->nodes = calloc(size, sizeof (*ht->nodes)); if (!ht->nodes) { free(ht); goto errout; } ht->size = size; return ht; errout: return NULL; } /** * Free hashtable including all nodes * @arg ht Hashtable * * @note Reference counter of all objects in the hashtable will be decremented. */ void nl_hash_table_free(nl_hash_table_t *ht) { int i; for(i = 0; i < ht->size; i++) { nl_hash_node_t *node = ht->nodes[i]; nl_hash_node_t *saved_node; while (node) { saved_node = node; node = node->next; nl_object_put(saved_node->obj); free(saved_node); } } free(ht->nodes); free(ht); } /** * Lookup identical object in hashtable * @arg ht Hashtable * @arg obj Object to lookup * * Generates hashkey for `obj` and traverses the corresponding chain calling * `nl_object_identical()` on each trying to find a match. * * @return Pointer to object if match was found or NULL. */ struct nl_object* nl_hash_table_lookup(nl_hash_table_t *ht, struct nl_object *obj) { nl_hash_node_t *node; uint32_t key_hash; nl_object_keygen(obj, &key_hash, ht->size); node = ht->nodes[key_hash]; while (node) { if (nl_object_identical(node->obj, obj)) return node->obj; node = node->next; } return NULL; } /** * Add object to hashtable * @arg ht Hashtable * @arg obj Object to add * * Adds `obj` to the hashtable. Object type must support hashing, otherwise all * objects will be added to the chain `0`. * * @note The reference counter of the object is incremented. * * @return 0 on success or a negative error code * @retval -NLE_EXIST Identical object already present in hashtable */ int nl_hash_table_add(nl_hash_table_t *ht, struct nl_object *obj) { nl_hash_node_t *node; uint32_t key_hash; nl_object_keygen(obj, &key_hash, ht->size); node = ht->nodes[key_hash]; while (node) { if (nl_object_identical(node->obj, obj)) { NL_DBG(2, "Warning: Add to hashtable found duplicate...\n"); return -NLE_EXIST; } node = node->next; } NL_DBG (5, "adding cache entry of obj %p in table %p, with hash 0x%x\n", obj, ht, key_hash); node = malloc(sizeof(nl_hash_node_t)); if (!node) return -NLE_NOMEM; nl_object_get(obj); node->obj = obj; node->key = key_hash; node->key_size = sizeof(uint32_t); node->next = ht->nodes[key_hash]; ht->nodes[key_hash] = node; return 0; } /** * Remove object from hashtable * @arg ht Hashtable * @arg obj Object to remove * * Remove `obj` from hashtable if it exists. * * @note Reference counter of object will be decremented. * * @return 0 on success or a negative error code. * @retval -NLE_OBJ_NOTFOUND Object not present in hashtable. */ int nl_hash_table_del(nl_hash_table_t *ht, struct nl_object *obj) { nl_hash_node_t *node, *prev; uint32_t key_hash; nl_object_keygen(obj, &key_hash, ht->size); prev = node = ht->nodes[key_hash]; while (node) { if (nl_object_identical(node->obj, obj)) { nl_object_put(obj); NL_DBG (5, "deleting cache entry of obj %p in table %p, with" " hash 0x%x\n", obj, ht, key_hash); if (node == ht->nodes[key_hash]) ht->nodes[key_hash] = node->next; else prev->next = node->next; free(node); return 0; } prev = node; node = node->next; } return -NLE_OBJ_NOTFOUND; } uint32_t nl_hash(void *k, size_t length, uint32_t initval) { return(__nl_hash(k, length, initval)); } /** @} */ libnl-3.2.29/lib/route/0000755000175000017500000000000013031473756011625 500000000000000libnl-3.2.29/lib/route/neigh.c0000644000175000017500000006624713023014600012776 00000000000000/* * lib/route/neigh.c Neighbours * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup rtnl * @defgroup neigh Neighbours * @brief * * The neighbour table establishes bindings between protocol addresses and * link layer addresses for hosts sharing the same physical link. This * module allows you to access and manipulate the content of these tables. * * @par Neighbour States * @code * NUD_INCOMPLETE * NUD_REACHABLE * NUD_STALE * NUD_DELAY * NUD_PROBE * NUD_FAILED * NUD_NOARP * NUD_PERMANENT * @endcode * * @par Neighbour Flags * @code * NTF_USE * NTF_PROXY * NTF_ROUTER * NTF_SELF * @endcode * * @par Neighbour Identification * A neighbour is uniquely identified by the attributes listed below, whenever * you refer to an existing neighbour all of the attributes must be set. * Neighbours from caches automatically have all required attributes set. * - interface index (rtnl_neigh_set_ifindex()) * - destination address (rtnl_neigh_set_dst()) * * @par Changeable Attributes * \anchor neigh_changeable * - state (rtnl_neigh_set_state()) * - link layer address (rtnl_neigh_set_lladdr()) * * @par Required Caches for Dumping * In order to dump neighbour attributes you must provide the following * caches via nl_cache_provide() * - link cache holding all links * * @par TODO * - Document proxy settings * - Document states and their influence * * @par 1) Retrieving information about configured neighbours * @code * // The first step is to retrieve a list of all available neighbour within * // the kernel and put them into a cache. * struct nl_cache *cache = rtnl_neigh_alloc_cache(sk); * * // Neighbours can then be looked up by the interface and destination * // address: * struct rtnl_neigh *neigh = rtnl_neigh_get(cache, ifindex, dst_addr); * * // After successful usage, the object must be given back to the cache * rtnl_neigh_put(neigh); * @endcode * * @par 2) Adding new neighbours * @code * // Allocate an empty neighbour handle to be filled out with the attributes * // of the new neighbour. * struct rtnl_neigh *neigh = rtnl_neigh_alloc(); * * // Fill out the attributes of the new neighbour * rtnl_neigh_set_ifindex(neigh, ifindex); * rtnl_neigh_set_dst(neigh, dst_addr); * rtnl_neigh_set_state(neigh, rtnl_neigh_str2state("permanent")); * * // Build the netlink message and send it to the kernel, the operation will * // block until the operation has been completed. Alternatively the required * // netlink message can be built using rtnl_neigh_build_add_request() * // to be sent out using nl_send_auto_complete(). * rtnl_neigh_add(sk, neigh, NLM_F_CREATE); * * // Free the memory * rtnl_neigh_put(neigh); * @endcode * * @par 3) Deleting an existing neighbour * @code * // Allocate an empty neighbour object to be filled out with the attributes * // matching the neighbour to be deleted. Alternatively a fully equipped * // neighbour object out of a cache can be used instead. * struct rtnl_neigh *neigh = rtnl_neigh_alloc(); * * // Neighbours are uniquely identified by their interface index and * // destination address, you may fill out other attributes but they * // will have no influence. * rtnl_neigh_set_ifindex(neigh, ifindex); * rtnl_neigh_set_dst(neigh, dst_addr); * * // Build the netlink message and send it to the kernel, the operation will * // block until the operation has been completed. Alternatively the required * // netlink message can be built using rtnl_neigh_build_delete_request() * // to be sent out using nl_send_auto_complete(). * rtnl_neigh_delete(sk, neigh, 0); * * // Free the memory * rtnl_neigh_put(neigh); * @endcode * * @par 4) Changing neighbour attributes * @code * // Allocate an empty neighbour object to be filled out with the attributes * // matching the neighbour to be changed and the new parameters. Alternatively * // a fully equipped modified neighbour object out of a cache can be used. * struct rtnl_neigh *neigh = rtnl_neigh_alloc(); * * // Identify the neighbour to be changed by its interface index and * // destination address * rtnl_neigh_set_ifindex(neigh, ifindex); * rtnl_neigh_set_dst(neigh, dst_addr); * * // The link layer address may be modified, if so it is wise to change * // its state to "permanent" in order to avoid having it overwritten. * rtnl_neigh_set_lladdr(neigh, lladdr); * * // Secondly the state can be modified allowing normal neighbours to be * // converted into permanent entries or to manually confirm a neighbour. * rtnl_neigh_set_state(neigh, state); * * // Build the netlink message and send it to the kernel, the operation will * // block until the operation has been completed. Alternatively the required * // netlink message can be built using rtnl_neigh_build_change_request() * // to be sent out using nl_send_auto_complete(). * rtnl_neigh_add(sk, neigh, NLM_F_REPLACE); * * // Free the memory * rtnl_neigh_put(neigh); * @endcode * @{ */ #include #include #include #include #include #include #include #include /** @cond SKIP */ #define NEIGH_ATTR_FLAGS 0x01 #define NEIGH_ATTR_STATE 0x02 #define NEIGH_ATTR_LLADDR 0x04 #define NEIGH_ATTR_DST 0x08 #define NEIGH_ATTR_CACHEINFO 0x10 #define NEIGH_ATTR_IFINDEX 0x20 #define NEIGH_ATTR_FAMILY 0x40 #define NEIGH_ATTR_TYPE 0x80 #define NEIGH_ATTR_PROBES 0x100 #define NEIGH_ATTR_MASTER 0x200 #define NEIGH_ATTR_VLAN 0x400 static struct nl_cache_ops rtnl_neigh_ops; static struct nl_object_ops neigh_obj_ops; /** @endcond */ static void neigh_free_data(struct nl_object *c) { struct rtnl_neigh *neigh = nl_object_priv(c); if (!neigh) return; nl_addr_put(neigh->n_lladdr); nl_addr_put(neigh->n_dst); } static int neigh_clone(struct nl_object *_dst, struct nl_object *_src) { struct rtnl_neigh *dst = nl_object_priv(_dst); struct rtnl_neigh *src = nl_object_priv(_src); if (src->n_lladdr) if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr))) return -NLE_NOMEM; if (src->n_dst) if (!(dst->n_dst = nl_addr_clone(src->n_dst))) return -NLE_NOMEM; return 0; } static void neigh_keygen(struct nl_object *obj, uint32_t *hashkey, uint32_t table_sz) { struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj; unsigned int nkey_sz; struct nl_addr *addr = NULL; struct neigh_hash_key { uint32_t n_family; uint32_t n_ifindex; uint16_t n_vlan; char n_addr[0]; } __attribute__((packed)) *nkey; #ifdef NL_DEBUG char buf[INET6_ADDRSTRLEN+5]; #endif if (neigh->n_family == AF_BRIDGE) { if (neigh->n_lladdr) addr = neigh->n_lladdr; } else if (neigh->n_dst) { addr = neigh->n_dst; } nkey_sz = sizeof(*nkey); if (addr) nkey_sz += nl_addr_get_len(addr); nkey = calloc(1, nkey_sz); if (!nkey) { *hashkey = 0; return; } nkey->n_family = neigh->n_family; if (neigh->n_family == AF_BRIDGE) { nkey->n_vlan = neigh->n_vlan; if (neigh->n_flags & NTF_SELF) nkey->n_ifindex = neigh->n_ifindex; else nkey->n_ifindex = neigh->n_master; } else nkey->n_ifindex = neigh->n_ifindex; if (addr) memcpy(nkey->n_addr, nl_addr_get_binary_addr(addr), nl_addr_get_len(addr)); *hashkey = nl_hash(nkey, nkey_sz, 0) % table_sz; NL_DBG(5, "neigh %p key (fam %d dev %d addr %s) keysz %d hash 0x%x\n", neigh, nkey->n_family, nkey->n_ifindex, nl_addr2str(addr, buf, sizeof(buf)), nkey_sz, *hashkey); free(nkey); return; } static uint64_t neigh_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct rtnl_neigh *a = (struct rtnl_neigh *) _a; struct rtnl_neigh *b = (struct rtnl_neigh *) _b; uint64_t diff = 0; #define NEIGH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGH_ATTR_##ATTR, a, b, EXPR) diff |= NEIGH_DIFF(IFINDEX, a->n_ifindex != b->n_ifindex); diff |= NEIGH_DIFF(FAMILY, a->n_family != b->n_family); diff |= NEIGH_DIFF(TYPE, a->n_type != b->n_type); diff |= NEIGH_DIFF(LLADDR, nl_addr_cmp(a->n_lladdr, b->n_lladdr)); diff |= NEIGH_DIFF(DST, nl_addr_cmp(a->n_dst, b->n_dst)); diff |= NEIGH_DIFF(MASTER, a->n_master != b->n_master); diff |= NEIGH_DIFF(VLAN, a->n_vlan != b->n_vlan); if (flags & LOOSE_COMPARISON) { diff |= NEIGH_DIFF(STATE, (a->n_state ^ b->n_state) & b->n_state_mask); diff |= NEIGH_DIFF(FLAGS, (a->n_flags ^ b->n_flags) & b->n_flag_mask); } else { diff |= NEIGH_DIFF(STATE, a->n_state != b->n_state); diff |= NEIGH_DIFF(FLAGS, a->n_flags != b->n_flags); } #undef NEIGH_DIFF return diff; } static const struct trans_tbl neigh_attrs[] = { __ADD(NEIGH_ATTR_FLAGS, flags), __ADD(NEIGH_ATTR_STATE, state), __ADD(NEIGH_ATTR_LLADDR, lladdr), __ADD(NEIGH_ATTR_DST, dst), __ADD(NEIGH_ATTR_CACHEINFO, cacheinfo), __ADD(NEIGH_ATTR_IFINDEX, ifindex), __ADD(NEIGH_ATTR_FAMILY, family), __ADD(NEIGH_ATTR_TYPE, type), __ADD(NEIGH_ATTR_PROBES, probes), __ADD(NEIGH_ATTR_MASTER, master), __ADD(NEIGH_ATTR_VLAN, vlan), }; static char *neigh_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, neigh_attrs, ARRAY_SIZE(neigh_attrs)); } static uint32_t neigh_id_attrs_get(struct nl_object *obj) { struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj; if (neigh->n_family == AF_BRIDGE) { if (neigh->n_flags & NTF_SELF) return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX | NEIGH_ATTR_VLAN); else return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER | NEIGH_ATTR_VLAN); } else return (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY); } static struct nla_policy neigh_policy[NDA_MAX+1] = { [NDA_CACHEINFO] = { .minlen = sizeof(struct nda_cacheinfo) }, [NDA_PROBES] = { .type = NLA_U32 }, }; static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct rtnl_neigh *neigh; int err; if ((err = rtnl_neigh_parse(n, &neigh)) < 0) return err; err = pp->pp_cb((struct nl_object *) neigh, pp); rtnl_neigh_put(neigh); return err; } int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result) { struct rtnl_neigh *neigh; struct nlattr *tb[NDA_MAX + 1]; struct ndmsg *nm; int err; neigh = rtnl_neigh_alloc(); if (!neigh) { err = -NLE_NOMEM; goto errout; } neigh->ce_msgtype = n->nlmsg_type; nm = nlmsg_data(n); err = nlmsg_parse(n, sizeof(*nm), tb, NDA_MAX, neigh_policy); if (err < 0) goto errout; neigh->n_family = nm->ndm_family; neigh->n_ifindex = nm->ndm_ifindex; neigh->n_state = nm->ndm_state; neigh->n_flags = nm->ndm_flags; neigh->n_type = nm->ndm_type; neigh->ce_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX | NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS | NEIGH_ATTR_TYPE); if (tb[NDA_LLADDR]) { neigh->n_lladdr = nl_addr_alloc_attr(tb[NDA_LLADDR], AF_UNSPEC); if (!neigh->n_lladdr) { err = -NLE_NOMEM; goto errout; } nl_addr_set_family(neigh->n_lladdr, nl_addr_guess_family(neigh->n_lladdr)); neigh->ce_mask |= NEIGH_ATTR_LLADDR; } if (tb[NDA_DST]) { neigh->n_dst = nl_addr_alloc_attr(tb[NDA_DST], neigh->n_family); if (!neigh->n_dst) { err = -NLE_NOMEM; goto errout; } neigh->ce_mask |= NEIGH_ATTR_DST; } if (tb[NDA_CACHEINFO]) { struct nda_cacheinfo *ci = nla_data(tb[NDA_CACHEINFO]); neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed; neigh->n_cacheinfo.nci_used = ci->ndm_used; neigh->n_cacheinfo.nci_updated = ci->ndm_updated; neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt; neigh->ce_mask |= NEIGH_ATTR_CACHEINFO; } if (tb[NDA_PROBES]) { neigh->n_probes = nla_get_u32(tb[NDA_PROBES]); neigh->ce_mask |= NEIGH_ATTR_PROBES; } if (tb[NDA_VLAN]) { neigh->n_vlan = nla_get_u16(tb[NDA_VLAN]); neigh->ce_mask |= NEIGH_ATTR_VLAN; } /* * Get the bridge index for AF_BRIDGE family entries */ if (neigh->n_family == AF_BRIDGE) { struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link"); if (lcache ) { struct rtnl_link *link = rtnl_link_get(lcache, neigh->n_ifindex); if (link) { neigh->n_master = link->l_master; rtnl_link_put(link); neigh->ce_mask |= NEIGH_ATTR_MASTER; } nl_cache_put(lcache); } } *result = neigh; return 0; errout: rtnl_neigh_put(neigh); return err; } static int neigh_request_update(struct nl_cache *c, struct nl_sock *h) { int family = c->c_iarg1; return nl_rtgen_request(h, RTM_GETNEIGH, family, NLM_F_DUMP); } static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p) { char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5]; struct rtnl_neigh *n = (struct rtnl_neigh *) a; struct nl_cache *link_cache; char state[128], flags[64]; link_cache = nl_cache_mngt_require_safe("route/link"); if (n->n_family != AF_BRIDGE) nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst))); if (link_cache) nl_dump(p, "dev %s ", rtnl_link_i2name(link_cache, n->n_ifindex, state, sizeof(state))); else nl_dump(p, "dev %d ", n->n_ifindex); if (n->ce_mask & NEIGH_ATTR_LLADDR) nl_dump(p, "lladdr %s ", nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr))); if (n->ce_mask & NEIGH_ATTR_VLAN) nl_dump(p, "vlan %d ", n->n_vlan); rtnl_neigh_state2str(n->n_state, state, sizeof(state)); rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags)); if (state[0]) nl_dump(p, "<%s", state); if (flags[0]) nl_dump(p, "%s%s", state[0] ? "," : "<", flags); if (state[0] || flags[0]) nl_dump(p, ">"); nl_dump(p, "\n"); if (link_cache) nl_cache_put(link_cache); } static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p) { char rtn_type[32]; struct rtnl_neigh *n = (struct rtnl_neigh *) a; int hz = nl_get_user_hz(); neigh_dump_line(a, p); nl_dump_line(p, " refcnt %u type %s confirmed %u used " "%u updated %u\n", n->n_cacheinfo.nci_refcnt, nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)), n->n_cacheinfo.nci_confirmed/hz, n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz); } static void neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p) { neigh_dump_details(a, p); } /** * @name Neighbour Object Allocation/Freeage * @{ */ struct rtnl_neigh *rtnl_neigh_alloc(void) { return (struct rtnl_neigh *) nl_object_alloc(&neigh_obj_ops); } void rtnl_neigh_put(struct rtnl_neigh *neigh) { nl_object_put((struct nl_object *) neigh); } /** @} */ /** * @name Neighbour Cache Managament * @{ */ /** * Build a neighbour cache including all neighbours currently configured in the kernel. * @arg sock Netlink socket. * @arg result Pointer to store resulting cache. * * Allocates a new neighbour cache, initializes it properly and updates it * to include all neighbours currently configured in the kernel. * * @return 0 on success or a negative error code. */ int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result) { return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result); } /** * Build a neighbour cache including all neighbours currently configured in the kernel. * @arg sock Netlink socket. * @arg result Pointer to store resulting cache. * @arg flags Flags to apply to cache before filling * * Allocates a new neighbour cache, initializes it properly and updates it * to include all neighbours currently configured in the kernel. * * @return 0 on success or a negative error code. */ int rtnl_neigh_alloc_cache_flags(struct nl_sock *sock, struct nl_cache **result, unsigned int flags) { struct nl_cache * cache; int err; cache = nl_cache_alloc(&rtnl_neigh_ops); if (!cache) return -NLE_NOMEM; nl_cache_set_flags(cache, flags); if (sock && (err = nl_cache_refill(sock, cache)) < 0) { nl_cache_free(cache); return err; } *result = cache; return 0; } /** * Look up a neighbour by interface index and destination address * @arg cache neighbour cache * @arg ifindex interface index the neighbour is on * @arg dst destination address of the neighbour * * @return neighbour handle or NULL if no match was found. */ struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex, struct nl_addr *dst) { struct rtnl_neigh *neigh; nl_list_for_each_entry(neigh, &cache->c_items, ce_list) { if (neigh->n_ifindex == ifindex && !nl_addr_cmp(neigh->n_dst, dst)) { nl_object_get((struct nl_object *) neigh); return neigh; } } return NULL; } /** * Look up a neighbour by interface index, link layer address and vlan id * @arg cache neighbour cache * @arg ifindex interface index the neighbour is on * @arg lladdr link layer address of the neighbour * @arg vlan vlan id of the neighbour * * @return neighbour handle or NULL if no match was found. */ struct rtnl_neigh * rtnl_neigh_get_by_vlan(struct nl_cache *cache, int ifindex, struct nl_addr *lladdr, int vlan) { struct rtnl_neigh *neigh; nl_list_for_each_entry(neigh, &cache->c_items, ce_list) { if (neigh->n_ifindex == ifindex && neigh->n_vlan == vlan && neigh->n_lladdr && !nl_addr_cmp(neigh->n_lladdr, lladdr)) { nl_object_get((struct nl_object *) neigh); return neigh; } } return NULL; } /** @} */ /** * @name Neighbour Addition * @{ */ static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; struct ndmsg nhdr = { .ndm_ifindex = tmpl->n_ifindex, .ndm_state = NUD_PERMANENT, }; if (tmpl->n_family != AF_BRIDGE) { if (!(tmpl->ce_mask & NEIGH_ATTR_DST)) return -NLE_MISSING_ATTR; nhdr.ndm_family = nl_addr_get_family(tmpl->n_dst); } else nhdr.ndm_family = AF_BRIDGE; if (tmpl->ce_mask & NEIGH_ATTR_FLAGS) nhdr.ndm_flags = tmpl->n_flags; if (tmpl->ce_mask & NEIGH_ATTR_STATE) nhdr.ndm_state = tmpl->n_state; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tmpl->n_family != AF_BRIDGE) NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst); if (tmpl->ce_mask & NEIGH_ATTR_LLADDR) NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr); if (tmpl->ce_mask & NEIGH_ATTR_VLAN) NLA_PUT_U16(msg, NDA_VLAN, tmpl->n_vlan); *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * Build netlink request message to add a new neighbour * @arg tmpl template with data of new neighbour * @arg flags additional netlink message flags * @arg result Pointer to store resulting message. * * Builds a new netlink message requesting a addition of a new * neighbour. The netlink message header isn't fully equipped with * all relevant fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. \a tmpl must contain the attributes of the new * neighbour set via \c rtnl_neigh_set_* functions. * * The following attributes must be set in the template: * - Interface index (rtnl_neigh_set_ifindex()) * - State (rtnl_neigh_set_state()) * - Destination address (rtnl_neigh_set_dst()) * - Link layer address (rtnl_neigh_set_lladdr()) * * @return 0 on success or a negative error code. */ int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags, struct nl_msg **result) { return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result); } /** * Add a new neighbour * @arg sk Netlink socket. * @arg tmpl template with requested changes * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_neigh_build_add_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * The following attributes must be set in the template: * - Interface index (rtnl_neigh_set_ifindex()) * - State (rtnl_neigh_set_state()) * - Destination address (rtnl_neigh_set_dst()) * - Link layer address (rtnl_neigh_set_lladdr()) * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags) { int err; struct nl_msg *msg; if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ /** * @name Neighbour Deletion * @{ */ /** * Build a netlink request message to delete a neighbour * @arg neigh neighbour to delete * @arg flags additional netlink message flags * @arg result Pointer to store resulting message. * * Builds a new netlink message requesting a deletion of a neighbour. * The netlink message header isn't fully equipped with all relevant * fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. \a neigh must point to an existing * neighbour. * * @return 0 on success or a negative error code. */ int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags, struct nl_msg **result) { return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result); } /** * Delete a neighbour * @arg sk Netlink socket. * @arg neigh neighbour to delete * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_neigh_build_delete_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ /** * @name Neighbour States Translations * @{ */ static const struct trans_tbl neigh_states[] = { __ADD(NUD_INCOMPLETE, incomplete), __ADD(NUD_REACHABLE, reachable), __ADD(NUD_STALE, stale), __ADD(NUD_DELAY, delay), __ADD(NUD_PROBE, probe), __ADD(NUD_FAILED, failed), __ADD(NUD_NOARP, noarp), __ADD(NUD_PERMANENT, permanent), /* Accept this value for backward compatibility. Originally * there was a typo in the string value. This was fixed later, * but we still want to successfully parse "norarp". */ __ADD(NUD_NOARP, norarp), }; char * rtnl_neigh_state2str(int state, char *buf, size_t len) { return __flags2str(state, buf, len, neigh_states, ARRAY_SIZE(neigh_states) - 1); } int rtnl_neigh_str2state(const char *name) { return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states)); } /** @} */ /** * @name Neighbour Flags Translations * @{ */ static const struct trans_tbl neigh_flags[] = { __ADD(NTF_USE, use), __ADD(NTF_PROXY, proxy), __ADD(NTF_ROUTER, router), __ADD(NTF_SELF, self), }; char * rtnl_neigh_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, neigh_flags, ARRAY_SIZE(neigh_flags)); } int rtnl_neigh_str2flag(const char *name) { return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags)); } /** @} */ /** * @name Attributes * @{ */ void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state) { neigh->n_state_mask |= state; neigh->n_state |= state; neigh->ce_mask |= NEIGH_ATTR_STATE; } int rtnl_neigh_get_state(struct rtnl_neigh *neigh) { if (neigh->ce_mask & NEIGH_ATTR_STATE) return neigh->n_state; else return -1; } void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state) { neigh->n_state_mask |= state; neigh->n_state &= ~state; neigh->ce_mask |= NEIGH_ATTR_STATE; } void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags) { neigh->n_flag_mask |= flags; neigh->n_flags |= flags; neigh->ce_mask |= NEIGH_ATTR_FLAGS; } unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh) { return neigh->n_flags; } void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags) { neigh->n_flag_mask |= flags; neigh->n_flags &= ~flags; neigh->ce_mask |= NEIGH_ATTR_FLAGS; } void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex) { neigh->n_ifindex = ifindex; neigh->ce_mask |= NEIGH_ATTR_IFINDEX; } int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh) { return neigh->n_ifindex; } static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos, struct nl_addr *new, int flag, int nocheck) { if (!nocheck) { if (neigh->ce_mask & NEIGH_ATTR_FAMILY) { if (new->a_family != neigh->n_family) return -NLE_AF_MISMATCH; } else { neigh->n_family = new->a_family; neigh->ce_mask |= NEIGH_ATTR_FAMILY; } } if (*pos) nl_addr_put(*pos); nl_addr_get(new); *pos = new; neigh->ce_mask |= flag; return 0; } void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr) { __assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1); } struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh) { if (neigh->ce_mask & NEIGH_ATTR_LLADDR) return neigh->n_lladdr; else return NULL; } int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr) { return __assign_addr(neigh, &neigh->n_dst, addr, NEIGH_ATTR_DST, 0); } struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh) { if (neigh->ce_mask & NEIGH_ATTR_DST) return neigh->n_dst; else return NULL; } void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family) { neigh->n_family = family; neigh->ce_mask |= NEIGH_ATTR_FAMILY; } int rtnl_neigh_get_family(struct rtnl_neigh *neigh) { return neigh->n_family; } void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type) { neigh->n_type = type; neigh->ce_mask = NEIGH_ATTR_TYPE; } int rtnl_neigh_get_type(struct rtnl_neigh *neigh) { if (neigh->ce_mask & NEIGH_ATTR_TYPE) return neigh->n_type; else return -1; } void rtnl_neigh_set_vlan(struct rtnl_neigh *neigh, int vlan) { neigh->n_vlan = vlan; neigh->ce_mask |= NEIGH_ATTR_VLAN; } int rtnl_neigh_get_vlan(struct rtnl_neigh *neigh) { if (neigh->ce_mask & NEIGH_ATTR_VLAN) return neigh->n_vlan; else return -1; } /** @} */ static struct nl_object_ops neigh_obj_ops = { .oo_name = "route/neigh", .oo_size = sizeof(struct rtnl_neigh), .oo_free_data = neigh_free_data, .oo_clone = neigh_clone, .oo_dump = { [NL_DUMP_LINE] = neigh_dump_line, [NL_DUMP_DETAILS] = neigh_dump_details, [NL_DUMP_STATS] = neigh_dump_stats, }, .oo_compare = neigh_compare, .oo_keygen = neigh_keygen, .oo_attrs2str = neigh_attrs2str, .oo_id_attrs = (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY), .oo_id_attrs_get = neigh_id_attrs_get }; static struct nl_af_group neigh_groups[] = { { AF_UNSPEC, RTNLGRP_NEIGH }, { AF_BRIDGE, RTNLGRP_NEIGH }, { END_OF_GROUP_LIST }, }; static struct nl_cache_ops rtnl_neigh_ops = { .co_name = "route/neigh", .co_hdrsize = sizeof(struct ndmsg), .co_msgtypes = { { RTM_NEWNEIGH, NL_ACT_NEW, "new" }, { RTM_DELNEIGH, NL_ACT_DEL, "del" }, { RTM_GETNEIGH, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_groups = neigh_groups, .co_request_update = neigh_request_update, .co_msg_parser = neigh_msg_parser, .co_obj_ops = &neigh_obj_ops, }; static void __init neigh_init(void) { nl_cache_mngt_register(&rtnl_neigh_ops); } static void __exit neigh_exit(void) { nl_cache_mngt_unregister(&rtnl_neigh_ops); } /** @} */ libnl-3.2.29/lib/route/rule.c0000644000175000017500000004276313023014600012650 00000000000000/* * lib/route/rule.c Routing Rules * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2010 Thomas Graf */ /** * @ingroup rtnl * @defgroup rule Routing Rules * @brief * @{ */ #include #include #include #include #include #include /** @cond SKIP */ #define RULE_ATTR_FAMILY 0x0001 #define RULE_ATTR_TABLE 0x0002 #define RULE_ATTR_ACTION 0x0004 #define RULE_ATTR_FLAGS 0x0008 #define RULE_ATTR_IIFNAME 0x0010 #define RULE_ATTR_OIFNAME 0x0020 #define RULE_ATTR_PRIO 0x0040 #define RULE_ATTR_MARK 0x0080 #define RULE_ATTR_MASK 0x0100 #define RULE_ATTR_GOTO 0x0200 #define RULE_ATTR_SRC 0x0400 #define RULE_ATTR_DST 0x0800 #define RULE_ATTR_DSFIELD 0x1000 #define RULE_ATTR_FLOW 0x2000 static struct nl_cache_ops rtnl_rule_ops; static struct nl_object_ops rule_obj_ops; /** @endcond */ static void rule_free_data(struct nl_object *c) { struct rtnl_rule *rule = nl_object_priv(c); if (!rule) return; nl_addr_put(rule->r_src); nl_addr_put(rule->r_dst); } static int rule_clone(struct nl_object *_dst, struct nl_object *_src) { struct rtnl_rule *dst = nl_object_priv(_dst); struct rtnl_rule *src = nl_object_priv(_src); if (src->r_src) if (!(dst->r_src = nl_addr_clone(src->r_src))) return -NLE_NOMEM; if (src->r_dst) if (!(dst->r_dst = nl_addr_clone(src->r_dst))) return -NLE_NOMEM; return 0; } static struct nla_policy rule_policy[FRA_MAX+1] = { [FRA_TABLE] = { .type = NLA_U32 }, [FRA_IIFNAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [FRA_OIFNAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [FRA_PRIORITY] = { .type = NLA_U32 }, [FRA_FWMARK] = { .type = NLA_U32 }, [FRA_FWMASK] = { .type = NLA_U32 }, [FRA_GOTO] = { .type = NLA_U32 }, [FRA_FLOW] = { .type = NLA_U32 }, }; static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct rtnl_rule *rule; struct fib_rule_hdr *frh; struct nlattr *tb[FRA_MAX+1]; int err = 1, family; rule = rtnl_rule_alloc(); if (!rule) { err = -NLE_NOMEM; goto errout; } rule->ce_msgtype = n->nlmsg_type; frh = nlmsg_data(n); err = nlmsg_parse(n, sizeof(*frh), tb, FRA_MAX, rule_policy); if (err < 0) goto errout; rule->r_family = family = frh->family; rule->r_table = frh->table; rule->r_action = frh->action; rule->r_flags = frh->flags; rule->ce_mask = (RULE_ATTR_FAMILY | RULE_ATTR_TABLE | RULE_ATTR_ACTION | RULE_ATTR_FLAGS); /* ipv4 only */ if (frh->tos) { rule->r_dsfield = frh->tos; rule->ce_mask |= RULE_ATTR_DSFIELD; } if (tb[FRA_TABLE]) { rule->r_table = nla_get_u32(tb[FRA_TABLE]); rule->ce_mask |= RULE_ATTR_TABLE; } if (tb[FRA_IIFNAME]) { nla_strlcpy(rule->r_iifname, tb[FRA_IIFNAME], IFNAMSIZ); rule->ce_mask |= RULE_ATTR_IIFNAME; } if (tb[FRA_OIFNAME]) { nla_strlcpy(rule->r_oifname, tb[FRA_OIFNAME], IFNAMSIZ); rule->ce_mask |= RULE_ATTR_OIFNAME; } if (tb[FRA_PRIORITY]) { rule->r_prio = nla_get_u32(tb[FRA_PRIORITY]); rule->ce_mask |= RULE_ATTR_PRIO; } if (tb[FRA_FWMARK]) { rule->r_mark = nla_get_u32(tb[FRA_FWMARK]); rule->ce_mask |= RULE_ATTR_MARK; } if (tb[FRA_FWMASK]) { rule->r_mask = nla_get_u32(tb[FRA_FWMASK]); rule->ce_mask |= RULE_ATTR_MASK; } if (tb[FRA_GOTO]) { rule->r_goto = nla_get_u32(tb[FRA_GOTO]); rule->ce_mask |= RULE_ATTR_GOTO; } if (tb[FRA_SRC]) { if (!(rule->r_src = nl_addr_alloc_attr(tb[FRA_SRC], family))) goto errout_enomem; nl_addr_set_prefixlen(rule->r_src, frh->src_len); rule->ce_mask |= RULE_ATTR_SRC; } if (tb[FRA_DST]) { if (!(rule->r_dst = nl_addr_alloc_attr(tb[FRA_DST], family))) goto errout_enomem; nl_addr_set_prefixlen(rule->r_dst, frh->dst_len); rule->ce_mask |= RULE_ATTR_DST; } /* ipv4 only */ if (tb[FRA_FLOW]) { rule->r_flow = nla_get_u32(tb[FRA_FLOW]); rule->ce_mask |= RULE_ATTR_FLOW; } err = pp->pp_cb((struct nl_object *) rule, pp); errout: rtnl_rule_put(rule); return err; errout_enomem: err = -NLE_NOMEM; goto errout; } static int rule_request_update(struct nl_cache *c, struct nl_sock *h) { return nl_rtgen_request(h, RTM_GETRULE, AF_UNSPEC, NLM_F_DUMP); } static void rule_dump_line(struct nl_object *o, struct nl_dump_params *p) { struct rtnl_rule *r = (struct rtnl_rule *) o; char buf[128]; nl_dump_line(p, "%8d ", (r->ce_mask & RULE_ATTR_PRIO) ? r->r_prio : 0); nl_dump(p, "%s ", nl_af2str(r->r_family, buf, sizeof(buf))); if (r->ce_mask & RULE_ATTR_SRC) nl_dump(p, "from %s ", nl_addr2str(r->r_src, buf, sizeof(buf))); if (r->ce_mask & RULE_ATTR_DST) nl_dump(p, "to %s ", nl_addr2str(r->r_dst, buf, sizeof(buf))); if (r->ce_mask & RULE_ATTR_DSFIELD) nl_dump(p, "tos %u ", r->r_dsfield); if (r->ce_mask & (RULE_ATTR_MARK | RULE_ATTR_MASK)) nl_dump(p, "mark %#x/%#x", r->r_mark, r->r_mask); if (r->ce_mask & RULE_ATTR_IIFNAME) nl_dump(p, "iif %s ", r->r_iifname); if (r->ce_mask & RULE_ATTR_OIFNAME) nl_dump(p, "oif %s ", r->r_oifname); if (r->ce_mask & RULE_ATTR_TABLE) nl_dump(p, "lookup %s ", rtnl_route_table2str(r->r_table, buf, sizeof(buf))); if (r->ce_mask & RULE_ATTR_FLOW) nl_dump(p, "flow %s ", rtnl_realms2str(r->r_flow, buf, sizeof(buf))); if (r->ce_mask & RULE_ATTR_GOTO) nl_dump(p, "goto %u ", r->r_goto); if (r->ce_mask & RULE_ATTR_ACTION) nl_dump(p, "action %s", nl_rtntype2str(r->r_action, buf, sizeof(buf))); nl_dump(p, "\n"); } static void rule_dump_details(struct nl_object *obj, struct nl_dump_params *p) { rule_dump_line(obj, p); } static void rule_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { rule_dump_details(obj, p); } #define RULE_ATTR_FLAGS 0x0008 static uint64_t rule_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct rtnl_rule *a = (struct rtnl_rule *) _a; struct rtnl_rule *b = (struct rtnl_rule *) _b; uint64_t diff = 0; #define RULE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, RULE_ATTR_##ATTR, a, b, EXPR) diff |= RULE_DIFF(FAMILY, a->r_family != b->r_family); diff |= RULE_DIFF(TABLE, a->r_table != b->r_table); diff |= RULE_DIFF(ACTION, a->r_action != b->r_action); diff |= RULE_DIFF(IIFNAME, strcmp(a->r_iifname, b->r_iifname)); diff |= RULE_DIFF(OIFNAME, strcmp(a->r_oifname, b->r_oifname)); diff |= RULE_DIFF(PRIO, a->r_prio != b->r_prio); diff |= RULE_DIFF(MARK, a->r_mark != b->r_mark); diff |= RULE_DIFF(MASK, a->r_mask != b->r_mask); diff |= RULE_DIFF(GOTO, a->r_goto != b->r_goto); diff |= RULE_DIFF(SRC, nl_addr_cmp(a->r_src, b->r_src)); diff |= RULE_DIFF(DST, nl_addr_cmp(a->r_dst, b->r_dst)); diff |= RULE_DIFF(DSFIELD, a->r_dsfield != b->r_dsfield); diff |= RULE_DIFF(FLOW, a->r_flow != b->r_flow); #undef RULE_DIFF return diff; } static const struct trans_tbl rule_attrs[] = { __ADD(RULE_ATTR_FAMILY, family), __ADD(RULE_ATTR_TABLE, table), __ADD(RULE_ATTR_ACTION, action), __ADD(RULE_ATTR_IIFNAME, iifname), __ADD(RULE_ATTR_OIFNAME, oifname), __ADD(RULE_ATTR_PRIO, prio), __ADD(RULE_ATTR_MARK, mark), __ADD(RULE_ATTR_MASK, mask), __ADD(RULE_ATTR_GOTO, goto), __ADD(RULE_ATTR_SRC, src), __ADD(RULE_ATTR_DST, dst), __ADD(RULE_ATTR_DSFIELD, dsfield), __ADD(RULE_ATTR_FLOW, flow), }; static char *rule_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, rule_attrs, ARRAY_SIZE(rule_attrs)); } /** * @name Allocation/Freeing * @{ */ struct rtnl_rule *rtnl_rule_alloc(void) { return (struct rtnl_rule *) nl_object_alloc(&rule_obj_ops); } void rtnl_rule_put(struct rtnl_rule *rule) { nl_object_put((struct nl_object *) rule); } /** @} */ /** * @name Cache Management * @{ */ /** * Build a rule cache including all rules currently configured in the kernel. * @arg sock Netlink socket. * @arg family Address family or AF_UNSPEC. * @arg result Pointer to store resulting cache. * * Allocates a new rule cache, initializes it properly and updates it * to include all rules currently configured in the kernel. * * @return 0 on success or a negative error code. */ int rtnl_rule_alloc_cache(struct nl_sock *sock, int family, struct nl_cache **result) { struct nl_cache * cache; int err; if (!(cache = nl_cache_alloc(&rtnl_rule_ops))) return -NLE_NOMEM; cache->c_iarg1 = family; if (sock && (err = nl_cache_refill(sock, cache)) < 0) { free(cache); return err; } *result = cache; return 0; } /** @} */ /** * @name Rule Addition * @{ */ static int build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; struct fib_rule_hdr frh = { .family = tmpl->r_family, .table = tmpl->r_table, .action = tmpl->r_action, .flags = tmpl->r_flags, .tos = tmpl->r_dsfield, }; if (!(tmpl->ce_mask & RULE_ATTR_FAMILY)) return -NLE_MISSING_ATTR; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (tmpl->ce_mask & RULE_ATTR_SRC) frh.src_len = nl_addr_get_prefixlen(tmpl->r_src); if (tmpl->ce_mask & RULE_ATTR_DST) frh.dst_len = nl_addr_get_prefixlen(tmpl->r_dst); if (nlmsg_append(msg, &frh, sizeof(frh), NLMSG_ALIGNTO) < 0) goto nla_put_failure; /* Additional table attribute replacing the 8bit in the header, was * required to allow more than 256 tables. */ NLA_PUT_U32(msg, FRA_TABLE, tmpl->r_table); if (tmpl->ce_mask & RULE_ATTR_SRC) NLA_PUT_ADDR(msg, FRA_SRC, tmpl->r_src); if (tmpl->ce_mask & RULE_ATTR_DST) NLA_PUT_ADDR(msg, FRA_DST, tmpl->r_dst); if (tmpl->ce_mask & RULE_ATTR_IIFNAME) NLA_PUT_STRING(msg, FRA_IIFNAME, tmpl->r_iifname); if (tmpl->ce_mask & RULE_ATTR_OIFNAME) NLA_PUT_STRING(msg, FRA_OIFNAME, tmpl->r_oifname); if (tmpl->ce_mask & RULE_ATTR_PRIO) NLA_PUT_U32(msg, FRA_PRIORITY, tmpl->r_prio); if (tmpl->ce_mask & RULE_ATTR_MARK) NLA_PUT_U32(msg, FRA_FWMARK, tmpl->r_mark); if (tmpl->ce_mask & RULE_ATTR_MASK) NLA_PUT_U32(msg, FRA_FWMASK, tmpl->r_mask); if (tmpl->ce_mask & RULE_ATTR_GOTO) NLA_PUT_U32(msg, FRA_GOTO, tmpl->r_goto); if (tmpl->ce_mask & RULE_ATTR_FLOW) NLA_PUT_U32(msg, FRA_FLOW, tmpl->r_flow); *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * Build netlink request message to add a new rule * @arg tmpl template with data of new rule * @arg flags additional netlink message flags * @arg result Result pointer * * Builds a new netlink message requesting a addition of a new * rule. The netlink message header isn't fully equipped with * all relevant fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. \a tmpl must contain the attributes of the new * address set via \c rtnl_rule_set_* functions. * * @return 0 on success or a negative error code. */ int rtnl_rule_build_add_request(struct rtnl_rule *tmpl, int flags, struct nl_msg **result) { return build_rule_msg(tmpl, RTM_NEWRULE, NLM_F_CREATE | flags, result); } /** * Add a new rule * @arg sk Netlink socket. * @arg tmpl template with requested changes * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_rule_build_add_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_rule_add(struct nl_sock *sk, struct rtnl_rule *tmpl, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_rule_build_add_request(tmpl, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ /** * @name Rule Deletion * @{ */ /** * Build a netlink request message to delete a rule * @arg rule rule to delete * @arg flags additional netlink message flags * @arg result Result pointer * * Builds a new netlink message requesting a deletion of a rule. * The netlink message header isn't fully equipped with all relevant * fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. \a rule must point to an existing * address. * * @return 0 on success or a negative error code. */ int rtnl_rule_build_delete_request(struct rtnl_rule *rule, int flags, struct nl_msg **result) { return build_rule_msg(rule, RTM_DELRULE, flags, result); } /** * Delete a rule * @arg sk Netlink socket. * @arg rule rule to delete * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_rule_build_delete_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_rule_delete(struct nl_sock *sk, struct rtnl_rule *rule, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_rule_build_delete_request(rule, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ /** * @name Attribute Modification * @{ */ void rtnl_rule_set_family(struct rtnl_rule *rule, int family) { rule->r_family = family; rule->ce_mask |= RULE_ATTR_FAMILY; } int rtnl_rule_get_family(struct rtnl_rule *rule) { if (rule->ce_mask & RULE_ATTR_FAMILY) return rule->r_family; else return AF_UNSPEC; } void rtnl_rule_set_prio(struct rtnl_rule *rule, uint32_t prio) { rule->r_prio = prio; rule->ce_mask |= RULE_ATTR_PRIO; } uint32_t rtnl_rule_get_prio(struct rtnl_rule *rule) { return rule->r_prio; } void rtnl_rule_set_mark(struct rtnl_rule *rule, uint32_t mark) { rule->r_mark = mark; rule->ce_mask |= RULE_ATTR_MARK; } uint32_t rtnl_rule_get_mark(struct rtnl_rule *rule) { return rule->r_mark; } void rtnl_rule_set_mask(struct rtnl_rule *rule, uint32_t mask) { rule->r_mask = mask; rule->ce_mask |= RULE_ATTR_MASK; } uint32_t rtnl_rule_get_mask(struct rtnl_rule *rule) { return rule->r_mask; } void rtnl_rule_set_table(struct rtnl_rule *rule, uint32_t table) { rule->r_table = table; rule->ce_mask |= RULE_ATTR_TABLE; } uint32_t rtnl_rule_get_table(struct rtnl_rule *rule) { return rule->r_table; } void rtnl_rule_set_dsfield(struct rtnl_rule *rule, uint8_t dsfield) { rule->r_dsfield = dsfield; rule->ce_mask |= RULE_ATTR_DSFIELD; } uint8_t rtnl_rule_get_dsfield(struct rtnl_rule *rule) { return rule->r_dsfield; } static inline int __assign_addr(struct rtnl_rule *rule, struct nl_addr **pos, struct nl_addr *new, int flag) { if (rule->ce_mask & RULE_ATTR_FAMILY) { if (new->a_family != rule->r_family) return -NLE_AF_MISMATCH; } else rule->r_family = new->a_family; if (*pos) nl_addr_put(*pos); nl_addr_get(new); *pos = new; rule->ce_mask |= (flag | RULE_ATTR_FAMILY); return 0; } int rtnl_rule_set_src(struct rtnl_rule *rule, struct nl_addr *src) { return __assign_addr(rule, &rule->r_src, src, RULE_ATTR_SRC); } struct nl_addr *rtnl_rule_get_src(struct rtnl_rule *rule) { return rule->r_src; } int rtnl_rule_set_dst(struct rtnl_rule *rule, struct nl_addr *dst) { return __assign_addr(rule, &rule->r_dst, dst, RULE_ATTR_DST); } struct nl_addr *rtnl_rule_get_dst(struct rtnl_rule *rule) { return rule->r_dst; } int rtnl_rule_set_iif(struct rtnl_rule *rule, const char *dev) { if (strlen(dev) > IFNAMSIZ-1) return -NLE_RANGE; strcpy(rule->r_iifname, dev); rule->ce_mask |= RULE_ATTR_IIFNAME; return 0; } char *rtnl_rule_get_iif(struct rtnl_rule *rule) { if (rule->ce_mask & RULE_ATTR_IIFNAME) return rule->r_iifname; else return NULL; } int rtnl_rule_set_oif(struct rtnl_rule *rule, const char *dev) { if (strlen(dev) > IFNAMSIZ-1) return -NLE_RANGE; strcpy(rule->r_oifname, dev); rule->ce_mask |= RULE_ATTR_OIFNAME; return 0; } char *rtnl_rule_get_oif(struct rtnl_rule *rule) { if (rule->ce_mask & RULE_ATTR_OIFNAME) return rule->r_oifname; else return NULL; } void rtnl_rule_set_action(struct rtnl_rule *rule, uint8_t action) { rule->r_action = action; rule->ce_mask |= RULE_ATTR_ACTION; } uint8_t rtnl_rule_get_action(struct rtnl_rule *rule) { return rule->r_action; } void rtnl_rule_set_realms(struct rtnl_rule *rule, uint32_t realms) { rule->r_flow = realms; rule->ce_mask |= RULE_ATTR_FLOW; } uint32_t rtnl_rule_get_realms(struct rtnl_rule *rule) { return rule->r_flow; } void rtnl_rule_set_goto(struct rtnl_rule *rule, uint32_t ref) { rule->r_goto = ref; rule->ce_mask |= RULE_ATTR_GOTO; } uint32_t rtnl_rule_get_goto(struct rtnl_rule *rule) { return rule->r_goto; } /** @} */ static struct nl_object_ops rule_obj_ops = { .oo_name = "route/rule", .oo_size = sizeof(struct rtnl_rule), .oo_free_data = rule_free_data, .oo_clone = rule_clone, .oo_dump = { [NL_DUMP_LINE] = rule_dump_line, [NL_DUMP_DETAILS] = rule_dump_details, [NL_DUMP_STATS] = rule_dump_stats, }, .oo_compare = rule_compare, .oo_attrs2str = rule_attrs2str, .oo_id_attrs = ~0, }; static struct nl_cache_ops rtnl_rule_ops = { .co_name = "route/rule", .co_hdrsize = sizeof(struct fib_rule_hdr), .co_msgtypes = { { RTM_NEWRULE, NL_ACT_NEW, "new" }, { RTM_DELRULE, NL_ACT_DEL, "del" }, { RTM_GETRULE, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_request_update = rule_request_update, .co_msg_parser = rule_msg_parser, .co_obj_ops = &rule_obj_ops, }; static void __init rule_init(void) { nl_cache_mngt_register(&rtnl_rule_ops); } static void __exit rule_exit(void) { nl_cache_mngt_unregister(&rtnl_rule_ops); } /** @} */ libnl-3.2.29/lib/route/pktloc_grammar.l0000644000175000017500000000206513023014600014703 00000000000000%{ #include #include #include #include #include #include "pktloc_syntax.h" %} %option 8bit %option reentrant %option warn %option noyywrap %option noinput %option nounput %option bison-bridge %option bison-locations %option prefix="pktloc_" %% [ \t\r\n]+ "#".* [[:digit:]]+ | 0[xX][[:xdigit:]]+ { yylval->i = strtoul(yytext, NULL, 0); return NUMBER; } "+" { return yylval->i = yytext[0]; } [uU]8 { yylval->i = TCF_EM_ALIGN_U8; return ALIGN; } [uU]16 { yylval->i = TCF_EM_ALIGN_U16; return ALIGN; } [uU]32 { yylval->i = TCF_EM_ALIGN_U32; return ALIGN; } [lL][iI][nN][kK] | [eE][tT][hH] { yylval->i = TCF_LAYER_LINK; return LAYER; } [nN][eE][tT] | [iI][pP] { yylval->i = TCF_LAYER_NETWORK; return LAYER; } [tT][rR][aA][nN][sS][pP][oO][rR][tT] | [tT][cC][pP] { yylval->i = TCF_LAYER_TRANSPORT; return LAYER; } [^ \t\r\n+]+ { yylval->s = strdup(yytext); if (yylval->s == NULL) return ERROR; return NAME; } libnl-3.2.29/lib/route/route_obj.c0000644000175000017500000007617313023014600013673 00000000000000/* * lib/route/route_obj.c Route Object * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup route * @defgroup route_obj Route Object * * @par Attributes * @code * Name Default * ------------------------------------------------------------- * routing table RT_TABLE_MAIN * scope RT_SCOPE_NOWHERE * tos 0 * protocol RTPROT_STATIC * prio 0 * family AF_UNSPEC * type RTN_UNICAST * iif NULL * @endcode * * @{ */ #include #include #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define ROUTE_ATTR_FAMILY 0x000001 #define ROUTE_ATTR_TOS 0x000002 #define ROUTE_ATTR_TABLE 0x000004 #define ROUTE_ATTR_PROTOCOL 0x000008 #define ROUTE_ATTR_SCOPE 0x000010 #define ROUTE_ATTR_TYPE 0x000020 #define ROUTE_ATTR_FLAGS 0x000040 #define ROUTE_ATTR_DST 0x000080 #define ROUTE_ATTR_SRC 0x000100 #define ROUTE_ATTR_IIF 0x000200 #define ROUTE_ATTR_OIF 0x000400 #define ROUTE_ATTR_GATEWAY 0x000800 #define ROUTE_ATTR_PRIO 0x001000 #define ROUTE_ATTR_PREF_SRC 0x002000 #define ROUTE_ATTR_METRICS 0x004000 #define ROUTE_ATTR_MULTIPATH 0x008000 #define ROUTE_ATTR_REALMS 0x010000 #define ROUTE_ATTR_CACHEINFO 0x020000 /** @endcond */ static void route_constructor(struct nl_object *c) { struct rtnl_route *r = (struct rtnl_route *) c; r->rt_family = AF_UNSPEC; r->rt_scope = RT_SCOPE_NOWHERE; r->rt_table = RT_TABLE_MAIN; r->rt_protocol = RTPROT_STATIC; r->rt_type = RTN_UNICAST; r->rt_prio = 0; nl_init_list_head(&r->rt_nexthops); } static void route_free_data(struct nl_object *c) { struct rtnl_route *r = (struct rtnl_route *) c; struct rtnl_nexthop *nh, *tmp; if (r == NULL) return; nl_addr_put(r->rt_dst); nl_addr_put(r->rt_src); nl_addr_put(r->rt_pref_src); nl_list_for_each_entry_safe(nh, tmp, &r->rt_nexthops, rtnh_list) { rtnl_route_remove_nexthop(r, nh); rtnl_route_nh_free(nh); } } static int route_clone(struct nl_object *_dst, struct nl_object *_src) { struct rtnl_route *dst = (struct rtnl_route *) _dst; struct rtnl_route *src = (struct rtnl_route *) _src; struct rtnl_nexthop *nh, *new; if (src->rt_dst) if (!(dst->rt_dst = nl_addr_clone(src->rt_dst))) return -NLE_NOMEM; if (src->rt_src) if (!(dst->rt_src = nl_addr_clone(src->rt_src))) return -NLE_NOMEM; if (src->rt_pref_src) if (!(dst->rt_pref_src = nl_addr_clone(src->rt_pref_src))) return -NLE_NOMEM; /* Will be inc'ed again while adding the nexthops of the source */ dst->rt_nr_nh = 0; nl_init_list_head(&dst->rt_nexthops); nl_list_for_each_entry(nh, &src->rt_nexthops, rtnh_list) { new = rtnl_route_nh_clone(nh); if (!new) return -NLE_NOMEM; rtnl_route_add_nexthop(dst, new); } return 0; } static void route_dump_line(struct nl_object *a, struct nl_dump_params *p) { struct rtnl_route *r = (struct rtnl_route *) a; int cache = 0, flags; char buf[64]; if (r->rt_flags & RTM_F_CLONED) cache = 1; nl_dump_line(p, "%s ", nl_af2str(r->rt_family, buf, sizeof(buf))); if (cache) nl_dump(p, "cache "); if (!(r->ce_mask & ROUTE_ATTR_DST) || nl_addr_get_len(r->rt_dst) == 0) nl_dump(p, "default "); else nl_dump(p, "%s ", nl_addr2str(r->rt_dst, buf, sizeof(buf))); if (r->ce_mask & ROUTE_ATTR_TABLE && !cache) nl_dump(p, "table %s ", rtnl_route_table2str(r->rt_table, buf, sizeof(buf))); if (r->ce_mask & ROUTE_ATTR_TYPE) nl_dump(p, "type %s ", nl_rtntype2str(r->rt_type, buf, sizeof(buf))); if (r->ce_mask & ROUTE_ATTR_TOS && r->rt_tos != 0) nl_dump(p, "tos %#x ", r->rt_tos); if (r->ce_mask & ROUTE_ATTR_MULTIPATH) { struct rtnl_nexthop *nh; nl_list_for_each_entry(nh, &r->rt_nexthops, rtnh_list) { p->dp_ivar = NH_DUMP_FROM_ONELINE; rtnl_route_nh_dump(nh, p); } } flags = r->rt_flags & ~(RTM_F_CLONED); if (r->ce_mask & ROUTE_ATTR_FLAGS && flags) { nl_dump(p, "<"); #define PRINT_FLAG(f) if (flags & RTNH_F_##f) { \ flags &= ~RTNH_F_##f; nl_dump(p, #f "%s", flags ? "," : ""); } PRINT_FLAG(DEAD); PRINT_FLAG(ONLINK); PRINT_FLAG(PERVASIVE); #undef PRINT_FLAG #define PRINT_FLAG(f) if (flags & RTM_F_##f) { \ flags &= ~RTM_F_##f; nl_dump(p, #f "%s", flags ? "," : ""); } PRINT_FLAG(NOTIFY); PRINT_FLAG(EQUALIZE); PRINT_FLAG(PREFIX); #undef PRINT_FLAG #define PRINT_FLAG(f) if (flags & RTCF_##f) { \ flags &= ~RTCF_##f; nl_dump(p, #f "%s", flags ? "," : ""); } PRINT_FLAG(NOTIFY); PRINT_FLAG(REDIRECTED); PRINT_FLAG(DOREDIRECT); PRINT_FLAG(DIRECTSRC); PRINT_FLAG(DNAT); PRINT_FLAG(BROADCAST); PRINT_FLAG(MULTICAST); PRINT_FLAG(LOCAL); #undef PRINT_FLAG nl_dump(p, ">"); } nl_dump(p, "\n"); } static void route_dump_details(struct nl_object *a, struct nl_dump_params *p) { struct rtnl_route *r = (struct rtnl_route *) a; struct nl_cache *link_cache; char buf[256]; int i; link_cache = nl_cache_mngt_require_safe("route/link"); route_dump_line(a, p); nl_dump_line(p, " "); if (r->ce_mask & ROUTE_ATTR_PREF_SRC) nl_dump(p, "preferred-src %s ", nl_addr2str(r->rt_pref_src, buf, sizeof(buf))); if (r->ce_mask & ROUTE_ATTR_SCOPE && r->rt_scope != RT_SCOPE_NOWHERE) nl_dump(p, "scope %s ", rtnl_scope2str(r->rt_scope, buf, sizeof(buf))); if (r->ce_mask & ROUTE_ATTR_PRIO) nl_dump(p, "priority %#x ", r->rt_prio); if (r->ce_mask & ROUTE_ATTR_PROTOCOL) nl_dump(p, "protocol %s ", rtnl_route_proto2str(r->rt_protocol, buf, sizeof(buf))); if (r->ce_mask & ROUTE_ATTR_IIF) { if (link_cache) { nl_dump(p, "iif %s ", rtnl_link_i2name(link_cache, r->rt_iif, buf, sizeof(buf))); } else nl_dump(p, "iif %d ", r->rt_iif); } if (r->ce_mask & ROUTE_ATTR_SRC) nl_dump(p, "src %s ", nl_addr2str(r->rt_src, buf, sizeof(buf))); nl_dump(p, "\n"); if (r->ce_mask & ROUTE_ATTR_MULTIPATH) { struct rtnl_nexthop *nh; nl_list_for_each_entry(nh, &r->rt_nexthops, rtnh_list) { nl_dump_line(p, " "); p->dp_ivar = NH_DUMP_FROM_DETAILS; rtnl_route_nh_dump(nh, p); nl_dump(p, "\n"); } } if ((r->ce_mask & ROUTE_ATTR_CACHEINFO) && r->rt_cacheinfo.rtci_error) { nl_dump_line(p, " cacheinfo error %d (%s)\n", r->rt_cacheinfo.rtci_error, nl_strerror_l(-r->rt_cacheinfo.rtci_error)); } if (r->ce_mask & ROUTE_ATTR_METRICS) { nl_dump_line(p, " metrics ["); for (i = 0; i < RTAX_MAX; i++) if (r->rt_metrics_mask & (1 << i)) nl_dump(p, "%s %u ", rtnl_route_metric2str(i+1, buf, sizeof(buf)), r->rt_metrics[i]); nl_dump(p, "]\n"); } if (link_cache) nl_cache_put(link_cache); } static void route_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_route *route = (struct rtnl_route *) obj; route_dump_details(obj, p); if (route->ce_mask & ROUTE_ATTR_CACHEINFO) { struct rtnl_rtcacheinfo *ci = &route->rt_cacheinfo; nl_dump_line(p, " used %u refcnt %u last-use %us " "expires %us\n", ci->rtci_used, ci->rtci_clntref, ci->rtci_last_use / nl_get_user_hz(), ci->rtci_expires / nl_get_user_hz()); } } static void route_keygen(struct nl_object *obj, uint32_t *hashkey, uint32_t table_sz) { struct rtnl_route *route = (struct rtnl_route *) obj; unsigned int rkey_sz; struct nl_addr *addr = NULL; struct route_hash_key { uint8_t rt_family; uint8_t rt_tos; uint32_t rt_table; uint32_t rt_prio; char rt_addr[0]; } __attribute__((packed)) *rkey; #ifdef NL_DEBUG char buf[INET6_ADDRSTRLEN+5]; #endif if (route->rt_dst) addr = route->rt_dst; rkey_sz = sizeof(*rkey); if (addr) rkey_sz += nl_addr_get_len(addr); rkey = calloc(1, rkey_sz); if (!rkey) { NL_DBG(2, "Warning: calloc failed for %d bytes...\n", rkey_sz); *hashkey = 0; return; } rkey->rt_family = route->rt_family; rkey->rt_tos = route->rt_tos; rkey->rt_table = route->rt_table; rkey->rt_prio = route->rt_prio; if (addr) memcpy(rkey->rt_addr, nl_addr_get_binary_addr(addr), nl_addr_get_len(addr)); *hashkey = nl_hash(rkey, rkey_sz, 0) % table_sz; NL_DBG(5, "route %p key (fam %d tos %d table %d addr %s) keysz %d " "hash 0x%x\n", route, rkey->rt_family, rkey->rt_tos, rkey->rt_table, nl_addr2str(addr, buf, sizeof(buf)), rkey_sz, *hashkey); free(rkey); return; } static uint64_t route_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct rtnl_route *a = (struct rtnl_route *) _a; struct rtnl_route *b = (struct rtnl_route *) _b; struct rtnl_nexthop *nh_a, *nh_b; int i, found; uint64_t diff = 0; #define ROUTE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ROUTE_ATTR_##ATTR, a, b, EXPR) diff |= ROUTE_DIFF(FAMILY, a->rt_family != b->rt_family); diff |= ROUTE_DIFF(TOS, a->rt_tos != b->rt_tos); diff |= ROUTE_DIFF(TABLE, a->rt_table != b->rt_table); diff |= ROUTE_DIFF(PROTOCOL, a->rt_protocol != b->rt_protocol); diff |= ROUTE_DIFF(SCOPE, a->rt_scope != b->rt_scope); diff |= ROUTE_DIFF(TYPE, a->rt_type != b->rt_type); diff |= ROUTE_DIFF(PRIO, a->rt_prio != b->rt_prio); diff |= ROUTE_DIFF(DST, nl_addr_cmp(a->rt_dst, b->rt_dst)); diff |= ROUTE_DIFF(SRC, nl_addr_cmp(a->rt_src, b->rt_src)); diff |= ROUTE_DIFF(IIF, a->rt_iif != b->rt_iif); diff |= ROUTE_DIFF(PREF_SRC, nl_addr_cmp(a->rt_pref_src, b->rt_pref_src)); if (flags & LOOSE_COMPARISON) { nl_list_for_each_entry(nh_b, &b->rt_nexthops, rtnh_list) { found = 0; nl_list_for_each_entry(nh_a, &a->rt_nexthops, rtnh_list) { if (!rtnl_route_nh_compare(nh_a, nh_b, nh_b->ce_mask, 1)) { found = 1; break; } } if (!found) goto nh_mismatch; } for (i = 0; i < RTAX_MAX - 1; i++) { if (a->rt_metrics_mask & (1 << i) && (!(b->rt_metrics_mask & (1 << i)) || a->rt_metrics[i] != b->rt_metrics[i])) diff |= ROUTE_DIFF(METRICS, 1); } diff |= ROUTE_DIFF(FLAGS, (a->rt_flags ^ b->rt_flags) & b->rt_flag_mask); } else { if (a->rt_nr_nh != b->rt_nr_nh) goto nh_mismatch; /* search for a dup in each nh of a */ nl_list_for_each_entry(nh_a, &a->rt_nexthops, rtnh_list) { found = 0; nl_list_for_each_entry(nh_b, &b->rt_nexthops, rtnh_list) { if (!rtnl_route_nh_compare(nh_a, nh_b, ~0, 0)) { found = 1; break; } } if (!found) goto nh_mismatch; } /* search for a dup in each nh of b, covers case where a has * dupes itself */ nl_list_for_each_entry(nh_b, &b->rt_nexthops, rtnh_list) { found = 0; nl_list_for_each_entry(nh_a, &a->rt_nexthops, rtnh_list) { if (!rtnl_route_nh_compare(nh_a, nh_b, ~0, 0)) { found = 1; break; } } if (!found) goto nh_mismatch; } for (i = 0; i < RTAX_MAX - 1; i++) { if ((a->rt_metrics_mask & (1 << i)) ^ (b->rt_metrics_mask & (1 << i))) diff |= ROUTE_DIFF(METRICS, 1); else diff |= ROUTE_DIFF(METRICS, a->rt_metrics[i] != b->rt_metrics[i]); } diff |= ROUTE_DIFF(FLAGS, a->rt_flags != b->rt_flags); } out: return diff; nh_mismatch: diff |= ROUTE_DIFF(MULTIPATH, 1); goto out; #undef ROUTE_DIFF } static int route_update(struct nl_object *old_obj, struct nl_object *new_obj) { struct rtnl_route *new_route = (struct rtnl_route *) new_obj; struct rtnl_route *old_route = (struct rtnl_route *) old_obj; struct rtnl_nexthop *new_nh; int action = new_obj->ce_msgtype; #ifdef NL_DEBUG char buf[INET6_ADDRSTRLEN+5]; #endif /* * ipv6 ECMP route notifications from the kernel come as * separate notifications, one for every nexthop. This update * function collapses such route msgs into a single * route with multiple nexthops. The resulting object looks * similar to a ipv4 ECMP route */ if (new_route->rt_family != AF_INET6 || new_route->rt_table == RT_TABLE_LOCAL) return -NLE_OPNOTSUPP; /* * For routes that are already multipath, * or dont have a nexthop dont do anything */ if (rtnl_route_get_nnexthops(new_route) != 1) return -NLE_OPNOTSUPP; /* * Get the only nexthop entry from the new route. For * IPv6 we always get a route with a 0th NH * filled or nothing at all */ new_nh = rtnl_route_nexthop_n(new_route, 0); if (!new_nh || !rtnl_route_nh_get_gateway(new_nh)) return -NLE_OPNOTSUPP; switch(action) { case RTM_NEWROUTE : { struct rtnl_nexthop *cloned_nh; /* * Add the nexthop to old route */ cloned_nh = rtnl_route_nh_clone(new_nh); if (!cloned_nh) return -NLE_NOMEM; rtnl_route_add_nexthop(old_route, cloned_nh); NL_DBG(2, "Route obj %p updated. Added " "nexthop %p via %s\n", old_route, cloned_nh, nl_addr2str(cloned_nh->rtnh_gateway, buf, sizeof(buf))); } break; case RTM_DELROUTE : { struct rtnl_nexthop *old_nh; /* * Only take care of nexthop deletes and not * route deletes. So, if there is only one nexthop * quite likely we did not update it. So dont do * anything and return */ if (rtnl_route_get_nnexthops(old_route) <= 1) return -NLE_OPNOTSUPP; /* * Find the next hop in old route and delete it */ nl_list_for_each_entry(old_nh, &old_route->rt_nexthops, rtnh_list) { if (!rtnl_route_nh_compare(old_nh, new_nh, ~0, 0)) { rtnl_route_remove_nexthop(old_route, old_nh); NL_DBG(2, "Route obj %p updated. Removed " "nexthop %p via %s\n", old_route, old_nh, nl_addr2str(old_nh->rtnh_gateway, buf, sizeof(buf))); rtnl_route_nh_free(old_nh); break; } } } break; default: NL_DBG(2, "Unknown action associated " "to object %p during route update\n", new_obj); return -NLE_OPNOTSUPP; } return NLE_SUCCESS; } static const struct trans_tbl route_attrs[] = { __ADD(ROUTE_ATTR_FAMILY, family), __ADD(ROUTE_ATTR_TOS, tos), __ADD(ROUTE_ATTR_TABLE, table), __ADD(ROUTE_ATTR_PROTOCOL, protocol), __ADD(ROUTE_ATTR_SCOPE, scope), __ADD(ROUTE_ATTR_TYPE, type), __ADD(ROUTE_ATTR_FLAGS, flags), __ADD(ROUTE_ATTR_DST, dst), __ADD(ROUTE_ATTR_SRC, src), __ADD(ROUTE_ATTR_IIF, iif), __ADD(ROUTE_ATTR_OIF, oif), __ADD(ROUTE_ATTR_GATEWAY, gateway), __ADD(ROUTE_ATTR_PRIO, prio), __ADD(ROUTE_ATTR_PREF_SRC, pref_src), __ADD(ROUTE_ATTR_METRICS, metrics), __ADD(ROUTE_ATTR_MULTIPATH, multipath), __ADD(ROUTE_ATTR_REALMS, realms), __ADD(ROUTE_ATTR_CACHEINFO, cacheinfo), }; static char *route_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, route_attrs, ARRAY_SIZE(route_attrs)); } /** * @name Allocation/Freeing * @{ */ struct rtnl_route *rtnl_route_alloc(void) { return (struct rtnl_route *) nl_object_alloc(&route_obj_ops); } void rtnl_route_get(struct rtnl_route *route) { nl_object_get((struct nl_object *) route); } void rtnl_route_put(struct rtnl_route *route) { nl_object_put((struct nl_object *) route); } /** @} */ /** * @name Attributes * @{ */ void rtnl_route_set_table(struct rtnl_route *route, uint32_t table) { route->rt_table = table; route->ce_mask |= ROUTE_ATTR_TABLE; } uint32_t rtnl_route_get_table(struct rtnl_route *route) { return route->rt_table; } void rtnl_route_set_scope(struct rtnl_route *route, uint8_t scope) { route->rt_scope = scope; route->ce_mask |= ROUTE_ATTR_SCOPE; } uint8_t rtnl_route_get_scope(struct rtnl_route *route) { return route->rt_scope; } void rtnl_route_set_tos(struct rtnl_route *route, uint8_t tos) { route->rt_tos = tos; route->ce_mask |= ROUTE_ATTR_TOS; } uint8_t rtnl_route_get_tos(struct rtnl_route *route) { return route->rt_tos; } void rtnl_route_set_protocol(struct rtnl_route *route, uint8_t protocol) { route->rt_protocol = protocol; route->ce_mask |= ROUTE_ATTR_PROTOCOL; } uint8_t rtnl_route_get_protocol(struct rtnl_route *route) { return route->rt_protocol; } void rtnl_route_set_priority(struct rtnl_route *route, uint32_t prio) { route->rt_prio = prio; route->ce_mask |= ROUTE_ATTR_PRIO; } uint32_t rtnl_route_get_priority(struct rtnl_route *route) { return route->rt_prio; } int rtnl_route_set_family(struct rtnl_route *route, uint8_t family) { if (family != AF_INET && family != AF_INET6 && family != AF_DECnet) return -NLE_AF_NOSUPPORT; route->rt_family = family; route->ce_mask |= ROUTE_ATTR_FAMILY; return 0; } uint8_t rtnl_route_get_family(struct rtnl_route *route) { return route->rt_family; } int rtnl_route_set_dst(struct rtnl_route *route, struct nl_addr *addr) { if (route->ce_mask & ROUTE_ATTR_FAMILY) { if (addr->a_family != route->rt_family) return -NLE_AF_MISMATCH; } else route->rt_family = addr->a_family; if (route->rt_dst) nl_addr_put(route->rt_dst); nl_addr_get(addr); route->rt_dst = addr; route->ce_mask |= (ROUTE_ATTR_DST | ROUTE_ATTR_FAMILY); return 0; } struct nl_addr *rtnl_route_get_dst(struct rtnl_route *route) { return route->rt_dst; } int rtnl_route_set_src(struct rtnl_route *route, struct nl_addr *addr) { if (addr->a_family == AF_INET) return -NLE_SRCRT_NOSUPPORT; if (route->ce_mask & ROUTE_ATTR_FAMILY) { if (addr->a_family != route->rt_family) return -NLE_AF_MISMATCH; } else route->rt_family = addr->a_family; if (route->rt_src) nl_addr_put(route->rt_src); nl_addr_get(addr); route->rt_src = addr; route->ce_mask |= (ROUTE_ATTR_SRC | ROUTE_ATTR_FAMILY); return 0; } struct nl_addr *rtnl_route_get_src(struct rtnl_route *route) { return route->rt_src; } int rtnl_route_set_type(struct rtnl_route *route, uint8_t type) { if (type > RTN_MAX) return -NLE_RANGE; route->rt_type = type; route->ce_mask |= ROUTE_ATTR_TYPE; return 0; } uint8_t rtnl_route_get_type(struct rtnl_route *route) { return route->rt_type; } void rtnl_route_set_flags(struct rtnl_route *route, uint32_t flags) { route->rt_flag_mask |= flags; route->rt_flags |= flags; route->ce_mask |= ROUTE_ATTR_FLAGS; } void rtnl_route_unset_flags(struct rtnl_route *route, uint32_t flags) { route->rt_flag_mask |= flags; route->rt_flags &= ~flags; route->ce_mask |= ROUTE_ATTR_FLAGS; } uint32_t rtnl_route_get_flags(struct rtnl_route *route) { return route->rt_flags; } int rtnl_route_set_metric(struct rtnl_route *route, int metric, uint32_t value) { if (metric > RTAX_MAX || metric < 1) return -NLE_RANGE; route->rt_metrics[metric - 1] = value; if (!(route->rt_metrics_mask & (1 << (metric - 1)))) { route->rt_nmetrics++; route->rt_metrics_mask |= (1 << (metric - 1)); } route->ce_mask |= ROUTE_ATTR_METRICS; return 0; } int rtnl_route_unset_metric(struct rtnl_route *route, int metric) { if (metric > RTAX_MAX || metric < 1) return -NLE_RANGE; if (route->rt_metrics_mask & (1 << (metric - 1))) { route->rt_nmetrics--; route->rt_metrics_mask &= ~(1 << (metric - 1)); } return 0; } int rtnl_route_get_metric(struct rtnl_route *route, int metric, uint32_t *value) { if (metric > RTAX_MAX || metric < 1) return -NLE_RANGE; if (!(route->rt_metrics_mask & (1 << (metric - 1)))) return -NLE_OBJ_NOTFOUND; if (value) *value = route->rt_metrics[metric - 1]; return 0; } int rtnl_route_set_pref_src(struct rtnl_route *route, struct nl_addr *addr) { if (route->ce_mask & ROUTE_ATTR_FAMILY) { if (addr->a_family != route->rt_family) return -NLE_AF_MISMATCH; } else route->rt_family = addr->a_family; if (route->rt_pref_src) nl_addr_put(route->rt_pref_src); nl_addr_get(addr); route->rt_pref_src = addr; route->ce_mask |= (ROUTE_ATTR_PREF_SRC | ROUTE_ATTR_FAMILY); return 0; } struct nl_addr *rtnl_route_get_pref_src(struct rtnl_route *route) { return route->rt_pref_src; } void rtnl_route_set_iif(struct rtnl_route *route, int ifindex) { route->rt_iif = ifindex; route->ce_mask |= ROUTE_ATTR_IIF; } int rtnl_route_get_iif(struct rtnl_route *route) { return route->rt_iif; } void rtnl_route_add_nexthop(struct rtnl_route *route, struct rtnl_nexthop *nh) { nl_list_add_tail(&nh->rtnh_list, &route->rt_nexthops); route->rt_nr_nh++; route->ce_mask |= ROUTE_ATTR_MULTIPATH; } void rtnl_route_remove_nexthop(struct rtnl_route *route, struct rtnl_nexthop *nh) { if (route->ce_mask & ROUTE_ATTR_MULTIPATH) { route->rt_nr_nh--; nl_list_del(&nh->rtnh_list); } } struct nl_list_head *rtnl_route_get_nexthops(struct rtnl_route *route) { if (route->ce_mask & ROUTE_ATTR_MULTIPATH) return &route->rt_nexthops; return NULL; } int rtnl_route_get_nnexthops(struct rtnl_route *route) { if (route->ce_mask & ROUTE_ATTR_MULTIPATH) return route->rt_nr_nh; return 0; } void rtnl_route_foreach_nexthop(struct rtnl_route *r, void (*cb)(struct rtnl_nexthop *, void *), void *arg) { struct rtnl_nexthop *nh; if (r->ce_mask & ROUTE_ATTR_MULTIPATH) { nl_list_for_each_entry(nh, &r->rt_nexthops, rtnh_list) { cb(nh, arg); } } } struct rtnl_nexthop *rtnl_route_nexthop_n(struct rtnl_route *r, int n) { struct rtnl_nexthop *nh; uint32_t i; if (r->ce_mask & ROUTE_ATTR_MULTIPATH && r->rt_nr_nh > n) { i = 0; nl_list_for_each_entry(nh, &r->rt_nexthops, rtnh_list) { if (i == n) return nh; i++; } } return NULL; } /** @} */ /** * @name Utilities * @{ */ /** * Guess scope of a route object. * @arg route Route object. * * Guesses the scope of a route object, based on the following rules: * @code * 1) Local route -> local scope * 2) At least one nexthop not directly connected -> universe scope * 3) All others -> link scope * @endcode * * @return Scope value. */ int rtnl_route_guess_scope(struct rtnl_route *route) { if (route->rt_type == RTN_LOCAL) return RT_SCOPE_HOST; if (!nl_list_empty(&route->rt_nexthops)) { struct rtnl_nexthop *nh; /* * Use scope uiniverse if there is at least one nexthop which * is not directly connected */ nl_list_for_each_entry(nh, &route->rt_nexthops, rtnh_list) { if (nh->rtnh_gateway) return RT_SCOPE_UNIVERSE; } } return RT_SCOPE_LINK; } /** @} */ static struct nla_policy route_policy[RTA_MAX+1] = { [RTA_IIF] = { .type = NLA_U32 }, [RTA_OIF] = { .type = NLA_U32 }, [RTA_PRIORITY] = { .type = NLA_U32 }, [RTA_FLOW] = { .type = NLA_U32 }, [RTA_CACHEINFO] = { .minlen = sizeof(struct rta_cacheinfo) }, [RTA_METRICS] = { .type = NLA_NESTED }, [RTA_MULTIPATH] = { .type = NLA_NESTED }, }; static int parse_multipath(struct rtnl_route *route, struct nlattr *attr) { struct rtnl_nexthop *nh = NULL; struct rtnexthop *rtnh = nla_data(attr); size_t tlen = nla_len(attr); int err; while (tlen >= sizeof(*rtnh) && tlen >= rtnh->rtnh_len) { nh = rtnl_route_nh_alloc(); if (!nh) return -NLE_NOMEM; rtnl_route_nh_set_weight(nh, rtnh->rtnh_hops); rtnl_route_nh_set_ifindex(nh, rtnh->rtnh_ifindex); rtnl_route_nh_set_flags(nh, rtnh->rtnh_flags); if (rtnh->rtnh_len > sizeof(*rtnh)) { struct nlattr *ntb[RTA_MAX + 1]; err = nla_parse(ntb, RTA_MAX, (struct nlattr *) RTNH_DATA(rtnh), rtnh->rtnh_len - sizeof(*rtnh), route_policy); if (err < 0) goto errout; if (ntb[RTA_GATEWAY]) { struct nl_addr *addr; addr = nl_addr_alloc_attr(ntb[RTA_GATEWAY], route->rt_family); if (!addr) { err = -NLE_NOMEM; goto errout; } rtnl_route_nh_set_gateway(nh, addr); nl_addr_put(addr); } if (ntb[RTA_FLOW]) { uint32_t realms; realms = nla_get_u32(ntb[RTA_FLOW]); rtnl_route_nh_set_realms(nh, realms); } } rtnl_route_add_nexthop(route, nh); tlen -= RTNH_ALIGN(rtnh->rtnh_len); rtnh = RTNH_NEXT(rtnh); } err = 0; errout: if (err && nh) rtnl_route_nh_free(nh); return err; } int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result) { struct rtmsg *rtm; struct rtnl_route *route; struct nlattr *tb[RTA_MAX + 1]; struct nl_addr *src = NULL, *dst = NULL, *addr; struct rtnl_nexthop *old_nh = NULL; int err, family; route = rtnl_route_alloc(); if (!route) { err = -NLE_NOMEM; goto errout; } route->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct rtmsg), tb, RTA_MAX, route_policy); if (err < 0) goto errout; rtm = nlmsg_data(nlh); route->rt_family = family = rtm->rtm_family; route->rt_tos = rtm->rtm_tos; route->rt_table = rtm->rtm_table; route->rt_type = rtm->rtm_type; route->rt_scope = rtm->rtm_scope; route->rt_protocol = rtm->rtm_protocol; route->rt_flags = rtm->rtm_flags; route->rt_prio = 0; route->ce_mask |= ROUTE_ATTR_FAMILY | ROUTE_ATTR_TOS | ROUTE_ATTR_TABLE | ROUTE_ATTR_TYPE | ROUTE_ATTR_SCOPE | ROUTE_ATTR_PROTOCOL | ROUTE_ATTR_FLAGS | ROUTE_ATTR_PRIO; if (tb[RTA_DST]) { if (!(dst = nl_addr_alloc_attr(tb[RTA_DST], family))) goto errout_nomem; } else { if (!(dst = nl_addr_alloc(0))) goto errout_nomem; nl_addr_set_family(dst, rtm->rtm_family); } nl_addr_set_prefixlen(dst, rtm->rtm_dst_len); err = rtnl_route_set_dst(route, dst); if (err < 0) goto errout; nl_addr_put(dst); if (tb[RTA_SRC]) { if (!(src = nl_addr_alloc_attr(tb[RTA_SRC], family))) goto errout_nomem; } else if (rtm->rtm_src_len) if (!(src = nl_addr_alloc(0))) goto errout_nomem; if (src) { nl_addr_set_prefixlen(src, rtm->rtm_src_len); rtnl_route_set_src(route, src); nl_addr_put(src); } if (tb[RTA_TABLE]) rtnl_route_set_table(route, nla_get_u32(tb[RTA_TABLE])); if (tb[RTA_IIF]) rtnl_route_set_iif(route, nla_get_u32(tb[RTA_IIF])); if (tb[RTA_PRIORITY]) rtnl_route_set_priority(route, nla_get_u32(tb[RTA_PRIORITY])); if (tb[RTA_PREFSRC]) { if (!(addr = nl_addr_alloc_attr(tb[RTA_PREFSRC], family))) goto errout_nomem; rtnl_route_set_pref_src(route, addr); nl_addr_put(addr); } if (tb[RTA_METRICS]) { struct nlattr *mtb[RTAX_MAX + 1]; int i; err = nla_parse_nested(mtb, RTAX_MAX, tb[RTA_METRICS], NULL); if (err < 0) goto errout; for (i = 1; i <= RTAX_MAX; i++) { if (mtb[i] && nla_len(mtb[i]) >= sizeof(uint32_t)) { uint32_t m = nla_get_u32(mtb[i]); if (rtnl_route_set_metric(route, i, m) < 0) goto errout; } } } if (tb[RTA_MULTIPATH]) if ((err = parse_multipath(route, tb[RTA_MULTIPATH])) < 0) goto errout; if (tb[RTA_CACHEINFO]) { nla_memcpy(&route->rt_cacheinfo, tb[RTA_CACHEINFO], sizeof(route->rt_cacheinfo)); route->ce_mask |= ROUTE_ATTR_CACHEINFO; } if (tb[RTA_OIF]) { if (!old_nh && !(old_nh = rtnl_route_nh_alloc())) goto errout; rtnl_route_nh_set_ifindex(old_nh, nla_get_u32(tb[RTA_OIF])); } if (tb[RTA_GATEWAY]) { if (!old_nh && !(old_nh = rtnl_route_nh_alloc())) goto errout; if (!(addr = nl_addr_alloc_attr(tb[RTA_GATEWAY], family))) goto errout_nomem; rtnl_route_nh_set_gateway(old_nh, addr); nl_addr_put(addr); } if (tb[RTA_FLOW]) { if (!old_nh && !(old_nh = rtnl_route_nh_alloc())) goto errout; rtnl_route_nh_set_realms(old_nh, nla_get_u32(tb[RTA_FLOW])); } if (old_nh) { rtnl_route_nh_set_flags(old_nh, rtm->rtm_flags & 0xff); if (route->rt_nr_nh == 0) { /* If no nexthops have been provided via RTA_MULTIPATH * we add it as regular nexthop to maintain backwards * compatibility */ rtnl_route_add_nexthop(route, old_nh); } else { /* Kernel supports new style nexthop configuration, * verify that it is a duplicate and discard nexthop. */ struct rtnl_nexthop *first; first = nl_list_first_entry(&route->rt_nexthops, struct rtnl_nexthop, rtnh_list); if (!first) BUG(); if (rtnl_route_nh_compare(old_nh, first, old_nh->ce_mask, 0)) { err = -NLE_INVAL; goto errout; } rtnl_route_nh_free(old_nh); } } *result = route; return 0; errout: rtnl_route_put(route); return err; errout_nomem: err = -NLE_NOMEM; goto errout; } int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route) { int i; struct nlattr *metrics; struct rtmsg rtmsg = { .rtm_family = route->rt_family, .rtm_tos = route->rt_tos, .rtm_table = route->rt_table, .rtm_protocol = route->rt_protocol, .rtm_scope = route->rt_scope, .rtm_type = route->rt_type, .rtm_flags = route->rt_flags, }; if (route->rt_dst == NULL) return -NLE_MISSING_ATTR; rtmsg.rtm_dst_len = nl_addr_get_prefixlen(route->rt_dst); if (route->rt_src) rtmsg.rtm_src_len = nl_addr_get_prefixlen(route->rt_src); if (!(route->ce_mask & ROUTE_ATTR_SCOPE)) rtmsg.rtm_scope = rtnl_route_guess_scope(route); if (rtnl_route_get_nnexthops(route) == 1) { struct rtnl_nexthop *nh; nh = rtnl_route_nexthop_n(route, 0); rtmsg.rtm_flags |= nh->rtnh_flags; } if (nlmsg_append(msg, &rtmsg, sizeof(rtmsg), NLMSG_ALIGNTO) < 0) goto nla_put_failure; /* Additional table attribute replacing the 8bit in the header, was * required to allow more than 256 tables. */ NLA_PUT_U32(msg, RTA_TABLE, route->rt_table); if (nl_addr_get_len(route->rt_dst)) NLA_PUT_ADDR(msg, RTA_DST, route->rt_dst); NLA_PUT_U32(msg, RTA_PRIORITY, route->rt_prio); if (route->ce_mask & ROUTE_ATTR_SRC) NLA_PUT_ADDR(msg, RTA_SRC, route->rt_src); if (route->ce_mask & ROUTE_ATTR_PREF_SRC) NLA_PUT_ADDR(msg, RTA_PREFSRC, route->rt_pref_src); if (route->ce_mask & ROUTE_ATTR_IIF) NLA_PUT_U32(msg, RTA_IIF, route->rt_iif); if (route->rt_nmetrics > 0) { uint32_t val; metrics = nla_nest_start(msg, RTA_METRICS); if (metrics == NULL) goto nla_put_failure; for (i = 1; i <= RTAX_MAX; i++) { if (!rtnl_route_get_metric(route, i, &val)) NLA_PUT_U32(msg, i, val); } nla_nest_end(msg, metrics); } if (rtnl_route_get_nnexthops(route) == 1) { struct rtnl_nexthop *nh; nh = rtnl_route_nexthop_n(route, 0); if (nh->rtnh_gateway) NLA_PUT_ADDR(msg, RTA_GATEWAY, nh->rtnh_gateway); if (nh->rtnh_ifindex) NLA_PUT_U32(msg, RTA_OIF, nh->rtnh_ifindex); if (nh->rtnh_realms) NLA_PUT_U32(msg, RTA_FLOW, nh->rtnh_realms); } else if (rtnl_route_get_nnexthops(route) > 1) { struct nlattr *multipath; struct rtnl_nexthop *nh; if (!(multipath = nla_nest_start(msg, RTA_MULTIPATH))) goto nla_put_failure; nl_list_for_each_entry(nh, &route->rt_nexthops, rtnh_list) { struct rtnexthop *rtnh; rtnh = nlmsg_reserve(msg, sizeof(*rtnh), NLMSG_ALIGNTO); if (!rtnh) goto nla_put_failure; rtnh->rtnh_flags = nh->rtnh_flags; rtnh->rtnh_hops = nh->rtnh_weight; rtnh->rtnh_ifindex = nh->rtnh_ifindex; if (nh->rtnh_gateway) NLA_PUT_ADDR(msg, RTA_GATEWAY, nh->rtnh_gateway); if (nh->rtnh_realms) NLA_PUT_U32(msg, RTA_FLOW, nh->rtnh_realms); rtnh->rtnh_len = nlmsg_tail(msg->nm_nlh) - (void *) rtnh; } nla_nest_end(msg, multipath); } return 0; nla_put_failure: return -NLE_MSGSIZE; } /** @cond SKIP */ struct nl_object_ops route_obj_ops = { .oo_name = "route/route", .oo_size = sizeof(struct rtnl_route), .oo_constructor = route_constructor, .oo_free_data = route_free_data, .oo_clone = route_clone, .oo_dump = { [NL_DUMP_LINE] = route_dump_line, [NL_DUMP_DETAILS] = route_dump_details, [NL_DUMP_STATS] = route_dump_stats, }, .oo_compare = route_compare, .oo_keygen = route_keygen, .oo_update = route_update, .oo_attrs2str = route_attrs2str, .oo_id_attrs = (ROUTE_ATTR_FAMILY | ROUTE_ATTR_TOS | ROUTE_ATTR_TABLE | ROUTE_ATTR_DST | ROUTE_ATTR_PRIO), }; /** @endcond */ /** @} */ libnl-3.2.29/lib/route/nexthop.c0000644000175000017500000001404513023014600013356 00000000000000/* * lib/route/nexthop.c Routing Nexthop * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup route_obj * @defgroup nexthop Nexthop * @{ */ #include #include #include #include #include /** @cond SKIP */ #define NH_ATTR_FLAGS 0x000001 #define NH_ATTR_WEIGHT 0x000002 #define NH_ATTR_IFINDEX 0x000004 #define NH_ATTR_GATEWAY 0x000008 #define NH_ATTR_REALMS 0x000010 /** @endcond */ /** * @name Allocation/Freeing * @{ */ struct rtnl_nexthop *rtnl_route_nh_alloc(void) { struct rtnl_nexthop *nh; nh = calloc(1, sizeof(*nh)); if (!nh) return NULL; nl_init_list_head(&nh->rtnh_list); return nh; } struct rtnl_nexthop *rtnl_route_nh_clone(struct rtnl_nexthop *src) { struct rtnl_nexthop *nh; nh = rtnl_route_nh_alloc(); if (!nh) return NULL; nh->rtnh_flags = src->rtnh_flags; nh->rtnh_flag_mask = src->rtnh_flag_mask; nh->rtnh_weight = src->rtnh_weight; nh->rtnh_ifindex = src->rtnh_ifindex; nh->ce_mask = src->ce_mask; if (src->rtnh_gateway) { nh->rtnh_gateway = nl_addr_clone(src->rtnh_gateway); if (!nh->rtnh_gateway) { free(nh); return NULL; } } return nh; } void rtnl_route_nh_free(struct rtnl_nexthop *nh) { nl_addr_put(nh->rtnh_gateway); free(nh); } /** @} */ int rtnl_route_nh_compare(struct rtnl_nexthop *a, struct rtnl_nexthop *b, uint32_t attrs, int loose) { int diff = 0; #define NH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NH_ATTR_##ATTR, a, b, EXPR) diff |= NH_DIFF(IFINDEX, a->rtnh_ifindex != b->rtnh_ifindex); diff |= NH_DIFF(WEIGHT, a->rtnh_weight != b->rtnh_weight); diff |= NH_DIFF(REALMS, a->rtnh_realms != b->rtnh_realms); diff |= NH_DIFF(GATEWAY, nl_addr_cmp(a->rtnh_gateway, b->rtnh_gateway)); if (loose) diff |= NH_DIFF(FLAGS, (a->rtnh_flags ^ b->rtnh_flags) & b->rtnh_flag_mask); else diff |= NH_DIFF(FLAGS, a->rtnh_flags != b->rtnh_flags); #undef NH_DIFF return diff; } static void nh_dump_line(struct rtnl_nexthop *nh, struct nl_dump_params *dp) { struct nl_cache *link_cache; char buf[128]; link_cache = nl_cache_mngt_require_safe("route/link"); nl_dump(dp, "via"); if (nh->ce_mask & NH_ATTR_GATEWAY) nl_dump(dp, " %s", nl_addr2str(nh->rtnh_gateway, buf, sizeof(buf))); if(nh->ce_mask & NH_ATTR_IFINDEX) { if (link_cache) { nl_dump(dp, " dev %s", rtnl_link_i2name(link_cache, nh->rtnh_ifindex, buf, sizeof(buf))); } else nl_dump(dp, " dev %d", nh->rtnh_ifindex); } nl_dump(dp, " "); if (link_cache) nl_cache_put(link_cache); } static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp) { struct nl_cache *link_cache; char buf[128]; link_cache = nl_cache_mngt_require_safe("route/link"); nl_dump(dp, "nexthop"); if (nh->ce_mask & NH_ATTR_GATEWAY) nl_dump(dp, " via %s", nl_addr2str(nh->rtnh_gateway, buf, sizeof(buf))); if(nh->ce_mask & NH_ATTR_IFINDEX) { if (link_cache) { nl_dump(dp, " dev %s", rtnl_link_i2name(link_cache, nh->rtnh_ifindex, buf, sizeof(buf))); } else nl_dump(dp, " dev %d", nh->rtnh_ifindex); } if (nh->ce_mask & NH_ATTR_WEIGHT) nl_dump(dp, " weight %u", nh->rtnh_weight); if (nh->ce_mask & NH_ATTR_REALMS) nl_dump(dp, " realm %04x:%04x", RTNL_REALM_FROM(nh->rtnh_realms), RTNL_REALM_TO(nh->rtnh_realms)); if (nh->ce_mask & NH_ATTR_FLAGS) nl_dump(dp, " <%s>", rtnl_route_nh_flags2str(nh->rtnh_flags, buf, sizeof(buf))); if (link_cache) nl_cache_put(link_cache); } void rtnl_route_nh_dump(struct rtnl_nexthop *nh, struct nl_dump_params *dp) { switch (dp->dp_type) { case NL_DUMP_LINE: nh_dump_line(nh, dp); break; case NL_DUMP_DETAILS: case NL_DUMP_STATS: if (dp->dp_ivar == NH_DUMP_FROM_DETAILS) nh_dump_details(nh, dp); break; default: break; } } /** * @name Attributes * @{ */ void rtnl_route_nh_set_weight(struct rtnl_nexthop *nh, uint8_t weight) { nh->rtnh_weight = weight; nh->ce_mask |= NH_ATTR_WEIGHT; } uint8_t rtnl_route_nh_get_weight(struct rtnl_nexthop *nh) { return nh->rtnh_weight; } void rtnl_route_nh_set_ifindex(struct rtnl_nexthop *nh, int ifindex) { nh->rtnh_ifindex = ifindex; nh->ce_mask |= NH_ATTR_IFINDEX; } int rtnl_route_nh_get_ifindex(struct rtnl_nexthop *nh) { return nh->rtnh_ifindex; } /* FIXME: Convert to return an int */ void rtnl_route_nh_set_gateway(struct rtnl_nexthop *nh, struct nl_addr *addr) { struct nl_addr *old = nh->rtnh_gateway; if (addr) { nh->rtnh_gateway = nl_addr_get(addr); nh->ce_mask |= NH_ATTR_GATEWAY; } else { nh->ce_mask &= ~NH_ATTR_GATEWAY; nh->rtnh_gateway = NULL; } if (old) nl_addr_put(old); } struct nl_addr *rtnl_route_nh_get_gateway(struct rtnl_nexthop *nh) { return nh->rtnh_gateway; } void rtnl_route_nh_set_flags(struct rtnl_nexthop *nh, unsigned int flags) { nh->rtnh_flag_mask |= flags; nh->rtnh_flags |= flags; nh->ce_mask |= NH_ATTR_FLAGS; } void rtnl_route_nh_unset_flags(struct rtnl_nexthop *nh, unsigned int flags) { nh->rtnh_flag_mask |= flags; nh->rtnh_flags &= ~flags; nh->ce_mask |= NH_ATTR_FLAGS; } unsigned int rtnl_route_nh_get_flags(struct rtnl_nexthop *nh) { return nh->rtnh_flags; } void rtnl_route_nh_set_realms(struct rtnl_nexthop *nh, uint32_t realms) { nh->rtnh_realms = realms; nh->ce_mask |= NH_ATTR_REALMS; } uint32_t rtnl_route_nh_get_realms(struct rtnl_nexthop *nh) { return nh->rtnh_realms; } /** @} */ /** * @name Nexthop Flags Translations * @{ */ static const struct trans_tbl nh_flags[] = { __ADD(RTNH_F_DEAD, dead), __ADD(RTNH_F_PERVASIVE, pervasive), __ADD(RTNH_F_ONLINK, onlink), }; char *rtnl_route_nh_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, nh_flags, ARRAY_SIZE(nh_flags)); } int rtnl_route_nh_str2flags(const char *name) { return __str2flags(name, nh_flags, ARRAY_SIZE(nh_flags)); } /** @} */ /** @} */ libnl-3.2.29/lib/route/rtnl.c0000644000175000017500000000511713023014600012650 00000000000000/* * lib/route/rtnl.c Routing Netlink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @defgroup rtnl Routing Library (libnl-route) * @{ */ #include #include #include #include /** * @name Sending * @{ */ /** * Send routing netlink request message * @arg sk Netlink socket. * @arg type Netlink message type. * @arg family Address family. * @arg flags Additional netlink message flags. * * Fills out a routing netlink request message and sends it out * using nl_send_simple(). * * @return 0 on success or a negative error code. Due to a bug in older * version of the library, this function returned the number of bytes sent. * Treat any non-negative number as success. */ int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags) { int err; struct rtgenmsg gmsg = { .rtgen_family = family, }; err = nl_send_simple(sk, type, flags, &gmsg, sizeof(gmsg)); return err >= 0 ? 0 : err; } /** @} */ /** * @name Routing Type Translations * @{ */ static const struct trans_tbl rtntypes[] = { __ADD(RTN_UNSPEC,unspec), __ADD(RTN_UNICAST,unicast), __ADD(RTN_LOCAL,local), __ADD(RTN_BROADCAST,broadcast), __ADD(RTN_ANYCAST,anycast), __ADD(RTN_MULTICAST,multicast), __ADD(RTN_BLACKHOLE,blackhole), __ADD(RTN_UNREACHABLE,unreachable), __ADD(RTN_PROHIBIT,prohibit), __ADD(RTN_THROW,throw), __ADD(RTN_NAT,nat), __ADD(RTN_XRESOLVE,xresolve), }; char *nl_rtntype2str(int type, char *buf, size_t size) { return __type2str(type, buf, size, rtntypes, ARRAY_SIZE(rtntypes)); } int nl_str2rtntype(const char *name) { return __str2type(name, rtntypes, ARRAY_SIZE(rtntypes)); } /** @} */ /** * @name Scope Translations * @{ */ static const struct trans_tbl scopes[] = { __ADD(255,nowhere), __ADD(254,host), __ADD(253,link), __ADD(200,site), __ADD(0,global), }; char *rtnl_scope2str(int scope, char *buf, size_t size) { return __type2str(scope, buf, size, scopes, ARRAY_SIZE(scopes)); } int rtnl_str2scope(const char *name) { return __str2type(name, scopes, ARRAY_SIZE(scopes)); } /** @} */ /** * @name Realms Translations * @{ */ char * rtnl_realms2str(uint32_t realms, char *buf, size_t len) { int from = RTNL_REALM_FROM(realms); int to = RTNL_REALM_TO(realms); snprintf(buf, len, "%d/%d", from, to); return buf; } /** @} */ /** @} */ libnl-3.2.29/lib/route/neightbl.c0000644000175000017500000005600013023014600013462 00000000000000/* * lib/route/neightbl.c neighbour tables * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup rtnl * @defgroup neightbl Neighbour Tables * @brief * @{ */ #include #include #include #include #include #include /** @cond SKIP */ #define NEIGHTBL_ATTR_FAMILY 0x001 #define NEIGHTBL_ATTR_STATS 0x002 #define NEIGHTBL_ATTR_NAME 0x004 #define NEIGHTBL_ATTR_THRESH1 0x008 #define NEIGHTBL_ATTR_THRESH2 0x010 #define NEIGHTBL_ATTR_THRESH3 0x020 #define NEIGHTBL_ATTR_CONFIG 0x040 #define NEIGHTBL_ATTR_PARMS 0x080 #define NEIGHTBL_ATTR_GC_INTERVAL 0x100 #define NEIGHTBLPARM_ATTR_IFINDEX 0x0001 #define NEIGHTBLPARM_ATTR_REFCNT 0x0002 #define NEIGHTBLPARM_ATTR_QUEUE_LEN 0x0004 #define NEIGHTBLPARM_ATTR_APP_PROBES 0x0008 #define NEIGHTBLPARM_ATTR_UCAST_PROBES 0x0010 #define NEIGHTBLPARM_ATTR_MCAST_PROBES 0x0020 #define NEIGHTBLPARM_ATTR_PROXY_QLEN 0x0040 #define NEIGHTBLPARM_ATTR_REACHABLE_TIME 0x0080 #define NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME 0x0100 #define NEIGHTBLPARM_ATTR_RETRANS_TIME 0x0200 #define NEIGHTBLPARM_ATTR_GC_STALETIME 0x0400 #define NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME 0x0800 #define NEIGHTBLPARM_ATTR_ANYCAST_DELAY 0x1000 #define NEIGHTBLPARM_ATTR_PROXY_DELAY 0x2000 #define NEIGHTBLPARM_ATTR_LOCKTIME 0x4000 static struct nl_cache_ops rtnl_neightbl_ops; static struct nl_object_ops neightbl_obj_ops; /** @endcond */ static uint64_t neightbl_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct rtnl_neightbl *a = (struct rtnl_neightbl *) _a; struct rtnl_neightbl *b = (struct rtnl_neightbl *) _b; uint64_t diff = 0; #define NT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGHTBL_ATTR_##ATTR, a, b, EXPR) diff |= NT_DIFF(FAMILY, a->nt_family != b->nt_family); diff |= NT_DIFF(NAME, strcmp(a->nt_name, b->nt_name)); diff |= NT_DIFF(THRESH1, a->nt_gc_thresh1 != b->nt_gc_thresh1); diff |= NT_DIFF(THRESH2, a->nt_gc_thresh2 != b->nt_gc_thresh2); diff |= NT_DIFF(THRESH3, a->nt_gc_thresh3 != b->nt_gc_thresh3); diff |= NT_DIFF(GC_INTERVAL, a->nt_gc_interval != b->nt_gc_interval); #undef NT_DIFF if (!(a->ce_mask & NEIGHTBL_ATTR_PARMS) && !(b->ce_mask & NEIGHTBL_ATTR_PARMS)) return diff; /* XXX: FIXME: Compare parameter table */ #if 0 #define REQ(F) (fp->ntp_mask & NEIGHTBLPARM_ATTR_##F) #define AVAIL(F) (op->ntp_mask & NEIGHTBLPARM_ATTR_##F) #define _C(F, N) (REQ(F) && (!AVAIL(F) || (op->N != fp->N))) if (_C(IFINDEX, ntp_ifindex) || _C(QUEUE_LEN, ntp_queue_len) || _C(APP_PROBES, ntp_app_probes) || _C(UCAST_PROBES, ntp_ucast_probes) || _C(MCAST_PROBES, ntp_mcast_probes) || _C(PROXY_QLEN, ntp_proxy_qlen) || _C(LOCKTIME, ntp_locktime) || _C(RETRANS_TIME, ntp_retrans_time) || _C(BASE_REACHABLE_TIME, ntp_base_reachable_time) || _C(GC_STALETIME, ntp_gc_stale_time) || _C(DELAY_PROBE_TIME, ntp_probe_delay) || _C(ANYCAST_DELAY, ntp_anycast_delay) || _C(PROXY_DELAY, ntp_proxy_delay)) return 0; #undef REQ #undef AVAIL #undef _C #endif return diff; } static struct nla_policy neightbl_policy[NDTA_MAX+1] = { [NDTA_NAME] = { .type = NLA_STRING, .maxlen = NTBLNAMSIZ }, [NDTA_THRESH1] = { .type = NLA_U32 }, [NDTA_THRESH2] = { .type = NLA_U32 }, [NDTA_THRESH3] = { .type = NLA_U32 }, [NDTA_GC_INTERVAL] = { .type = NLA_U32 }, [NDTA_CONFIG] = { .minlen = sizeof(struct ndt_config) }, [NDTA_STATS] = { .minlen = sizeof(struct ndt_stats) }, [NDTA_PARMS] = { .type = NLA_NESTED }, }; static int neightbl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct rtnl_neightbl *ntbl; struct nlattr *tb[NDTA_MAX + 1]; struct rtgenmsg *rtmsg; int err; ntbl = rtnl_neightbl_alloc(); if (!ntbl) { err = -NLE_NOMEM; goto errout; } ntbl->ce_msgtype = n->nlmsg_type; rtmsg = nlmsg_data(n); err = nlmsg_parse(n, sizeof(*rtmsg), tb, NDTA_MAX, neightbl_policy); if (err < 0) goto errout; ntbl->nt_family = rtmsg->rtgen_family; if (tb[NDTA_NAME] == NULL) { err = -NLE_MISSING_ATTR; goto errout; } nla_strlcpy(ntbl->nt_name, tb[NDTA_NAME], NTBLNAMSIZ); ntbl->ce_mask |= NEIGHTBL_ATTR_NAME; if (tb[NDTA_THRESH1]) { ntbl->nt_gc_thresh1 = nla_get_u32(tb[NDTA_THRESH1]); ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH1; } if (tb[NDTA_THRESH2]) { ntbl->nt_gc_thresh2 = nla_get_u32(tb[NDTA_THRESH2]); ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH2; } if (tb[NDTA_THRESH3]) { ntbl->nt_gc_thresh3 = nla_get_u32(tb[NDTA_THRESH3]); ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH3; } if (tb[NDTA_GC_INTERVAL]) { ntbl->nt_gc_interval = nla_get_u32(tb[NDTA_GC_INTERVAL]); ntbl->ce_mask |= NEIGHTBL_ATTR_GC_INTERVAL; } if (tb[NDTA_CONFIG]) { nla_memcpy(&ntbl->nt_config, tb[NDTA_CONFIG], sizeof(ntbl->nt_config)); ntbl->ce_mask |= NEIGHTBL_ATTR_CONFIG; } if (tb[NDTA_STATS]) { nla_memcpy(&ntbl->nt_stats, tb[NDTA_STATS], sizeof(ntbl->nt_stats)); ntbl->ce_mask |= NEIGHTBL_ATTR_STATS; } if (tb[NDTA_PARMS]) { struct nlattr *tbp[NDTPA_MAX + 1]; struct rtnl_neightbl_parms *p = &ntbl->nt_parms; err = nla_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS], NULL); if (err < 0) goto errout; #define COPY_ENTRY(name, var) \ if (tbp[NDTPA_ ##name]) { \ p->ntp_ ##var = nla_get_u32(tbp[NDTPA_ ##name]); \ p->ntp_mask |= NEIGHTBLPARM_ATTR_ ##name; \ } COPY_ENTRY(IFINDEX, ifindex); COPY_ENTRY(REFCNT, refcnt); COPY_ENTRY(QUEUE_LEN, queue_len); COPY_ENTRY(APP_PROBES, app_probes); COPY_ENTRY(UCAST_PROBES, ucast_probes); COPY_ENTRY(MCAST_PROBES, mcast_probes); COPY_ENTRY(PROXY_QLEN, proxy_qlen); COPY_ENTRY(PROXY_DELAY, proxy_delay); COPY_ENTRY(ANYCAST_DELAY, anycast_delay); COPY_ENTRY(LOCKTIME, locktime); COPY_ENTRY(REACHABLE_TIME, reachable_time); COPY_ENTRY(BASE_REACHABLE_TIME, base_reachable_time); COPY_ENTRY(RETRANS_TIME, retrans_time); COPY_ENTRY(GC_STALETIME, gc_stale_time); COPY_ENTRY(DELAY_PROBE_TIME, probe_delay); #undef COPY_ENTRY ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } err = pp->pp_cb((struct nl_object *) ntbl, pp); errout: rtnl_neightbl_put(ntbl); return err; } static int neightbl_request_update(struct nl_cache *c, struct nl_sock *h) { return nl_rtgen_request(h, RTM_GETNEIGHTBL, AF_UNSPEC, NLM_F_DUMP); } static void neightbl_dump_line(struct nl_object *arg, struct nl_dump_params *p) { struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg; nl_dump_line(p, "%s", ntbl->nt_name); if (ntbl->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX) { struct nl_cache *link_cache; link_cache = nl_cache_mngt_require_safe("route/link"); if (link_cache) { char buf[32]; nl_dump(p, "<%s> ", rtnl_link_i2name(link_cache, ntbl->nt_parms.ntp_ifindex, buf, sizeof(buf))); nl_cache_put(link_cache); } else nl_dump(p, "<%u> ", ntbl->nt_parms.ntp_ifindex); } else nl_dump(p, " "); if (ntbl->ce_mask & NEIGHTBL_ATTR_CONFIG) nl_dump(p, "entries %u ", ntbl->nt_config.ndtc_entries); if (ntbl->ce_mask & NEIGHTBL_ATTR_PARMS) { char rt[32], rt2[32]; struct rtnl_neightbl_parms *pa = &ntbl->nt_parms; nl_dump(p, "reachable-time %s retransmit-time %s", nl_msec2str(pa->ntp_reachable_time, rt, sizeof(rt)), nl_msec2str(pa->ntp_retrans_time, rt2, sizeof(rt2))); } nl_dump(p, "\n"); } static void neightbl_dump_details(struct nl_object *arg, struct nl_dump_params *p) { char x[32], y[32], z[32]; struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg; neightbl_dump_line(arg, p); if (ntbl->ce_mask & NEIGHTBL_ATTR_CONFIG) { nl_dump_line(p, " key-len %u entry-size %u last-flush %s\n", ntbl->nt_config.ndtc_key_len, ntbl->nt_config.ndtc_entry_size, nl_msec2str(ntbl->nt_config.ndtc_last_flush, x, sizeof(x))); nl_dump_line(p, " gc threshold %u/%u/%u interval %s " \ "chain-position %u\n", ntbl->nt_gc_thresh1, ntbl->nt_gc_thresh2, ntbl->nt_gc_thresh3, nl_msec2str(ntbl->nt_gc_interval, x, sizeof(x)), ntbl->nt_config.ndtc_hash_chain_gc); nl_dump_line(p, " hash-rand 0x%08X/0x%08X last-rand %s\n", ntbl->nt_config.ndtc_hash_rnd, ntbl->nt_config.ndtc_hash_mask, nl_msec2str(ntbl->nt_config.ndtc_last_rand, x, sizeof(x))); } if (ntbl->ce_mask & NEIGHTBL_ATTR_PARMS) { struct rtnl_neightbl_parms *pa = &ntbl->nt_parms; nl_dump_line(p, " refcnt %u pending-queue-limit %u " \ "proxy-delayed-queue-limit %u\n", pa->ntp_refcnt, pa->ntp_queue_len, pa->ntp_proxy_qlen); nl_dump_line(p, " num-userspace-probes %u num-unicast-probes " \ "%u num-multicast-probes %u\n", pa->ntp_app_probes, pa->ntp_ucast_probes, pa->ntp_mcast_probes); nl_dump_line(p, " min-age %s base-reachable-time %s " \ "stale-check-interval %s\n", nl_msec2str(pa->ntp_locktime, x, sizeof(x)), nl_msec2str(pa->ntp_base_reachable_time, y, sizeof(y)), nl_msec2str(pa->ntp_gc_stale_time, z, sizeof(z))); nl_dump_line(p, " initial-probe-delay %s answer-delay %s " \ "proxy-answer-delay %s\n", nl_msec2str(pa->ntp_probe_delay, x, sizeof(x)), nl_msec2str(pa->ntp_anycast_delay, y, sizeof(y)), nl_msec2str(pa->ntp_proxy_delay, z, sizeof(z))); } } static void neightbl_dump_stats(struct nl_object *arg, struct nl_dump_params *p) { struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg; neightbl_dump_details(arg, p); if (!(ntbl->ce_mask & NEIGHTBL_ATTR_STATS)) return; nl_dump_line(p, " " \ " lookups %" PRIu64 \ " hits %" PRIu64 \ " failed %" PRIu64 \ " allocations %" PRIu64 \ " destroys %" PRIu64 \ "\n", ntbl->nt_stats.ndts_lookups, ntbl->nt_stats.ndts_hits, ntbl->nt_stats.ndts_res_failed, ntbl->nt_stats.ndts_allocs, ntbl->nt_stats.ndts_destroys); nl_dump_line(p, " " \ " hash-grows %" PRIu64 \ " forced-gc-runs %" PRIu64 \ " periodic-gc-runs %" PRIu64 \ "\n", ntbl->nt_stats.ndts_hash_grows, ntbl->nt_stats.ndts_forced_gc_runs, ntbl->nt_stats.ndts_periodic_gc_runs); nl_dump_line(p, " " \ " rcv-unicast-probes %" PRIu64 \ " rcv-multicast-probes %" PRIu64 \ "\n", ntbl->nt_stats.ndts_rcv_probes_ucast, ntbl->nt_stats.ndts_rcv_probes_mcast); } /** * @name Allocation/Freeing * @{ */ struct rtnl_neightbl *rtnl_neightbl_alloc(void) { return (struct rtnl_neightbl *) nl_object_alloc(&neightbl_obj_ops); } void rtnl_neightbl_put(struct rtnl_neightbl *neightbl) { nl_object_put((struct nl_object *) neightbl); } /** @} */ /** * @name Neighbour Table Cache Management * @{ */ /** * Build a neighbour table cache including all neighbour tables currently configured in the kernel. * @arg sk Netlink socket. * @arg result Pointer to store resulting cache. * * Allocates a new neighbour table cache, initializes it properly and * updates it to include all neighbour tables currently configured in * the kernel. * * @return 0 on success or a negative error code. */ int rtnl_neightbl_alloc_cache(struct nl_sock *sk, struct nl_cache **result) { return nl_cache_alloc_and_fill(&rtnl_neightbl_ops, sk, result); } /** * Lookup neighbour table by name and optional interface index * @arg cache neighbour table cache * @arg name name of table * @arg ifindex optional interface index * * Looks up the neighbour table matching the specified name and * optionally the specified ifindex to retrieve device specific * parameter sets. * * @return ptr to neighbour table inside the cache or NULL if no * match was found. */ struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *cache, const char *name, int ifindex) { struct rtnl_neightbl *nt; if (cache->c_ops != &rtnl_neightbl_ops) return NULL; nl_list_for_each_entry(nt, &cache->c_items, ce_list) { if (!strcasecmp(nt->nt_name, name) && ((!ifindex && !nt->nt_parms.ntp_ifindex) || (ifindex && ifindex == nt->nt_parms.ntp_ifindex))) { nl_object_get((struct nl_object *) nt); return nt; } } return NULL; } /** @} */ /** * @name Neighbour Table Modifications * @{ */ /** * Builds a netlink change request message to change neighbour table attributes * @arg old neighbour table to change * @arg tmpl template with requested changes * @arg result Pointer to store resulting message. * * Builds a new netlink message requesting a change of neighbour table * attributes. The netlink message header isn't fully equipped with all * relevant fields and must be sent out via nl_send_auto_complete() or * supplemented as needed. * \a old must point to a neighbour table currently configured in the * kernel and \a tmpl must contain the attributes to be changed set via * \c rtnl_neightbl_set_* functions. * * @return 0 on success or a negative error code. */ int rtnl_neightbl_build_change_request(struct rtnl_neightbl *old, struct rtnl_neightbl *tmpl, struct nl_msg **result) { struct nl_msg *m, *parms = NULL; struct ndtmsg ndt = { .ndtm_family = old->nt_family, }; m = nlmsg_alloc_simple(RTM_SETNEIGHTBL, 0); if (!m) return -NLE_NOMEM; if (nlmsg_append(m, &ndt, sizeof(ndt), NLMSG_ALIGNTO) < 0) goto nla_put_failure; NLA_PUT_STRING(m, NDTA_NAME, old->nt_name); if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH1) NLA_PUT_U32(m, NDTA_THRESH1, tmpl->nt_gc_thresh1); if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2) NLA_PUT_U32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2); if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2) NLA_PUT_U32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2); if (tmpl->ce_mask & NEIGHTBL_ATTR_GC_INTERVAL) NLA_PUT_U64(m, NDTA_GC_INTERVAL, tmpl->nt_gc_interval); if (tmpl->ce_mask & NEIGHTBL_ATTR_PARMS) { struct rtnl_neightbl_parms *p = &tmpl->nt_parms; parms = nlmsg_alloc(); if (!parms) goto nla_put_failure; if (old->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX) NLA_PUT_U32(parms, NDTPA_IFINDEX, old->nt_parms.ntp_ifindex); if (p->ntp_mask & NEIGHTBLPARM_ATTR_QUEUE_LEN) NLA_PUT_U32(parms, NDTPA_QUEUE_LEN, p->ntp_queue_len); if (p->ntp_mask & NEIGHTBLPARM_ATTR_APP_PROBES) NLA_PUT_U32(parms, NDTPA_APP_PROBES, p->ntp_app_probes); if (p->ntp_mask & NEIGHTBLPARM_ATTR_UCAST_PROBES) NLA_PUT_U32(parms, NDTPA_UCAST_PROBES, p->ntp_ucast_probes); if (p->ntp_mask & NEIGHTBLPARM_ATTR_MCAST_PROBES) NLA_PUT_U32(parms, NDTPA_MCAST_PROBES, p->ntp_mcast_probes); if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_QLEN) NLA_PUT_U32(parms, NDTPA_PROXY_QLEN, p->ntp_proxy_qlen); if (p->ntp_mask & NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME) NLA_PUT_U64(parms, NDTPA_BASE_REACHABLE_TIME, p->ntp_base_reachable_time); if (p->ntp_mask & NEIGHTBLPARM_ATTR_RETRANS_TIME) NLA_PUT_U64(parms, NDTPA_RETRANS_TIME, p->ntp_retrans_time); if (p->ntp_mask & NEIGHTBLPARM_ATTR_GC_STALETIME) NLA_PUT_U64(parms, NDTPA_GC_STALETIME, p->ntp_gc_stale_time); if (p->ntp_mask & NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME) NLA_PUT_U64(parms, NDTPA_DELAY_PROBE_TIME, p->ntp_proxy_delay); if (p->ntp_mask & NEIGHTBLPARM_ATTR_ANYCAST_DELAY) NLA_PUT_U64(parms, NDTPA_ANYCAST_DELAY, p->ntp_anycast_delay); if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_DELAY) NLA_PUT_U64(parms, NDTPA_PROXY_DELAY, p->ntp_proxy_delay); if (p->ntp_mask & NEIGHTBLPARM_ATTR_LOCKTIME) NLA_PUT_U64(parms, NDTPA_LOCKTIME, p->ntp_locktime); if (nla_put_nested(m, NDTA_PARMS, parms) < 0) goto nla_put_failure; nlmsg_free(parms); } *result = m; return 0; nla_put_failure: if (parms) nlmsg_free(parms); nlmsg_free(m); return -NLE_MSGSIZE; } /** * Change neighbour table attributes * @arg sk Netlink socket. * @arg old neighbour table to be changed * @arg tmpl template with requested changes * * Builds a new netlink message by calling * rtnl_neightbl_build_change_request(), sends the request to the * kernel and waits for the next ACK to be received, i.e. blocks * until the request has been processed. * * @return 0 on success or a negative error code */ int rtnl_neightbl_change(struct nl_sock *sk, struct rtnl_neightbl *old, struct rtnl_neightbl *tmpl) { struct nl_msg *msg; int err; if ((err = rtnl_neightbl_build_change_request(old, tmpl, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ /** * @name Attribute Modification * @{ */ void rtnl_neightbl_set_family(struct rtnl_neightbl *ntbl, int family) { ntbl->nt_family = family; ntbl->ce_mask |= NEIGHTBL_ATTR_FAMILY; } void rtnl_neightbl_set_gc_interval(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_gc_interval = ms; ntbl->ce_mask |= NEIGHTBL_ATTR_GC_INTERVAL; } void rtnl_neightbl_set_gc_tresh1(struct rtnl_neightbl *ntbl, int thresh) { ntbl->nt_gc_thresh1 = thresh; ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH1; } void rtnl_neightbl_set_gc_tresh2(struct rtnl_neightbl *ntbl, int thresh) { ntbl->nt_gc_thresh2 = thresh; ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH2; } void rtnl_neightbl_set_gc_tresh3(struct rtnl_neightbl *ntbl, int thresh) { ntbl->nt_gc_thresh3 = thresh; ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH3; } void rtnl_neightbl_set_name(struct rtnl_neightbl *ntbl, const char *name) { strncpy(ntbl->nt_name, name, sizeof(ntbl->nt_name) - 1); ntbl->ce_mask |= NEIGHTBL_ATTR_NAME; } void rtnl_neightbl_set_dev(struct rtnl_neightbl *ntbl, int ifindex) { ntbl->nt_parms.ntp_ifindex = ifindex; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_IFINDEX; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the queue length for pending requests of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg len new queue len */ void rtnl_neightbl_set_queue_len(struct rtnl_neightbl *ntbl, int len) { ntbl->nt_parms.ntp_queue_len = len; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_QUEUE_LEN; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the queue length for delay proxy arp requests of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg len new queue len */ void rtnl_neightbl_set_proxy_queue_len(struct rtnl_neightbl *ntbl, int len) { ntbl->nt_parms.ntp_proxy_qlen = len; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_PROXY_QLEN; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the number of application probes of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg probes new probes value */ void rtnl_neightbl_set_app_probes(struct rtnl_neightbl *ntbl, int probes) { ntbl->nt_parms.ntp_app_probes = probes; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_APP_PROBES; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the number of unicast probes of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg probes new probes value */ void rtnl_neightbl_set_ucast_probes(struct rtnl_neightbl *ntbl, int probes) { ntbl->nt_parms.ntp_ucast_probes = probes; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_UCAST_PROBES; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the number of multicast probes of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg probes new probes value */ void rtnl_neightbl_set_mcast_probes(struct rtnl_neightbl *ntbl, int probes) { ntbl->nt_parms.ntp_mcast_probes = probes; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_MCAST_PROBES; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the base reachable time of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg ms new base reachable time in milliseconds */ void rtnl_neightbl_set_base_reachable_time(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_parms.ntp_base_reachable_time = ms; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the retransmit time of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg ms new retransmit time */ void rtnl_neightbl_set_retrans_time(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_parms.ntp_retrans_time = ms; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_RETRANS_TIME; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the gc stale time of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg ms new gc stale time in milliseconds */ void rtnl_neightbl_set_gc_stale_time(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_parms.ntp_gc_stale_time = ms; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_GC_STALETIME; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the first probe delay time of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg ms new first probe delay time in milliseconds */ void rtnl_neightbl_set_delay_probe_time(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_parms.ntp_probe_delay = ms; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the anycast delay of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg ms new anycast delay in milliseconds */ void rtnl_neightbl_set_anycast_delay(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_parms.ntp_anycast_delay = ms; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_ANYCAST_DELAY; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the proxy delay of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg ms new proxy delay in milliseconds */ void rtnl_neightbl_set_proxy_delay(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_parms.ntp_proxy_delay = ms; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_PROXY_DELAY; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** * Set the locktime of a neighbour table to the specified value * @arg ntbl neighbour table to change * @arg ms new locktime in milliseconds */ void rtnl_neightbl_set_locktime(struct rtnl_neightbl *ntbl, uint64_t ms) { ntbl->nt_parms.ntp_locktime = ms; ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_LOCKTIME; ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS; } /** @} */ static struct nl_object_ops neightbl_obj_ops = { .oo_name = "route/neightbl", .oo_size = sizeof(struct rtnl_neightbl), .oo_dump = { [NL_DUMP_LINE] = neightbl_dump_line, [NL_DUMP_DETAILS] = neightbl_dump_details, [NL_DUMP_STATS] = neightbl_dump_stats, }, .oo_compare = neightbl_compare, }; static struct nl_cache_ops rtnl_neightbl_ops = { .co_name = "route/neightbl", .co_hdrsize = sizeof(struct rtgenmsg), .co_msgtypes = { { RTM_NEWNEIGHTBL, NL_ACT_NEW, "new" }, { RTM_SETNEIGHTBL, NL_ACT_SET, "set" }, { RTM_GETNEIGHTBL, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_request_update = neightbl_request_update, .co_msg_parser = neightbl_msg_parser, .co_obj_ops = &neightbl_obj_ops, }; static void __init neightbl_init(void) { nl_cache_mngt_register(&rtnl_neightbl_ops); } static void __exit neightbl_exit(void) { nl_cache_mngt_unregister(&rtnl_neightbl_ops); } /** @} */ libnl-3.2.29/lib/route/link.c0000644000175000017500000024461513024561717012657 00000000000000/* * lib/route/link.c Links (Interfaces) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup rtnl * @defgroup link Links (Interfaces) * * @details * @route_doc{route_link, Link Documentation} * @{ */ #include #include #include #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define LINK_ATTR_MTU (1 << 0) #define LINK_ATTR_LINK (1 << 1) #define LINK_ATTR_TXQLEN (1 << 2) #define LINK_ATTR_WEIGHT (1 << 3) #define LINK_ATTR_MASTER (1 << 4) #define LINK_ATTR_QDISC (1 << 5) #define LINK_ATTR_MAP (1 << 6) #define LINK_ATTR_ADDR (1 << 7) #define LINK_ATTR_BRD (1 << 8) #define LINK_ATTR_FLAGS (1 << 9) #define LINK_ATTR_IFNAME (1 << 10) #define LINK_ATTR_IFINDEX (1 << 11) #define LINK_ATTR_FAMILY (1 << 12) #define LINK_ATTR_ARPTYPE (1 << 13) #define LINK_ATTR_STATS (1 << 14) #define LINK_ATTR_CHANGE (1 << 15) #define LINK_ATTR_OPERSTATE (1 << 16) #define LINK_ATTR_LINKMODE (1 << 17) #define LINK_ATTR_LINKINFO (1 << 18) #define LINK_ATTR_IFALIAS (1 << 19) #define LINK_ATTR_NUM_VF (1 << 20) #define LINK_ATTR_PROMISCUITY (1 << 21) #define LINK_ATTR_NUM_TX_QUEUES (1 << 22) #define LINK_ATTR_NUM_RX_QUEUES (1 << 23) #define LINK_ATTR_GROUP (1 << 24) #define LINK_ATTR_CARRIER (1 << 25) #define LINK_ATTR_PROTINFO (1 << 26) #define LINK_ATTR_AF_SPEC (1 << 27) #define LINK_ATTR_PHYS_PORT_ID (1 << 28) #define LINK_ATTR_NS_FD (1 << 29) #define LINK_ATTR_NS_PID (1 << 30) /* 31 used by 32-bit api */ #define LINK_ATTR_LINK_NETNSID ((uint64_t) 1 << 32) #define LINK_ATTR_VF_LIST ((uint64_t) 1 << 33) #define LINK_ATTR_CARRIER_CHANGES ((uint64_t) 1 << 34) #define LINK_ATTR_PHYS_PORT_NAME ((uint64_t) 1 << 35) #define LINK_ATTR_PHYS_SWITCH_ID ((uint64_t) 1 << 36) #define LINK_ATTR_GSO_MAX_SEGS ((uint64_t) 1 << 37) #define LINK_ATTR_GSO_MAX_SIZE ((uint64_t) 1 << 38) static struct nl_cache_ops rtnl_link_ops; static struct nl_object_ops link_obj_ops; /** @endcond */ struct rtnl_link *link_lookup(struct nl_cache *cache, int ifindex) { if (!cache) { cache = __nl_cache_mngt_require("route/link"); if (!cache) return NULL; } return rtnl_link_get(cache, ifindex); } static struct rtnl_link_af_ops *af_lookup_and_alloc(struct rtnl_link *link, int family) { struct rtnl_link_af_ops *af_ops; void *data; af_ops = rtnl_link_af_ops_lookup(family); if (!af_ops) return NULL; if (!(data = rtnl_link_af_alloc(link, af_ops))) { rtnl_link_af_ops_put(af_ops); return NULL; } return af_ops; } static int af_free(struct rtnl_link *link, struct rtnl_link_af_ops *ops, void *data, void *arg) { if (ops->ao_free) ops->ao_free(link, data); rtnl_link_af_ops_put(ops); return 0; } static int af_request_type(int af_type) { struct rtnl_link_af_ops *ops; ops = rtnl_link_af_ops_lookup(af_type); if (ops && ops->ao_override_rtm) return RTM_SETLINK; return RTM_NEWLINK; } static int af_clone(struct rtnl_link *link, struct rtnl_link_af_ops *ops, void *data, void *arg) { struct rtnl_link *dst = arg; if (ops->ao_clone && !(dst->l_af_data[ops->ao_family] = ops->ao_clone(dst, data))) return -NLE_NOMEM; return 0; } static int af_fill(struct rtnl_link *link, struct rtnl_link_af_ops *ops, void *data, void *arg) { struct nl_msg *msg = arg; struct nlattr *af_attr = NULL; int err; if (!ops->ao_fill_af) return 0; if (!ops->ao_fill_af_no_nest) if (!(af_attr = nla_nest_start(msg, ops->ao_family))) return -NLE_MSGSIZE; if ((err = ops->ao_fill_af(link, arg, data)) < 0) return err; if (!ops->ao_fill_af_no_nest) nla_nest_end(msg, af_attr); return 0; } static int af_fill_pi(struct rtnl_link *link, struct rtnl_link_af_ops *ops, void *data, void *arg) { struct nl_msg *msg = arg; struct nlattr *pi_attr; int err, pi_type = IFLA_PROTINFO; if (!ops->ao_fill_pi) return 0; if (ops->ao_fill_pi_flags > 0) pi_type |= ops->ao_fill_pi_flags; if (!(pi_attr = nla_nest_start(msg, pi_type))) return -NLE_MSGSIZE; if ((err = ops->ao_fill_pi(link, arg, data)) < 0) return err; nla_nest_end(msg, pi_attr); return 0; } static int af_dump_line(struct rtnl_link *link, struct rtnl_link_af_ops *ops, void *data, void *arg) { struct nl_dump_params *p = arg; if (ops->ao_dump[NL_DUMP_LINE]) ops->ao_dump[NL_DUMP_LINE](link, p, data); return 0; } static int af_dump_details(struct rtnl_link *link, struct rtnl_link_af_ops *ops, void *data, void *arg) { struct nl_dump_params *p = arg; if (ops->ao_dump[NL_DUMP_DETAILS]) ops->ao_dump[NL_DUMP_DETAILS](link, p, data); return 0; } static int af_dump_stats(struct rtnl_link *link, struct rtnl_link_af_ops *ops, void *data, void *arg) { struct nl_dump_params *p = arg; if (ops->ao_dump[NL_DUMP_STATS]) ops->ao_dump[NL_DUMP_STATS](link, p, data); return 0; } static int do_foreach_af(struct rtnl_link *link, int (*cb)(struct rtnl_link *, struct rtnl_link_af_ops *, void *, void *), void *arg) { int i, err; for (i = 0; i < AF_MAX; i++) { if (link->l_af_data[i]) { struct rtnl_link_af_ops *ops; if (!(ops = rtnl_link_af_ops_lookup(i))) BUG(); err = cb(link, ops, link->l_af_data[i], arg); rtnl_link_af_ops_put(ops); if (err < 0) return err; } } return 0; } static void release_link_info(struct rtnl_link *link) { struct rtnl_link_info_ops *io = link->l_info_ops; if (io != NULL) { if (io->io_free) io->io_free(link); else { /* Catch missing io_free() implementations */ BUG_ON(link->l_info); } rtnl_link_info_ops_put(io); link->l_info_ops = NULL; } } static void link_free_data(struct nl_object *c) { struct rtnl_link *link = nl_object_priv(c); if (link) { release_link_info(link); /* proto info af reference */ rtnl_link_af_ops_put(link->l_af_ops); nl_addr_put(link->l_addr); nl_addr_put(link->l_bcast); free(link->l_ifalias); free(link->l_info_kind); do_foreach_af(link, af_free, NULL); nl_data_free(link->l_phys_port_id); nl_data_free(link->l_phys_switch_id); if (link->ce_mask & LINK_ATTR_VF_LIST) rtnl_link_sriov_free_data(link); } } static int link_clone(struct nl_object *_dst, struct nl_object *_src) { struct rtnl_link *dst = nl_object_priv(_dst); struct rtnl_link *src = nl_object_priv(_src); int err; if (src->l_addr) if (!(dst->l_addr = nl_addr_clone(src->l_addr))) return -NLE_NOMEM; if (src->l_bcast) if (!(dst->l_bcast = nl_addr_clone(src->l_bcast))) return -NLE_NOMEM; if (src->l_ifalias) if (!(dst->l_ifalias = strdup(src->l_ifalias))) return -NLE_NOMEM; if (src->l_info_kind) if (!(dst->l_info_kind = strdup(src->l_info_kind))) return -NLE_NOMEM; if (src->l_info_ops && src->l_info_ops->io_clone) { err = src->l_info_ops->io_clone(dst, src); if (err < 0) return err; } if ((err = do_foreach_af(src, af_clone, dst)) < 0) return err; if (src->l_phys_port_id) if (!(dst->l_phys_port_id = nl_data_clone(src->l_phys_port_id))) return -NLE_NOMEM; if (src->l_phys_switch_id) if (!(dst->l_phys_switch_id = nl_data_clone(src->l_phys_switch_id))) return -NLE_NOMEM; if (src->ce_mask & LINK_ATTR_VF_LIST) if ((err = rtnl_link_sriov_clone(dst, src)) < 0) return err; return 0; } struct nla_policy rtln_link_policy[IFLA_MAX+1] = { [IFLA_IFNAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [IFLA_MTU] = { .type = NLA_U32 }, [IFLA_TXQLEN] = { .type = NLA_U32 }, [IFLA_LINK] = { .type = NLA_U32 }, [IFLA_WEIGHT] = { .type = NLA_U32 }, [IFLA_MASTER] = { .type = NLA_U32 }, [IFLA_OPERSTATE] = { .type = NLA_U8 }, [IFLA_LINKMODE] = { .type = NLA_U8 }, [IFLA_LINKINFO] = { .type = NLA_NESTED }, [IFLA_QDISC] = { .type = NLA_STRING, .maxlen = IFQDISCSIZ }, [IFLA_STATS] = { .minlen = _nl_offsetofend (struct rtnl_link_stats, tx_compressed) }, [IFLA_STATS64] = { .minlen = _nl_offsetofend (struct rtnl_link_stats64, tx_compressed) }, [IFLA_MAP] = { .minlen = sizeof(struct rtnl_link_ifmap) }, [IFLA_IFALIAS] = { .type = NLA_STRING, .maxlen = IFALIASZ }, [IFLA_NUM_VF] = { .type = NLA_U32 }, [IFLA_VFINFO_LIST] = { .type = NLA_NESTED }, [IFLA_AF_SPEC] = { .type = NLA_NESTED }, [IFLA_PROMISCUITY] = { .type = NLA_U32 }, [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 }, [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 }, [IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 }, [IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 }, [IFLA_GROUP] = { .type = NLA_U32 }, [IFLA_CARRIER] = { .type = NLA_U8 }, [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, [IFLA_PHYS_PORT_ID] = { .type = NLA_UNSPEC }, [IFLA_PHYS_PORT_NAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [IFLA_PHYS_SWITCH_ID] = { .type = NLA_UNSPEC }, [IFLA_NET_NS_PID] = { .type = NLA_U32 }, [IFLA_NET_NS_FD] = { .type = NLA_U32 }, }; static struct nla_policy link_info_policy[IFLA_INFO_MAX+1] = { [IFLA_INFO_KIND] = { .type = NLA_STRING }, [IFLA_INFO_DATA] = { .type = NLA_NESTED }, [IFLA_INFO_XSTATS] = { .type = NLA_NESTED }, }; int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb) { if (tb[IFLA_IFNAME] == NULL) return -NLE_MISSING_ATTR; nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ); if (tb[IFLA_STATS]) { struct rtnl_link_stats *st = nla_data(tb[IFLA_STATS]); link->l_stats[RTNL_LINK_RX_PACKETS] = st->rx_packets; link->l_stats[RTNL_LINK_TX_PACKETS] = st->tx_packets; link->l_stats[RTNL_LINK_RX_BYTES] = st->rx_bytes; link->l_stats[RTNL_LINK_TX_BYTES] = st->tx_bytes; link->l_stats[RTNL_LINK_RX_ERRORS] = st->rx_errors; link->l_stats[RTNL_LINK_TX_ERRORS] = st->tx_errors; link->l_stats[RTNL_LINK_RX_DROPPED] = st->rx_dropped; link->l_stats[RTNL_LINK_TX_DROPPED] = st->tx_dropped; link->l_stats[RTNL_LINK_MULTICAST] = st->multicast; link->l_stats[RTNL_LINK_COLLISIONS] = st->collisions; link->l_stats[RTNL_LINK_RX_LEN_ERR] = st->rx_length_errors; link->l_stats[RTNL_LINK_RX_OVER_ERR] = st->rx_over_errors; link->l_stats[RTNL_LINK_RX_CRC_ERR] = st->rx_crc_errors; link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st->rx_frame_errors; link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st->rx_fifo_errors; link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st->rx_missed_errors; link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st->tx_aborted_errors; link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st->tx_carrier_errors; link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st->tx_fifo_errors; link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st->tx_heartbeat_errors; link->l_stats[RTNL_LINK_TX_WIN_ERR] = st->tx_window_errors; link->l_stats[RTNL_LINK_RX_COMPRESSED] = st->rx_compressed; link->l_stats[RTNL_LINK_TX_COMPRESSED] = st->tx_compressed; /* beware: @st might not be the full struct, only fields up to * tx_compressed are present. See _nl_offsetofend() above. */ if (nla_len(tb[IFLA_STATS]) >= _nl_offsetofend (struct rtnl_link_stats, rx_nohandler)) link->l_stats[RTNL_LINK_RX_NOHANDLER] = st->rx_nohandler; else link->l_stats[RTNL_LINK_RX_NOHANDLER] = 0; link->ce_mask |= LINK_ATTR_STATS; } if (tb[IFLA_STATS64]) { /* * This structure contains 64bit parameters, and per the * documentation in lib/attr.c, must not be accessed * directly (because of alignment to 4 instead of 8). * Therefore, copy the data to the stack and access it from * there, where it will be aligned to 8. */ struct rtnl_link_stats64 st = { 0 }; nla_memcpy(&st, tb[IFLA_STATS64], sizeof (st)); link->l_stats[RTNL_LINK_RX_PACKETS] = st.rx_packets; link->l_stats[RTNL_LINK_TX_PACKETS] = st.tx_packets; link->l_stats[RTNL_LINK_RX_BYTES] = st.rx_bytes; link->l_stats[RTNL_LINK_TX_BYTES] = st.tx_bytes; link->l_stats[RTNL_LINK_RX_ERRORS] = st.rx_errors; link->l_stats[RTNL_LINK_TX_ERRORS] = st.tx_errors; link->l_stats[RTNL_LINK_RX_DROPPED] = st.rx_dropped; link->l_stats[RTNL_LINK_TX_DROPPED] = st.tx_dropped; link->l_stats[RTNL_LINK_MULTICAST] = st.multicast; link->l_stats[RTNL_LINK_COLLISIONS] = st.collisions; link->l_stats[RTNL_LINK_RX_LEN_ERR] = st.rx_length_errors; link->l_stats[RTNL_LINK_RX_OVER_ERR] = st.rx_over_errors; link->l_stats[RTNL_LINK_RX_CRC_ERR] = st.rx_crc_errors; link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st.rx_frame_errors; link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st.rx_fifo_errors; link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st.rx_missed_errors; link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st.tx_aborted_errors; link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st.tx_carrier_errors; link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st.tx_fifo_errors; link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st.tx_heartbeat_errors; link->l_stats[RTNL_LINK_TX_WIN_ERR] = st.tx_window_errors; link->l_stats[RTNL_LINK_RX_COMPRESSED] = st.rx_compressed; link->l_stats[RTNL_LINK_TX_COMPRESSED] = st.tx_compressed; /* beware: @st might not be the full struct, only fields up to * tx_compressed are present. See _nl_offsetofend() above. */ link->l_stats[RTNL_LINK_RX_NOHANDLER] = st.rx_nohandler; link->ce_mask |= LINK_ATTR_STATS; } if (tb[IFLA_TXQLEN]) { link->l_txqlen = nla_get_u32(tb[IFLA_TXQLEN]); link->ce_mask |= LINK_ATTR_TXQLEN; } if (tb[IFLA_MTU]) { link->l_mtu = nla_get_u32(tb[IFLA_MTU]); link->ce_mask |= LINK_ATTR_MTU; } if (tb[IFLA_ADDRESS]) { link->l_addr = nl_addr_alloc_attr(tb[IFLA_ADDRESS], AF_UNSPEC); if (link->l_addr == NULL) return -NLE_NOMEM; nl_addr_set_family(link->l_addr, nl_addr_guess_family(link->l_addr)); link->ce_mask |= LINK_ATTR_ADDR; } if (tb[IFLA_BROADCAST]) { link->l_bcast = nl_addr_alloc_attr(tb[IFLA_BROADCAST], AF_UNSPEC); if (link->l_bcast == NULL) return -NLE_NOMEM; nl_addr_set_family(link->l_bcast, nl_addr_guess_family(link->l_bcast)); link->ce_mask |= LINK_ATTR_BRD; } if (tb[IFLA_LINK]) { link->l_link = nla_get_u32(tb[IFLA_LINK]); link->ce_mask |= LINK_ATTR_LINK; } if (tb[IFLA_LINK_NETNSID]) { link->l_link_netnsid = nla_get_s32(tb[IFLA_LINK_NETNSID]); link->ce_mask |= LINK_ATTR_LINK_NETNSID; } if (tb[IFLA_WEIGHT]) { link->l_weight = nla_get_u32(tb[IFLA_WEIGHT]); link->ce_mask |= LINK_ATTR_WEIGHT; } if (tb[IFLA_QDISC]) { nla_strlcpy(link->l_qdisc, tb[IFLA_QDISC], IFQDISCSIZ); link->ce_mask |= LINK_ATTR_QDISC; } if (tb[IFLA_MAP]) { nla_memcpy(&link->l_map, tb[IFLA_MAP], sizeof(struct rtnl_link_ifmap)); link->ce_mask |= LINK_ATTR_MAP; } if (tb[IFLA_MASTER]) { link->l_master = nla_get_u32(tb[IFLA_MASTER]); link->ce_mask |= LINK_ATTR_MASTER; } if (tb[IFLA_CARRIER]) { link->l_carrier = nla_get_u8(tb[IFLA_CARRIER]); link->ce_mask |= LINK_ATTR_CARRIER; } if (tb[IFLA_CARRIER_CHANGES]) { link->l_carrier_changes = nla_get_u32(tb[IFLA_CARRIER_CHANGES]); link->ce_mask |= LINK_ATTR_CARRIER_CHANGES; } if (tb[IFLA_OPERSTATE]) { link->l_operstate = nla_get_u8(tb[IFLA_OPERSTATE]); link->ce_mask |= LINK_ATTR_OPERSTATE; } if (tb[IFLA_LINKMODE]) { link->l_linkmode = nla_get_u8(tb[IFLA_LINKMODE]); link->ce_mask |= LINK_ATTR_LINKMODE; } if (tb[IFLA_IFALIAS]) { link->l_ifalias = nla_strdup(tb[IFLA_IFALIAS]); if (link->l_ifalias == NULL) return -NLE_NOMEM; link->ce_mask |= LINK_ATTR_IFALIAS; } if (tb[IFLA_NET_NS_FD]) { link->l_ns_fd = nla_get_u32(tb[IFLA_NET_NS_FD]); link->ce_mask |= LINK_ATTR_NS_FD; } if (tb[IFLA_NET_NS_PID]) { link->l_ns_pid = nla_get_u32(tb[IFLA_NET_NS_PID]); link->ce_mask |= LINK_ATTR_NS_PID; } return 0; } static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct rtnl_link *link; struct ifinfomsg *ifi; struct nlattr *tb[IFLA_MAX+1]; struct rtnl_link_af_ops *af_ops = NULL; struct rtnl_link_af_ops *af_ops_family; int err, family; struct nla_policy real_link_policy[IFLA_MAX+1]; memcpy(&real_link_policy, rtln_link_policy, sizeof(rtln_link_policy)); link = rtnl_link_alloc(); if (link == NULL) { err = -NLE_NOMEM; goto errout; } link->ce_msgtype = n->nlmsg_type; if (!nlmsg_valid_hdr(n, sizeof(*ifi))) { err = -NLE_MSG_TOOSHORT; goto errout; } ifi = nlmsg_data(n); link->l_family = family = ifi->ifi_family; link->l_arptype = ifi->ifi_type; link->l_index = ifi->ifi_index; link->l_flags = ifi->ifi_flags; link->l_change = ifi->ifi_change; link->ce_mask = (LINK_ATTR_IFNAME | LINK_ATTR_FAMILY | LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX | LINK_ATTR_FLAGS | LINK_ATTR_CHANGE); if ((af_ops_family = af_ops = af_lookup_and_alloc(link, family))) { if (af_ops->ao_protinfo_policy) { memcpy(&real_link_policy[IFLA_PROTINFO], af_ops->ao_protinfo_policy, sizeof(struct nla_policy)); } link->l_af_ops = af_ops; } err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, real_link_policy); if (err < 0) goto errout; err = rtnl_link_info_parse(link, tb); if (err < 0) goto errout; if (tb[IFLA_NUM_VF]) { link->l_num_vf = nla_get_u32(tb[IFLA_NUM_VF]); link->ce_mask |= LINK_ATTR_NUM_VF; if (link->l_num_vf && tb[IFLA_VFINFO_LIST]) { if ((err = rtnl_link_sriov_parse_vflist(link, tb)) < 0) { goto errout; } link->ce_mask |= LINK_ATTR_VF_LIST; } } if (tb[IFLA_LINKINFO]) { struct nlattr *li[IFLA_INFO_MAX+1]; err = nla_parse_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO], link_info_policy); if (err < 0) goto errout; if (li[IFLA_INFO_KIND]) { struct rtnl_link_info_ops *ops; char *kind = nla_get_string(li[IFLA_INFO_KIND]); int af; err = rtnl_link_set_type(link, kind); if (err < 0) goto errout; if ((af = nl_str2af(kind)) >= 0 && !af_ops && (af_ops = af_lookup_and_alloc(link, af))) { if (af_ops->ao_protinfo_policy) { tb[IFLA_PROTINFO] = (struct nlattr *)af_ops->ao_protinfo_policy; } link->l_family = af; link->l_af_ops = af_ops; } ops = rtnl_link_info_ops_lookup(kind); link->l_info_ops = ops; if (ops) { if (ops->io_parse && (li[IFLA_INFO_DATA] || li[IFLA_INFO_XSTATS])) { err = ops->io_parse(link, li[IFLA_INFO_DATA], li[IFLA_INFO_XSTATS]); if (err < 0) goto errout; } else { /* XXX: Warn about unparsed info? */ } } } link->ce_mask |= LINK_ATTR_LINKINFO; } if (tb[IFLA_PROTINFO] && af_ops && af_ops->ao_parse_protinfo) { err = af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO], link->l_af_data[link->l_family]); if (err < 0) goto errout; link->ce_mask |= LINK_ATTR_PROTINFO; } if (tb[IFLA_AF_SPEC]) { /* parsing of IFLA_AF_SPEC is dependent on the family used * in the request message. */ if (af_ops_family && af_ops_family->ao_parse_af_full) { err = af_ops_family->ao_parse_af_full(link, tb[IFLA_AF_SPEC], link->l_af_data[af_ops_family->ao_family]); if (err < 0) goto errout; link->ce_mask |= LINK_ATTR_AF_SPEC; } else if (family == AF_UNSPEC) { struct nlattr *af_attr; int remaining; nla_for_each_nested(af_attr, tb[IFLA_AF_SPEC], remaining) { af_ops = af_lookup_and_alloc(link, nla_type(af_attr)); if (af_ops && af_ops->ao_parse_af) { char *af_data = link->l_af_data[nla_type(af_attr)]; err = af_ops->ao_parse_af(link, af_attr, af_data); if (err < 0) goto errout; } } link->ce_mask |= LINK_ATTR_AF_SPEC; } else { NL_DBG(3, "IFLA_AF_SPEC parsing not implemented for family %d\n", family); } } if (tb[IFLA_PROMISCUITY]) { link->l_promiscuity = nla_get_u32(tb[IFLA_PROMISCUITY]); link->ce_mask |= LINK_ATTR_PROMISCUITY; } if (tb[IFLA_NUM_TX_QUEUES]) { link->l_num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]); link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES; } if (tb[IFLA_NUM_RX_QUEUES]) { link->l_num_rx_queues = nla_get_u32(tb[IFLA_NUM_RX_QUEUES]); link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES; } if (tb[IFLA_GSO_MAX_SEGS]) { link->l_gso_max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]); link->ce_mask |= LINK_ATTR_GSO_MAX_SEGS; } if (tb[IFLA_GSO_MAX_SIZE]) { link->l_gso_max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]); link->ce_mask |= LINK_ATTR_GSO_MAX_SIZE; } if (tb[IFLA_GROUP]) { link->l_group = nla_get_u32(tb[IFLA_GROUP]); link->ce_mask |= LINK_ATTR_GROUP; } if (tb[IFLA_PHYS_PORT_ID]) { link->l_phys_port_id = nl_data_alloc_attr(tb[IFLA_PHYS_PORT_ID]); if (link->l_phys_port_id == NULL) { err = -NLE_NOMEM; goto errout; } link->ce_mask |= LINK_ATTR_PHYS_PORT_ID; } if (tb[IFLA_PHYS_PORT_NAME]) { nla_strlcpy(link->l_phys_port_name, tb[IFLA_PHYS_PORT_NAME], IFNAMSIZ); link->ce_mask |= LINK_ATTR_PHYS_PORT_NAME; } if (tb[IFLA_PHYS_SWITCH_ID]) { link->l_phys_switch_id = nl_data_alloc_attr(tb[IFLA_PHYS_SWITCH_ID]); if (link->l_phys_switch_id == NULL) { err = -NLE_NOMEM; goto errout; } link->ce_mask |= LINK_ATTR_PHYS_SWITCH_ID; } err = pp->pp_cb((struct nl_object *) link, pp); errout: rtnl_link_af_ops_put(af_ops); rtnl_link_put(link); return err; } static int link_request_update(struct nl_cache *cache, struct nl_sock *sk) { int family = cache->c_iarg1; struct ifinfomsg hdr = { .ifi_family = family }; struct rtnl_link_af_ops *ops; struct nl_msg *msg; int err; __u32 ext_filter_mask = RTEXT_FILTER_VF; msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP); if (!msg) return -NLE_NOMEM; err = -NLE_MSGSIZE; if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0) goto nla_put_failure; ops = rtnl_link_af_ops_lookup(family); if (ops && ops->ao_get_af) { err = ops->ao_get_af(msg, &ext_filter_mask); if (err) goto nla_put_failure; } if (ext_filter_mask) { err = nla_put(msg, IFLA_EXT_MASK, sizeof(ext_filter_mask), &ext_filter_mask); if (err) goto nla_put_failure; } err = nl_send_auto(sk, msg); if (err > 0) err = 0; nla_put_failure: nlmsg_free(msg); return err; } static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) { char buf[128]; struct nl_cache *cache = obj->ce_cache; struct rtnl_link *link = (struct rtnl_link *) obj; int fetched_cache = 0; if (!cache) { cache = nl_cache_mngt_require_safe("route/link"); fetched_cache = 1; } nl_dump_line(p, "%s %s ", link->l_name, nl_llproto2str(link->l_arptype, buf, sizeof(buf))); if (link->l_addr && !nl_addr_iszero(link->l_addr)) nl_dump(p, "%s ", nl_addr2str(link->l_addr, buf, sizeof(buf))); if (link->ce_mask & LINK_ATTR_MASTER) { if (cache) { struct rtnl_link *master = rtnl_link_get(cache, link->l_master); nl_dump(p, "master %s ", master ? master->l_name : "inv"); if (master) rtnl_link_put(master); } else nl_dump(p, "master %d ", link->l_master); } rtnl_link_flags2str(link->l_flags, buf, sizeof(buf)); if (buf[0]) nl_dump(p, "<%s> ", buf); if (link->ce_mask & LINK_ATTR_LINK) { if ( cache && !(link->ce_mask & LINK_ATTR_LINK_NETNSID)) { struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE"); if (ll) rtnl_link_put(ll); } else nl_dump(p, "slave-of %d ", link->l_link); } if (link->ce_mask & LINK_ATTR_LINK_NETNSID) nl_dump(p, "link-netnsid %d ", link->l_link_netnsid); if (link->ce_mask & LINK_ATTR_GROUP) nl_dump(p, "group %u ", link->l_group); if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_LINE]) link->l_info_ops->io_dump[NL_DUMP_LINE](link, p); do_foreach_af(link, af_dump_line, p); nl_dump(p, "\n"); if (fetched_cache) nl_cache_put(cache); } static void link_dump_details(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_link *link = (struct rtnl_link *) obj; char buf[64]; link_dump_line(obj, p); nl_dump_line(p, " mtu %u ", link->l_mtu); nl_dump(p, "txqlen %u weight %u ", link->l_txqlen, link->l_weight); if (link->ce_mask & LINK_ATTR_QDISC) nl_dump(p, "qdisc %s ", link->l_qdisc); if (link->ce_mask & LINK_ATTR_MAP && link->l_map.lm_irq) nl_dump(p, "irq %u ", link->l_map.lm_irq); if (link->ce_mask & LINK_ATTR_IFINDEX) nl_dump(p, "index %u ", link->l_index); if (link->ce_mask & LINK_ATTR_PROMISCUITY && link->l_promiscuity > 0) nl_dump(p, "promisc-mode (%u users) ", link->l_promiscuity); nl_dump(p, "\n"); if (link->ce_mask & LINK_ATTR_IFALIAS) nl_dump_line(p, " alias %s\n", link->l_ifalias); nl_dump_line(p, " "); if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES) nl_dump(p, "txq %u ", link->l_num_tx_queues); if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES) nl_dump(p, "rxq %u ", link->l_num_rx_queues); if (link->ce_mask & LINK_ATTR_BRD) nl_dump(p, "brd %s ", nl_addr2str(link->l_bcast, buf, sizeof(buf))); if ((link->ce_mask & LINK_ATTR_OPERSTATE) && link->l_operstate != IF_OPER_UNKNOWN) { rtnl_link_operstate2str(link->l_operstate, buf, sizeof(buf)); nl_dump(p, "state %s ", buf); } if (link->ce_mask & LINK_ATTR_NUM_VF) nl_dump(p, "num-vf %u ", link->l_num_vf); nl_dump(p, "mode %s ", rtnl_link_mode2str(link->l_linkmode, buf, sizeof(buf))); nl_dump(p, "carrier %s", rtnl_link_carrier2str(link->l_carrier, buf, sizeof(buf))); if (link->ce_mask & LINK_ATTR_CARRIER_CHANGES) nl_dump(p, " carrier-changes %u", link->l_carrier_changes); nl_dump(p, "\n"); if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_DETAILS]) link->l_info_ops->io_dump[NL_DUMP_DETAILS](link, p); do_foreach_af(link, af_dump_details, p); if (link->ce_mask & LINK_ATTR_VF_LIST) rtnl_link_sriov_dump_details(link, p); } static void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_link *link = (struct rtnl_link *) obj; char *unit, fmt[64]; float res; link_dump_details(obj, p); nl_dump_line(p, " Stats: bytes packets errors " " dropped fifo-err compressed\n"); res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_RX_BYTES], &unit); strcpy(fmt, " RX %X.2f %s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n"); fmt[9] = *unit == 'B' ? '9' : '7'; nl_dump_line(p, fmt, res, unit, link->l_stats[RTNL_LINK_RX_PACKETS], link->l_stats[RTNL_LINK_RX_ERRORS], link->l_stats[RTNL_LINK_RX_DROPPED], link->l_stats[RTNL_LINK_RX_FIFO_ERR], link->l_stats[RTNL_LINK_RX_COMPRESSED]); res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_TX_BYTES], &unit); strcpy(fmt, " TX %X.2f %s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n"); fmt[9] = *unit == 'B' ? '9' : '7'; nl_dump_line(p, fmt, res, unit, link->l_stats[RTNL_LINK_TX_PACKETS], link->l_stats[RTNL_LINK_TX_ERRORS], link->l_stats[RTNL_LINK_TX_DROPPED], link->l_stats[RTNL_LINK_TX_FIFO_ERR], link->l_stats[RTNL_LINK_TX_COMPRESSED]); nl_dump_line(p, " Errors: length over crc " " frame missed multicast\n"); nl_dump_line(p, " RX %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", link->l_stats[RTNL_LINK_RX_LEN_ERR], link->l_stats[RTNL_LINK_RX_OVER_ERR], link->l_stats[RTNL_LINK_RX_CRC_ERR], link->l_stats[RTNL_LINK_RX_FRAME_ERR], link->l_stats[RTNL_LINK_RX_MISSED_ERR], link->l_stats[RTNL_LINK_MULTICAST]); nl_dump_line(p, " aborted carrier heartbeat " " window collision\n"); nl_dump_line(p, " TX %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", link->l_stats[RTNL_LINK_TX_ABORT_ERR], link->l_stats[RTNL_LINK_TX_CARRIER_ERR], link->l_stats[RTNL_LINK_TX_HBEAT_ERR], link->l_stats[RTNL_LINK_TX_WIN_ERR], link->l_stats[RTNL_LINK_COLLISIONS]); if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_STATS]) link->l_info_ops->io_dump[NL_DUMP_STATS](link, p); do_foreach_af(link, af_dump_stats, p); if (link->ce_mask & LINK_ATTR_VF_LIST) rtnl_link_sriov_dump_stats(link, p); } #if 0 static int link_handle_event(struct nl_object *a, struct rtnl_link_event_cb *cb) { struct rtnl_link *l = (struct rtnl_link *) a; struct nl_cache *c = dp_cache(a); int nevents = 0; if (l->l_change == ~0U) { if (l->ce_msgtype == RTM_NEWLINK) cb->le_register(l); else cb->le_unregister(l); return 1; } if (l->l_change & IFF_SLAVE) { if (l->l_flags & IFF_SLAVE) { struct rtnl_link *m = rtnl_link_get(c, l->l_master); cb->le_new_bonding(l, m); if (m) rtnl_link_put(m); } else cb->le_cancel_bonding(l); } #if 0 if (l->l_change & IFF_UP && l->l_change & IFF_RUNNING) dp_dump_line(p, line++, "link %s changed state to %s.\n", l->l_name, l->l_flags & IFF_UP ? "up" : "down"); if (l->l_change & IFF_PROMISC) { dp_new_line(p, line++); dp_dump(p, "link %s %s promiscuous mode.\n", l->l_name, l->l_flags & IFF_PROMISC ? "entered" : "left"); } if (line == 0) dp_dump_line(p, line++, "link %s sent unknown event.\n", l->l_name); #endif return nevents; } #endif static void link_keygen(struct nl_object *obj, uint32_t *hashkey, uint32_t table_sz) { struct rtnl_link *link = (struct rtnl_link *) obj; unsigned int lkey_sz; struct link_hash_key { uint32_t l_index; uint32_t l_family; } __attribute__((packed)) lkey; lkey_sz = sizeof(lkey); lkey.l_index = link->l_index; lkey.l_family = link->l_family; *hashkey = nl_hash(&lkey, lkey_sz, 0) % table_sz; NL_DBG(5, "link %p key (dev %d fam %d) keysz %d, hash 0x%x\n", link, lkey.l_index, lkey.l_family, lkey_sz, *hashkey); return; } static uint64_t link_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct rtnl_link *a = (struct rtnl_link *) _a; struct rtnl_link *b = (struct rtnl_link *) _b; uint64_t diff = 0; #define LINK_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, LINK_ATTR_##ATTR, a, b, EXPR) diff |= LINK_DIFF(IFINDEX, a->l_index != b->l_index); diff |= LINK_DIFF(MTU, a->l_mtu != b->l_mtu); diff |= LINK_DIFF(LINK, a->l_link != b->l_link); diff |= LINK_DIFF(LINK_NETNSID, a->l_link_netnsid != b->l_link_netnsid); diff |= LINK_DIFF(TXQLEN, a->l_txqlen != b->l_txqlen); diff |= LINK_DIFF(WEIGHT, a->l_weight != b->l_weight); diff |= LINK_DIFF(MASTER, a->l_master != b->l_master); diff |= LINK_DIFF(FAMILY, a->l_family != b->l_family); diff |= LINK_DIFF(OPERSTATE, a->l_operstate != b->l_operstate); diff |= LINK_DIFF(LINKMODE, a->l_linkmode != b->l_linkmode); diff |= LINK_DIFF(QDISC, strcmp(a->l_qdisc, b->l_qdisc)); diff |= LINK_DIFF(IFNAME, strcmp(a->l_name, b->l_name)); diff |= LINK_DIFF(ADDR, nl_addr_cmp(a->l_addr, b->l_addr)); diff |= LINK_DIFF(BRD, nl_addr_cmp(a->l_bcast, b->l_bcast)); diff |= LINK_DIFF(IFALIAS, strcmp(a->l_ifalias, b->l_ifalias)); diff |= LINK_DIFF(NUM_VF, a->l_num_vf != b->l_num_vf); diff |= LINK_DIFF(PROMISCUITY, a->l_promiscuity != b->l_promiscuity); diff |= LINK_DIFF(NUM_TX_QUEUES,a->l_num_tx_queues != b->l_num_tx_queues); diff |= LINK_DIFF(NUM_RX_QUEUES,a->l_num_rx_queues != b->l_num_rx_queues); diff |= LINK_DIFF(GROUP, a->l_group != b->l_group); if (flags & LOOSE_COMPARISON) diff |= LINK_DIFF(FLAGS, (a->l_flags ^ b->l_flags) & b->l_flag_mask); else diff |= LINK_DIFF(FLAGS, a->l_flags != b->l_flags); /* * Compare LINK_ATTR_PROTINFO af_data */ if (a->l_family == b->l_family) { if (rtnl_link_af_data_compare(a, b, a->l_family) != 0) goto protinfo_mismatch; } diff |= LINK_DIFF(LINKINFO, rtnl_link_info_data_compare(a, b, flags) != 0); out: return diff; protinfo_mismatch: diff |= LINK_DIFF(PROTINFO, 1); goto out; #undef LINK_DIFF } static const struct trans_tbl link_attrs[] = { __ADD(LINK_ATTR_MTU, mtu), __ADD(LINK_ATTR_LINK, link), __ADD(LINK_ATTR_TXQLEN, txqlen), __ADD(LINK_ATTR_WEIGHT, weight), __ADD(LINK_ATTR_MASTER, master), __ADD(LINK_ATTR_QDISC, qdisc), __ADD(LINK_ATTR_MAP, map), __ADD(LINK_ATTR_ADDR, address), __ADD(LINK_ATTR_BRD, broadcast), __ADD(LINK_ATTR_FLAGS, flags), __ADD(LINK_ATTR_IFNAME, name), __ADD(LINK_ATTR_IFINDEX, ifindex), __ADD(LINK_ATTR_FAMILY, family), __ADD(LINK_ATTR_ARPTYPE, arptype), __ADD(LINK_ATTR_STATS, stats), __ADD(LINK_ATTR_CHANGE, change), __ADD(LINK_ATTR_OPERSTATE, operstate), __ADD(LINK_ATTR_LINKMODE, linkmode), __ADD(LINK_ATTR_IFALIAS, ifalias), __ADD(LINK_ATTR_NUM_VF, num_vf), __ADD(LINK_ATTR_PROMISCUITY, promiscuity), __ADD(LINK_ATTR_NUM_TX_QUEUES, num_tx_queues), __ADD(LINK_ATTR_NUM_RX_QUEUES, num_rx_queues), __ADD(LINK_ATTR_GSO_MAX_SEGS, gso_max_segs), __ADD(LINK_ATTR_GSO_MAX_SIZE, gso_max_size), __ADD(LINK_ATTR_GROUP, group), __ADD(LINK_ATTR_CARRIER, carrier), __ADD(LINK_ATTR_CARRIER_CHANGES, carrier_changes), __ADD(LINK_ATTR_PHYS_PORT_ID, phys_port_id), __ADD(LINK_ATTR_PHYS_PORT_NAME, phys_port_name), __ADD(LINK_ATTR_PHYS_SWITCH_ID, phys_switch_id), __ADD(LINK_ATTR_NS_FD, ns_fd), __ADD(LINK_ATTR_NS_PID, ns_pid), __ADD(LINK_ATTR_LINK_NETNSID, link_netnsid), }; static char *link_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, link_attrs, ARRAY_SIZE(link_attrs)); } /** * @name Get / List * @{ */ /** * Allocate link cache and fill in all configured links. * @arg sk Netlink socket. * @arg family Link address family or AF_UNSPEC * @arg result Pointer to store resulting cache. * @arg flags Flags to set in link cache before filling * * Allocates and initializes a new link cache. If \c sk is valid, a netlink * message is sent to the kernel requesting a full dump of all configured * links. The returned messages are parsed and filled into the cache. If * the operation succeeds, the resulting cache will contain a link object for * each link configured in the kernel. If \c sk is NULL, returns 0 but the * cache is still empty. * * If \c family is set to an address family other than \c AF_UNSPEC the * contents of the cache can be limited to a specific address family. * Currently the following address families are supported: * - AF_BRIDGE * - AF_INET6 * * @route_doc{link_list, Get List of Links} * @see rtnl_link_get() * @see rtnl_link_get_by_name() * @return 0 on success or a negative error code. */ int rtnl_link_alloc_cache_flags(struct nl_sock *sk, int family, struct nl_cache **result, unsigned int flags) { struct nl_cache * cache; int err; cache = nl_cache_alloc(&rtnl_link_ops); if (!cache) return -NLE_NOMEM; cache->c_iarg1 = family; if (flags) nl_cache_set_flags(cache, flags); if (sk && (err = nl_cache_refill(sk, cache)) < 0) { nl_cache_free(cache); return err; } *result = cache; return 0; } /** * Allocate link cache and fill in all configured links. * @arg sk Netlink socket. * @arg family Link address family or AF_UNSPEC * @arg result Pointer to store resulting cache. * * Allocates and initializes a new link cache. If \c sk is valid, a netlink * message is sent to the kernel requesting a full dump of all configured * links. The returned messages are parsed and filled into the cache. If * the operation succeeds, the resulting cache will contain a link object for * each link configured in the kernel. If \c sk is NULL, returns 0 but the * cache is still empty. * * If \c family is set to an address family other than \c AF_UNSPEC the * contents of the cache can be limited to a specific address family. * Currently the following address families are supported: * - AF_BRIDGE * - AF_INET6 * * @route_doc{link_list, Get List of Links} * @see rtnl_link_get() * @see rtnl_link_get_by_name() * @return 0 on success or a negative error code. */ int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result) { return rtnl_link_alloc_cache_flags(sk, family, result, 0); } /** * Lookup link in cache by interface index * @arg cache Link cache * @arg ifindex Interface index * * Searches through the provided cache looking for a link with matching * interface index. * * @attention The reference counter of the returned link object will be * incremented. Use rtnl_link_put() to release the reference. * * @route_doc{link_list, Get List of Links} * @see rtnl_link_get_by_name() * @return Link object or NULL if no match was found. */ struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex) { struct rtnl_link *link; if (cache->c_ops != &rtnl_link_ops) return NULL; nl_list_for_each_entry(link, &cache->c_items, ce_list) { if (link->l_index == ifindex) { nl_object_get((struct nl_object *) link); return link; } } return NULL; } /** * Lookup link in cache by link name * @arg cache Link cache * @arg name Name of link * * Searches through the provided cache looking for a link with matching * link name * * @attention The reference counter of the returned link object will be * incremented. Use rtnl_link_put() to release the reference. * * @route_doc{link_list, Get List of Links} * @see rtnl_link_get() * @return Link object or NULL if no match was found. */ struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, const char *name) { struct rtnl_link *link; if (cache->c_ops != &rtnl_link_ops) return NULL; nl_list_for_each_entry(link, &cache->c_items, ce_list) { if (!strcmp(name, link->l_name)) { nl_object_get((struct nl_object *) link); return link; } } return NULL; } /** * Construct RTM_GETLINK netlink message * @arg ifindex Interface index * @arg name Name of link * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_link_get_kernel() * with the exception that it will not send the message but return it in * the provided return pointer instead. * * @see rtnl_link_get_kernel() * * @return 0 on success or a negative error code. */ int rtnl_link_build_get_request(int ifindex, const char *name, struct nl_msg **result) { struct ifinfomsg ifi; struct nl_msg *msg; __u32 vf_mask = RTEXT_FILTER_VF; int err = -NLE_MSGSIZE; if (ifindex <= 0 && !name) { APPBUG("ifindex or name must be specified"); return -NLE_MISSING_ATTR; } memset(&ifi, 0, sizeof(ifi)); if (!(msg = nlmsg_alloc_simple(RTM_GETLINK, 0))) return -NLE_NOMEM; if (ifindex > 0) ifi.ifi_index = ifindex; if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) { err = -NLE_MSGSIZE; goto nla_put_failure; } if (name) NLA_PUT_STRING(msg, IFLA_IFNAME, name); err = nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask); if (err) goto nla_put_failure; *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return err; } /** * Get a link object directly from kernel * @arg sk Netlink socket * @arg ifindex Interface index * @arg name Name of link * @arg result Pointer to store resulting link object * * This function builds a \c RTM_GETLINK netlink message to request * a specific link directly from the kernel. The returned answer is * parsed into a struct rtnl_link object and returned via the result * pointer or -NLE_OBJ_NOTFOUND is returned if no matching link was * found. * * Older kernels do not support lookup by name. In that case, libnl * will fail with -NLE_OPNOTSUPP. Note that previous version of libnl * failed in this case with -NLE_INVAL. You can check libnl behavior * using NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP capability. * * @route_doc{link_direct_lookup, Lookup Single Link (Direct Lookup)} * @return 0 on success or a negative error code. */ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, struct rtnl_link **result) { struct nl_msg *msg = NULL; struct nl_object *obj; int err; int syserr; if ((err = rtnl_link_build_get_request(ifindex, name, &msg)) < 0) return err; err = nl_send_auto(sk, msg); nlmsg_free(msg); if (err < 0) return err; if ((err = nl_pickup_keep_syserr(sk, link_msg_parser, &obj, &syserr)) < 0) { if (syserr == -EINVAL && ifindex <= 0 && name && *name) { /* Older kernels do not support lookup by ifname. This was added * by commit kernel a3d1289126e7b14307074b76bf1677015ea5036f . * Detect this error case and return NLE_OPNOTSUPP instead of * NLE_INVAL. */ return -NLE_OPNOTSUPP; } return err; } /* We have used link_msg_parser(), object is definitely a link */ *result = (struct rtnl_link *) obj; /* If an object has been returned, we also need to wait for the ACK */ if (err == 0 && obj) wait_for_ack(sk); return 0; } /** * Translate interface index to corresponding link name * @arg cache Link cache * @arg ifindex Interface index * @arg dst String to store name * @arg len Length of destination string * * Translates the specified interface index to the corresponding * link name and stores the name in the destination string. * * @route_doc{link_translate_ifindex, Translating interface index to link name} * @see rtnl_link_name2i() * @return Name of link or NULL if no match was found. */ char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len) { struct rtnl_link *link = rtnl_link_get(cache, ifindex); if (link) { strncpy(dst, link->l_name, len - 1); rtnl_link_put(link); return dst; } return NULL; } /** * Translate link name to corresponding interface index * @arg cache Link cache * @arg name Name of link * * @route_doc{link_translate_ifindex, Translating interface index to link name} * @see rtnl_link_i2name() * @return Interface index or 0 if no match was found. */ int rtnl_link_name2i(struct nl_cache *cache, const char *name) { int ifindex = 0; struct rtnl_link *link; link = rtnl_link_get_by_name(cache, name); if (link) { ifindex = link->l_index; rtnl_link_put(link); } return ifindex; } /** @} */ int rtnl_link_fill_info(struct nl_msg *msg, struct rtnl_link *link) { if (link->ce_mask & LINK_ATTR_ADDR) NLA_PUT_ADDR(msg, IFLA_ADDRESS, link->l_addr); if (link->ce_mask & LINK_ATTR_BRD) NLA_PUT_ADDR(msg, IFLA_BROADCAST, link->l_bcast); if (link->ce_mask & LINK_ATTR_MTU) NLA_PUT_U32(msg, IFLA_MTU, link->l_mtu); if (link->ce_mask & LINK_ATTR_TXQLEN) NLA_PUT_U32(msg, IFLA_TXQLEN, link->l_txqlen); if (link->ce_mask & LINK_ATTR_WEIGHT) NLA_PUT_U32(msg, IFLA_WEIGHT, link->l_weight); if (link->ce_mask & LINK_ATTR_IFNAME) NLA_PUT_STRING(msg, IFLA_IFNAME, link->l_name); if (link->ce_mask & LINK_ATTR_OPERSTATE) NLA_PUT_U8(msg, IFLA_OPERSTATE, link->l_operstate); if (link->ce_mask & LINK_ATTR_CARRIER) NLA_PUT_U8(msg, IFLA_CARRIER, link->l_carrier); if (link->ce_mask & LINK_ATTR_LINKMODE) NLA_PUT_U8(msg, IFLA_LINKMODE, link->l_linkmode); if (link->ce_mask & LINK_ATTR_IFALIAS) NLA_PUT_STRING(msg, IFLA_IFALIAS, link->l_ifalias); if (link->ce_mask & LINK_ATTR_LINK) NLA_PUT_U32(msg, IFLA_LINK, link->l_link); if (link->ce_mask & LINK_ATTR_LINK_NETNSID) NLA_PUT_S32(msg, IFLA_LINK_NETNSID, link->l_link_netnsid); if (link->ce_mask & LINK_ATTR_MASTER) NLA_PUT_U32(msg, IFLA_MASTER, link->l_master); if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES) NLA_PUT_U32(msg, IFLA_NUM_TX_QUEUES, link->l_num_tx_queues); if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES) NLA_PUT_U32(msg, IFLA_NUM_RX_QUEUES, link->l_num_rx_queues); if (link->ce_mask & LINK_ATTR_NS_FD) NLA_PUT_U32(msg, IFLA_NET_NS_FD, link->l_ns_fd); if (link->ce_mask & LINK_ATTR_NS_PID) NLA_PUT_U32(msg, IFLA_NET_NS_PID, link->l_ns_pid); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int build_link_msg(int cmd, struct ifinfomsg *hdr, struct rtnl_link *link, int flags, struct nl_msg **result) { struct nl_msg *msg; struct nlattr *af_spec; msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, hdr, sizeof(*hdr), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (rtnl_link_fill_info(msg, link)) goto nla_put_failure; if (link->ce_mask & LINK_ATTR_GROUP) NLA_PUT_U32(msg, IFLA_GROUP, link->l_group); if (link->ce_mask & LINK_ATTR_LINKINFO) { struct nlattr *info; if (!(info = nla_nest_start(msg, IFLA_LINKINFO))) goto nla_put_failure; NLA_PUT_STRING(msg, IFLA_INFO_KIND, link->l_info_kind); if (link->l_info_ops) { if (link->l_info_ops->io_put_attrs && link->l_info_ops->io_put_attrs(msg, link) < 0) goto nla_put_failure; } nla_nest_end(msg, info); } if (link->ce_mask & LINK_ATTR_VF_LIST) { if (rtnl_link_sriov_fill_vflist(msg, link) < 0) goto nla_put_failure; } if (do_foreach_af(link, af_fill_pi, msg) < 0) goto nla_put_failure; if (!(af_spec = nla_nest_start(msg, IFLA_AF_SPEC))) goto nla_put_failure; if (do_foreach_af(link, af_fill, msg) < 0) goto nla_put_failure; nla_nest_end(msg, af_spec); *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * @name Add / Modify * @{ */ /** * Build a netlink message requesting the addition of new virtual link * @arg link new link to add * @arg flags additional netlink message flags * @arg result pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_link_add() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_link_add() * * @note This operation is not supported on all kernel versions. * * @return 0 on success or a negative error code. */ int rtnl_link_build_add_request(struct rtnl_link *link, int flags, struct nl_msg **result) { struct ifinfomsg ifi = { .ifi_family = link->l_family, .ifi_index = link->l_index, .ifi_flags = link->l_flags, .ifi_change = link->l_flag_mask, }; return build_link_msg(RTM_NEWLINK, &ifi, link, flags, result); } /** * Add virtual link * @arg sk netlink socket. * @arg link new link to add * @arg flags additional netlink message flags * * Builds a \c RTM_NEWLINK netlink message requesting the addition of * a new virtual link. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @copydoc auto_ack_warning * * @return 0 on success or a negative error code. */ int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags) { struct nl_msg *msg; int err; err = rtnl_link_build_add_request(link, flags, &msg); if (err < 0) return err; return nl_send_sync(sk, msg); } /** * Build a netlink message requesting the modification of link * @arg orig original link to change * @arg changes link containing the changes to be made * @arg flags additional netlink message flags * @arg result pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_link_change() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_link_change() * * @note The resulting message will have message type set to RTM_NEWLINK * which may not work with older kernels. You may have to modify it * to RTM_SETLINK (does not allow changing link info attributes) to * have the change request work with older kernels. * * @return 0 on success or a negative error code. */ int rtnl_link_build_change_request(struct rtnl_link *orig, struct rtnl_link *changes, int flags, struct nl_msg **result) { struct ifinfomsg ifi = { .ifi_family = orig->l_family, .ifi_index = orig->l_index, }; int err, rt; if (changes->ce_mask & LINK_ATTR_FLAGS) { ifi.ifi_flags = orig->l_flags & ~changes->l_flag_mask; ifi.ifi_flags |= changes->l_flags; ifi.ifi_change = changes->l_flag_mask; } if (changes->l_family && changes->l_family != orig->l_family) { APPBUG("link change: family is immutable"); return -NLE_IMMUTABLE; } /* Avoid unnecessary name change requests */ if (orig->ce_mask & LINK_ATTR_IFINDEX && orig->ce_mask & LINK_ATTR_IFNAME && changes->ce_mask & LINK_ATTR_IFNAME && !strcmp(orig->l_name, changes->l_name)) changes->ce_mask &= ~LINK_ATTR_IFNAME; rt = af_request_type(orig->l_family); if ((err = build_link_msg(rt, &ifi, changes, flags, result)) < 0) goto errout; return 0; errout: return err; } /** * Change link * @arg sk netlink socket. * @arg orig original link to be changed * @arg changes link containing the changes to be made * @arg flags additional netlink message flags * * Builds a \c RTM_NEWLINK netlink message requesting the change of * a network link. If -EOPNOTSUPP is returned by the kernel, the * message type will be changed to \c RTM_SETLINK and the message is * resent to work around older kernel versions. * * The link to be changed is looked up based on the interface index * supplied in the \p orig link. Optionaly the link name is used but * only if no interface index is provided, otherwise providing an * link name will result in the link name being changed. * * If no matching link exists, the function will return * -NLE_OBJ_NOTFOUND. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @copydoc auto_ack_warning * * @note The link name can only be changed if the link has been put * in opertional down state. (~IF_UP) * * @return 0 on success or a negative error code. */ int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig, struct rtnl_link *changes, int flags) { struct nl_msg *msg; int err; err = rtnl_link_build_change_request(orig, changes, flags, &msg); if (err < 0) return err; retry: err = nl_send_auto_complete(sk, msg); if (err < 0) goto errout; err = wait_for_ack(sk); if (err == -NLE_OPNOTSUPP && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) { msg->nm_nlh->nlmsg_type = RTM_SETLINK; goto retry; } errout: nlmsg_free(msg); return err; } /** @} */ /** * @name Delete * @{ */ /** * Build a netlink message requesting the deletion of a link * @arg link Link to delete * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_link_delete() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_link_delete() * * @return 0 on success or a negative error code. */ int rtnl_link_build_delete_request(const struct rtnl_link *link, struct nl_msg **result) { struct nl_msg *msg; struct ifinfomsg ifi = { .ifi_index = link->l_index, }; if (!(link->ce_mask & (LINK_ATTR_IFINDEX | LINK_ATTR_IFNAME))) { APPBUG("ifindex or name must be specified"); return -NLE_MISSING_ATTR; } if (!(msg = nlmsg_alloc_simple(RTM_DELLINK, 0))) return -NLE_NOMEM; if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (link->ce_mask & LINK_ATTR_IFNAME) NLA_PUT_STRING(msg, IFLA_IFNAME, link->l_name); *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * Delete link * @arg sk Netlink socket * @arg link Link to delete * * Builds a \c RTM_DELLINK netlink message requesting the deletion of * a network link which has been previously added to the kernel and * sends the message to the kernel. * * If no matching link exists, the function will return * -NLE_OBJ_NOTFOUND. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @copydoc auto_ack_warning * * @note Only virtual links such as dummy interface or vlan interfaces * can be deleted. It is not possible to delete physical interfaces * such as ethernet interfaces or the loopback device. * * @return 0 on success or a negative error code. */ int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link) { struct nl_msg *msg; int err; if ((err = rtnl_link_build_delete_request(link, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** @} */ /** * @name Link Object * @{ */ /** * Allocate link object * * @see rtnl_link_put() * @return New link object or NULL if allocation failed */ struct rtnl_link *rtnl_link_alloc(void) { return (struct rtnl_link *) nl_object_alloc(&link_obj_ops); } /** * Return a link object reference * @arg link Link object */ void rtnl_link_put(struct rtnl_link *link) { nl_object_put((struct nl_object *) link); } /** * Set name of link object * @arg link Link object * @arg name New name * * @note To change the name of a link in the kernel, set the interface * index to the link you wish to change, modify the link name using * this function and pass the link object to rtnl_link_change() or * rtnl_link_add(). * * @route_doc{link_attr_name, Link Name} * @see rtnl_link_get_name() * @see rtnl_link_set_ifindex() */ void rtnl_link_set_name(struct rtnl_link *link, const char *name) { strncpy(link->l_name, name, sizeof(link->l_name) - 1); link->ce_mask |= LINK_ATTR_IFNAME; } /** * Return name of link object * @arg link Link object * * @route_doc{link_attr_name, Link Name} * @see rtnl_link_set_name() * @return Link name or NULL if name is not specified */ char *rtnl_link_get_name(struct rtnl_link *link) { return link->ce_mask & LINK_ATTR_IFNAME ? link->l_name : NULL; } /** * Set the group identifier of a link object * @arg link Link object * @arg group Group identifier */ void rtnl_link_set_group(struct rtnl_link *link, uint32_t group) { link->l_group = group; link->ce_mask |= LINK_ATTR_GROUP; } /** * Return the group identifier of link object * @arg link Link object * * @return Group identifier or 0 if not set. */ uint32_t rtnl_link_get_group(struct rtnl_link *link) { return link->l_group; } static inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos, struct nl_addr *new, int flag) { if (*pos) nl_addr_put(*pos); nl_addr_get(new); *pos = new; link->ce_mask |= flag; } /** * Set link layer address of link object * @arg link Link object * @arg addr New link layer address * * The function increments the reference counter of the address object * and overwrites any existing link layer address previously assigned. * * @route_doc{link_attr_address, Link layer address} * @see rtnl_link_get_addr() */ void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr) { __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR); } /** * Return link layer address of link object * @arg link Link object * * @copydoc pointer_lifetime_warning * @route_doc{link_attr_address, Link Layer Address} * @see rtnl_link_set_addr() * @return Link layer address or NULL if not set. */ struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link) { return link->ce_mask & LINK_ATTR_ADDR ? link->l_addr : NULL; } /** * Set link layer broadcast address of link object * @arg link Link object * @arg addr New broadcast address * * The function increments the reference counter of the address object * and overwrites any existing link layer broadcast address previously * assigned. * * @route_doc{link_attr_broadcast, Link Layer Broadcast Address} * @see rtnl_link_get_broadcast() */ void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr) { __assign_addr(link, &link->l_bcast, addr, LINK_ATTR_BRD); } /** * Return link layer broadcast address of link object * @arg link Link object * * @copydoc pointer_lifetime_warning * @route_doc{link_attr_address, Link Layer Address} * @see rtnl_link_set_broadcast() * @return Link layer address or NULL if not set. */ struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link) { return link->ce_mask & LINK_ATTR_BRD ? link->l_bcast : NULL; } /** * Set flags of link object * @arg link Link object * @arg flags Flags * * @see rtnl_link_get_flags() * @see rtnl_link_unset_flags() */ void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags) { link->l_flag_mask |= flags; link->l_flags |= flags; link->ce_mask |= LINK_ATTR_FLAGS; } /** * Unset flags of link object * @arg link Link object * @arg flags Flags * * @see rtnl_link_set_flags() * @see rtnl_link_get_flags() */ void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags) { link->l_flag_mask |= flags; link->l_flags &= ~flags; link->ce_mask |= LINK_ATTR_FLAGS; } /** * Return flags of link object * @arg link Link object * * @route_doc{link_attr_flags, Link Flags} * @see rtnl_link_set_flags() * @see rtnl_link_unset_flags() * @return Link flags or 0 if none have been set. */ unsigned int rtnl_link_get_flags(struct rtnl_link *link) { return link->l_flags; } /** * Set address family of link object * * @see rtnl_link_get_family() */ void rtnl_link_set_family(struct rtnl_link *link, int family) { link->l_family = family; link->ce_mask |= LINK_ATTR_FAMILY; if (link->l_af_ops) { af_free(link, link->l_af_ops, link->l_af_data[link->l_af_ops->ao_family], NULL); link->l_af_data[link->l_af_ops->ao_family] = NULL; } link->l_af_ops = af_lookup_and_alloc(link, family); } /** * Return address family of link object * @arg link Link object * * @see rtnl_link_set_family() * @return Address family or \c AF_UNSPEC if not specified. */ int rtnl_link_get_family(struct rtnl_link *link) { return link->ce_mask & LINK_ATTR_FAMILY ? link->l_family : AF_UNSPEC; } /** * Set hardware type of link object * @arg link Link object * @arg arptype New hardware type \c (ARPHRD_*) * * @route_doc{link_attr_arptype, Hardware Type} * @copydoc read_only_attribute * @see rtnl_link_get_arptype() */ void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype) { link->l_arptype = arptype; link->ce_mask |= LINK_ATTR_ARPTYPE; } /** * Get hardware type of link object * @arg link Link object * * @route_doc{link_attr_arptype, Hardware Type} * @see rtnl_link_set_arptype() * @return Hardware type \c (ARPHRD_ETHER *) or \c ARPHRD_VOID */ unsigned int rtnl_link_get_arptype(struct rtnl_link *link) { if (link->ce_mask & LINK_ATTR_ARPTYPE) return link->l_arptype; else return ARPHRD_VOID; } /** * Set interface index of link object * @arg link Link object * @arg ifindex Interface index * * @route_doc{link_attr_ifindex, Interface Index} * @see rtnl_link_get_ifindex() */ void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex) { link->l_index = ifindex; link->ce_mask |= LINK_ATTR_IFINDEX; } /** * Return interface index of link object * @arg link Link object * * @route_doc{link_attr_ifindex, Interface Index} * @see rtnl_link_set_ifindex() * @return Interface index or 0 if not set. */ int rtnl_link_get_ifindex(struct rtnl_link *link) { return link->l_index; } /** * Set Maximum Transmission Unit of link object * @arg link Link object * @arg mtu New MTU value in number of bytes * * @route_doc{link_attr_mtu, Maximum Transmission Unit} * @see rtnl_link_get_mtu() */ void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu) { link->l_mtu = mtu; link->ce_mask |= LINK_ATTR_MTU; } /** * Return maximum transmission unit of link object * @arg link Link object * * @route_doc{link_attr_mtu, Maximum Transmission Unit} * @see rtnl_link_set_mtu() * @return MTU in bytes or 0 if not set */ unsigned int rtnl_link_get_mtu(struct rtnl_link *link) { return link->l_mtu; } /** * Set transmission queue length * @arg link Link object * @arg txqlen New queue length * * The unit is dependant on the link type. The most common units is number * of packets. * * @route_doc{link_attr_txqlen, Transmission Queue Length} */ void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen) { link->l_txqlen = txqlen; link->ce_mask |= LINK_ATTR_TXQLEN; } /** * Return transmission queue length * @arg link Link object * * The unit is dependant on the link type. The most common units is number * of packets. * * @route_doc{link_attr_txqlen, Transmission Queue Length} * @return queue length or 0 if not specified. */ unsigned int rtnl_link_get_txqlen(struct rtnl_link *link) { return link->ce_mask & LINK_ATTR_TXQLEN ? link->l_txqlen : 0; } void rtnl_link_set_link(struct rtnl_link *link, int ifindex) { link->l_link = ifindex; link->ce_mask |= LINK_ATTR_LINK; } int rtnl_link_get_link(struct rtnl_link *link) { return link->l_link; } /** * Set the netnsid of the link * @arg link Link object * @link_netnsid the netnsid to set * * Sets the IFLA_LINK_NETNSID attribute of the link * @returns 0 on success */ int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid) { link->l_link_netnsid = link_netnsid; link->ce_mask |= LINK_ATTR_LINK_NETNSID; return 0; } /** * Get the netnsid of the link * @arg link Link object * @out_link_netnsid the netnsid * * Gets the IFLA_LINK_NETNSID attribute of the link * or returns an error if the value is unset. * * @returns 0 on success */ int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid) { if (!(link->ce_mask & LINK_ATTR_LINK_NETNSID)) return -NLE_INVAL; *out_link_netnsid = link->l_link_netnsid; return 0; } /** * Set master link of link object * @arg link Link object * @arg ifindex Interface index of master link * * @see rtnl_link_get_master() */ void rtnl_link_set_master(struct rtnl_link *link, int ifindex) { link->l_master = ifindex; link->ce_mask |= LINK_ATTR_MASTER; } /** * Return master link of link object * @arg link Link object * * @see rtnl_link_set_master() * @return Interface index of master link or 0 if not specified */ int rtnl_link_get_master(struct rtnl_link *link) { return link->l_master; } /** * Set carrier of link object * @arg link Link object * @arg status New carrier status * * @see rtnl_link_get_carrier() */ void rtnl_link_set_carrier(struct rtnl_link *link, uint8_t status) { link->l_carrier = status; link->ce_mask |= LINK_ATTR_CARRIER; } /** * Return carrier status of link object * @arg link Link object * * @see rtnl_link_set_master() * @return Carrier state. */ uint8_t rtnl_link_get_carrier(struct rtnl_link *link) { return link->l_carrier; } /** * Return carrier on/off changes of link object * @arg link Link object * @arg carrier_changes Pointer to store number of carrier changes * * @return 0 on success, negative error number otherwise */ int rtnl_link_get_carrier_changes(struct rtnl_link *link, uint32_t *carrier_changes) { if (!(link->ce_mask & LINK_ATTR_CARRIER_CHANGES)) return -NLE_NOATTR; if (carrier_changes) *carrier_changes = link->l_carrier_changes; return 0; } /** * Set operational status of link object * @arg link Link object * @arg status New opertional status * * @route_doc{link_attr_operstate, Operational Status}} * @see rtnl_link_get_operstate() */ void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t status) { link->l_operstate = status; link->ce_mask |= LINK_ATTR_OPERSTATE; } /** * Return operational status of link object * @arg link Link object * * @route_doc{link_attr_operstate, Operational Status} * @see rtnl_link_set_operstate() * @return Opertional state or \c IF_OPER_UNKNOWN */ uint8_t rtnl_link_get_operstate(struct rtnl_link *link) { return link->l_operstate; } /** * Set link mode of link object * @arg link Link object * @arg mode New link mode * * @route_doc{link_attr_mode, Mode} * @see rtnl_link_get_linkmode() */ void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode) { link->l_linkmode = mode; link->ce_mask |= LINK_ATTR_LINKMODE; } /** * Return link mode of link object * @arg link Link object * * @route_doc{link_attr_mode, Mode} * @see rtnl_link_get_linkmode() * @return Link mode or \c IF_LINK_MODE_DEFAULT */ uint8_t rtnl_link_get_linkmode(struct rtnl_link *link) { return link->l_linkmode; } /** * Return alias name of link object (SNMP IfAlias) * @arg link Link object * * @route_doc{link_attr_alias, Alias} * @see rtnl_link_set_ifalias() * @return Alias name or NULL if not set. */ const char *rtnl_link_get_ifalias(struct rtnl_link *link) { return link->l_ifalias; } /** * Set alias name of link object (SNMP IfAlias) * @arg link Link object * @arg alias Alias name or NULL to unset * * Sets the alias name of the link to the specified name. The alias * name can be unset by specyfing NULL as the alias. The name will * be strdup()ed, so no need to provide a persistent character string. * * @route_doc{link_attr_alias, Alias} * @see rtnl_link_get_ifalias() */ void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias) { free(link->l_ifalias); if (alias) { link->l_ifalias = strdup(alias); link->ce_mask |= LINK_ATTR_IFALIAS; } else { link->l_ifalias = NULL; link->ce_mask &= ~LINK_ATTR_IFALIAS; } } /** * Set queueing discipline name of link object * @arg link Link object * @arg name Name of queueing discipline * * @copydoc read_only_attribute * * For more information on how to modify the qdisc of a link, see section * @ref_route{route_tc, Traffic Control}. * * @route_doc{link_attr_qdisc, Queueing Discipline Name} * @see rtnl_link_get_qdisc() */ void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name) { strncpy(link->l_qdisc, name, sizeof(link->l_qdisc) - 1); link->ce_mask |= LINK_ATTR_QDISC; } /** * Return name of queueing discipline of link object * @arg link Link object * * @route_doc{link_attr_qdisc, Queueing Discipline Name} * @see rtnl_link_set_qdisc() * @return Name of qdisc or NULL if not specified. */ char *rtnl_link_get_qdisc(struct rtnl_link *link) { return link->ce_mask & LINK_ATTR_QDISC ? link->l_qdisc : NULL; } /** * Return number of PCI virtual functions of link object * @arg link Link object * @arg num_vf Pointer to store number of VFs * * @return 0 on success or -NLE_OPNOTSUPP if not available */ int rtnl_link_get_num_vf(struct rtnl_link *link, uint32_t *num_vf) { if (link->ce_mask & LINK_ATTR_NUM_VF) { *num_vf = link->l_num_vf; return 0; } else return -NLE_OPNOTSUPP; } /** * Return value of link statistics counter * @arg link Link object * @arg id Identifier of statistical counter * * @return Value of counter or 0 if not specified. */ uint64_t rtnl_link_get_stat(struct rtnl_link *link, rtnl_link_stat_id_t id) { if (id > RTNL_LINK_STATS_MAX) return 0; return link->l_stats[id]; } /** * Set value of link statistics counter * @arg link Link object * @arg id Identifier of statistical counter * @arg value New value * * \note Changing the value of a statistical counter will not change the * value in the kernel. * * @return 0 on success or a negative error code */ int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id, const uint64_t value) { if (id > RTNL_LINK_STATS_MAX) return -NLE_INVAL; link->l_stats[id] = value; return 0; } /** * Set type of link object * @arg link Link object * @arg type Name of link type * * Looks up the link type module and prepares the link to store type * specific attributes. If a type has been assigned already it will * be released with all link type specific attributes lost. * * @route_doc{link_modules, Link Modules} * @return 0 on success or a negative errror code. */ int rtnl_link_set_type(struct rtnl_link *link, const char *type) { struct rtnl_link_info_ops *io; int err; char *kind; free(link->l_info_kind); link->ce_mask &= ~LINK_ATTR_LINKINFO; release_link_info(link); if (!type) return 0; kind = strdup(type); if (!kind) return -NLE_NOMEM; io = rtnl_link_info_ops_lookup(type); if (io) { if (io->io_alloc && (err = io->io_alloc(link)) < 0) goto errout; link->l_info_ops = io; } link->l_info_kind = kind; link->ce_mask |= LINK_ATTR_LINKINFO; return 0; errout: free(kind); return err; } /** * Return type of link * @arg link Link object * * @route_doc{link_modules, Link Modules} * @return Name of link type or NULL if not specified. */ char *rtnl_link_get_type(struct rtnl_link *link) { return link->l_info_kind; } /** * Set link promiscuity count * @arg link Link object * @arg count New promiscuity count * * @copydoc read_only_attribute * * @see rtnl_link_get_promiscuity() */ void rtnl_link_set_promiscuity(struct rtnl_link *link, uint32_t count) { link->l_promiscuity = count; link->ce_mask |= LINK_ATTR_PROMISCUITY; } /** * Return link promiscuity count * @arg link Link object * * @see rtnl_link_set_promiscuity() * @return Link promiscuity count or 0 */ uint32_t rtnl_link_get_promiscuity(struct rtnl_link *link) { return link->l_promiscuity; } /** * Set number of TX queues * @arg link Link object * @arg nqueues Number of queues * * Sets the number of TX queues of the link object. The value is considered * by the kernel when creating network devices that can be created via * netlink. The value will be passed on to alloc_netdev_mqs() * * Therefore use of rtnl_link_set_num_tx_queues() only makes sense in * combination with rtnl_link_add() or if the link object is used as a filter. * * @see rtnl_link_get_num_tx_queues() */ void rtnl_link_set_num_tx_queues(struct rtnl_link *link, uint32_t nqueues) { link->l_num_tx_queues = nqueues; link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES; } /** * Return number of TX queues * @arg link Link object * * @return Number of TX queues or 0 */ uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *link) { return link->l_num_tx_queues; } /** * Set number of RX queues * @arg link Link object * @arg nqueues Number of queues * * Sets the number of RX queues of the link object. The value is considered * by the kernel when creating network devices that can be created via * netlink. The value will be passed on to alloc_netdev_mqs() * * Therefore use of rtnl_link_set_num_rx_queues() only makes sense in * combination with rtnl_link_add() or if the link object is used as a filter. * * @see rtnl_link_get_num_rx_queues() */ void rtnl_link_set_num_rx_queues(struct rtnl_link *link, uint32_t nqueues) { link->l_num_rx_queues = nqueues; link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES; } /** * Return number of RX queues * @arg link Link object * * @return Number of RX queues or 0 */ uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *link) { return link->l_num_rx_queues; } /** * Return maximum number of segments for generic segmentation offload * @arg link Link object * @arg gso_max_segs Pointer to store maximum number GSO segments * * @return 0 on success, negative error number otherwise */ int rtnl_link_get_gso_max_segs(struct rtnl_link *link, uint32_t *gso_max_segs) { if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SEGS)) return -NLE_NOATTR; if (gso_max_segs) *gso_max_segs = link->l_gso_max_segs; return 0; } /** * Return maximum size for generic segmentation offload * @arg link Link object * @arg gso_max_segs Pointer to store maximum GSO size * * @return 0 on success, negative error number otherwise */ int rtnl_link_get_gso_max_size(struct rtnl_link *link, uint32_t *gso_max_size) { if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SIZE)) return -NLE_NOATTR; if (gso_max_size) *gso_max_size = link->l_gso_max_size; return 0; } /** * Return physical port id of link object * @arg link Link object * * @return Physical port id or NULL if not set. */ struct nl_data *rtnl_link_get_phys_port_id(struct rtnl_link *link) { return link->l_phys_port_id; } /** * Return physical port name of link object * @arg link Link object * * @return Physical port name or NULL if not set. */ char *rtnl_link_get_phys_port_name(struct rtnl_link *link) { return link->l_phys_port_name; } /* * Return physical switch id of link object * @arg link Link object * * @return Physical switch id or NULL if not set. */ struct nl_data *rtnl_link_get_phys_switch_id(struct rtnl_link *link) { return link->l_phys_switch_id; } void rtnl_link_set_ns_fd(struct rtnl_link *link, int fd) { link->l_ns_fd = fd; link->ce_mask |= LINK_ATTR_NS_FD; } int rtnl_link_get_ns_fd(struct rtnl_link *link) { return link->l_ns_fd; } void rtnl_link_set_ns_pid(struct rtnl_link *link, pid_t pid) { link->l_ns_pid = pid; link->ce_mask |= LINK_ATTR_NS_PID; } pid_t rtnl_link_get_ns_pid(struct rtnl_link *link) { return link->l_ns_pid; } /** @} */ /** * @name Master/Slave * @{ */ /** * Enslave slave link to master link * @arg sock netlink socket * @arg master ifindex of master link * @arg slave ifindex of slave link * * This function is identical to rtnl_link_enslave() except that * it takes interface indices instead of rtnl_link objects. * * @see rtnl_link_enslave() * * @return 0 on success or a negative error code. */ int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return -NLE_NOMEM; rtnl_link_set_ifindex(link, slave); rtnl_link_set_master(link, master); if ((err = rtnl_link_change(sock, link, link, 0)) < 0) goto errout; rtnl_link_put(link); /* * Due to the kernel not signaling whether this opertion is * supported or not, we will retrieve the attribute to see if the * request was successful. If the master assigned remains unchanged * we will return NLE_OPNOTSUPP to allow performing backwards * compatibility of some sort. */ if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0) return err; if (rtnl_link_get_master(link) != master) err = -NLE_OPNOTSUPP; errout: rtnl_link_put(link); return err; } /** * Enslave slave link to master link * @arg sock netlink socket * @arg master master link * @arg slave slave link * * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to * the master and sends the request via the specified netlink socket. * * @note The feature of enslaving/releasing via netlink has only been added * recently to the kernel (Feb 2011). Also, the kernel does not signal * if the operation is not supported. Therefore this function will * verify if the master assignment has changed and will return * -NLE_OPNOTSUPP if it did not. * * @see rtnl_link_enslave_ifindex() * @see rtnl_link_release() * * @return 0 on success or a negative error code. */ int rtnl_link_enslave(struct nl_sock *sock, struct rtnl_link *master, struct rtnl_link *slave) { return rtnl_link_enslave_ifindex(sock, rtnl_link_get_ifindex(master), rtnl_link_get_ifindex(slave)); } /** * Release slave link from its master * @arg sock netlink socket * @arg slave slave link * * This function is identical to rtnl_link_release() except that * it takes an interface index instead of a rtnl_link object. * * @see rtnl_link_release() * * @return 0 on success or a negative error code. */ int rtnl_link_release_ifindex(struct nl_sock *sock, int slave) { return rtnl_link_enslave_ifindex(sock, 0, slave); } /** * Release slave link from its master * @arg sock netlink socket * @arg slave slave link * * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from * its master and sends the request via the specified netlink socket. * * @note The feature of enslaving/releasing via netlink has only been added * recently to the kernel (Feb 2011). Also, the kernel does not signal * if the operation is not supported. Therefore this function will * verify if the master assignment has changed and will return * -NLE_OPNOTSUPP if it did not. * * @see rtnl_link_release_ifindex() * @see rtnl_link_enslave() * * @return 0 on success or a negative error code. */ int rtnl_link_release(struct nl_sock *sock, struct rtnl_link *slave) { return rtnl_link_release_ifindex(sock, rtnl_link_get_ifindex(slave)); } /** @} */ /** * @name Utilities * @{ */ static const struct trans_tbl link_flags[] = { __ADD(IFF_LOOPBACK, loopback), __ADD(IFF_BROADCAST, broadcast), __ADD(IFF_POINTOPOINT, pointopoint), __ADD(IFF_MULTICAST, multicast), __ADD(IFF_NOARP, noarp), __ADD(IFF_ALLMULTI, allmulti), __ADD(IFF_PROMISC, promisc), __ADD(IFF_MASTER, master), __ADD(IFF_SLAVE, slave), __ADD(IFF_DEBUG, debug), __ADD(IFF_DYNAMIC, dynamic), __ADD(IFF_AUTOMEDIA, automedia), __ADD(IFF_PORTSEL, portsel), __ADD(IFF_NOTRAILERS, notrailers), __ADD(IFF_UP, up), __ADD(IFF_RUNNING, running), __ADD(IFF_LOWER_UP, lowerup), __ADD(IFF_DORMANT, dormant), __ADD(IFF_ECHO, echo), }; char *rtnl_link_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, link_flags, ARRAY_SIZE(link_flags)); } int rtnl_link_str2flags(const char *name) { return __str2flags(name, link_flags, ARRAY_SIZE(link_flags)); } static const struct trans_tbl link_stats[] = { __ADD(RTNL_LINK_RX_PACKETS, rx_packets), __ADD(RTNL_LINK_TX_PACKETS, tx_packets), __ADD(RTNL_LINK_RX_BYTES, rx_bytes), __ADD(RTNL_LINK_TX_BYTES, tx_bytes), __ADD(RTNL_LINK_RX_ERRORS, rx_errors), __ADD(RTNL_LINK_TX_ERRORS, tx_errors), __ADD(RTNL_LINK_RX_DROPPED, rx_dropped), __ADD(RTNL_LINK_TX_DROPPED, tx_dropped), __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed), __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed), __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err), __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err), __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err), __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err), __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err), __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err), __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err), __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err), __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err), __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err), __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err), __ADD(RTNL_LINK_COLLISIONS, collisions), __ADD(RTNL_LINK_MULTICAST, multicast), __ADD(RTNL_LINK_IP6_INPKTS, Ip6InReceives), __ADD(RTNL_LINK_IP6_INHDRERRORS, Ip6InHdrErrors), __ADD(RTNL_LINK_IP6_INTOOBIGERRORS, Ip6InTooBigErrors), __ADD(RTNL_LINK_IP6_INNOROUTES, Ip6InNoRoutes), __ADD(RTNL_LINK_IP6_INADDRERRORS, Ip6InAddrErrors), __ADD(RTNL_LINK_IP6_INUNKNOWNPROTOS, Ip6InUnknownProtos), __ADD(RTNL_LINK_IP6_INTRUNCATEDPKTS, Ip6InTruncatedPkts), __ADD(RTNL_LINK_IP6_INDISCARDS, Ip6InDiscards), __ADD(RTNL_LINK_IP6_INDELIVERS, Ip6InDelivers), __ADD(RTNL_LINK_IP6_OUTFORWDATAGRAMS, Ip6OutForwDatagrams), __ADD(RTNL_LINK_IP6_OUTPKTS, Ip6OutRequests), __ADD(RTNL_LINK_IP6_OUTDISCARDS, Ip6OutDiscards), __ADD(RTNL_LINK_IP6_OUTNOROUTES, Ip6OutNoRoutes), __ADD(RTNL_LINK_IP6_REASMTIMEOUT, Ip6ReasmTimeout), __ADD(RTNL_LINK_IP6_REASMREQDS, Ip6ReasmReqds), __ADD(RTNL_LINK_IP6_REASMOKS, Ip6ReasmOKs), __ADD(RTNL_LINK_IP6_REASMFAILS, Ip6ReasmFails), __ADD(RTNL_LINK_IP6_FRAGOKS, Ip6FragOKs), __ADD(RTNL_LINK_IP6_FRAGFAILS, Ip6FragFails), __ADD(RTNL_LINK_IP6_FRAGCREATES, Ip6FragCreates), __ADD(RTNL_LINK_IP6_INMCASTPKTS, Ip6InMcastPkts), __ADD(RTNL_LINK_IP6_OUTMCASTPKTS, Ip6OutMcastPkts), __ADD(RTNL_LINK_IP6_INBCASTPKTS, Ip6InBcastPkts), __ADD(RTNL_LINK_IP6_OUTBCASTPKTS, Ip6OutBcastPkts), __ADD(RTNL_LINK_IP6_INOCTETS, Ip6InOctets), __ADD(RTNL_LINK_IP6_OUTOCTETS, Ip6OutOctets), __ADD(RTNL_LINK_IP6_INMCASTOCTETS, Ip6InMcastOctets), __ADD(RTNL_LINK_IP6_OUTMCASTOCTETS, Ip6OutMcastOctets), __ADD(RTNL_LINK_IP6_INBCASTOCTETS, Ip6InBcastOctets), __ADD(RTNL_LINK_IP6_OUTBCASTOCTETS, Ip6OutBcastOctets), __ADD(RTNL_LINK_ICMP6_INMSGS, ICMP6_InMsgs), __ADD(RTNL_LINK_ICMP6_INERRORS, ICMP6_InErrors), __ADD(RTNL_LINK_ICMP6_OUTMSGS, ICMP6_OutMsgs), __ADD(RTNL_LINK_ICMP6_OUTERRORS, ICMP6_OutErrors), __ADD(RTNL_LINK_ICMP6_CSUMERRORS, ICMP6_InCsumErrors), __ADD(RTNL_LINK_IP6_CSUMERRORS, Ip6_InCsumErrors), __ADD(RTNL_LINK_IP6_NOECTPKTS, Ip6_InNoECTPkts), __ADD(RTNL_LINK_IP6_ECT1PKTS, Ip6_InECT1Pkts), __ADD(RTNL_LINK_IP6_ECT0PKTS, Ip6_InECT0Pkts), __ADD(RTNL_LINK_IP6_CEPKTS, Ip6_InCEPkts), __ADD(RTNL_LINK_RX_NOHANDLER, rx_nohandler), }; char *rtnl_link_stat2str(int st, char *buf, size_t len) { return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats)); } int rtnl_link_str2stat(const char *name) { return __str2type(name, link_stats, ARRAY_SIZE(link_stats)); } static const struct trans_tbl link_operstates[] = { __ADD(IF_OPER_UNKNOWN, unknown), __ADD(IF_OPER_NOTPRESENT, notpresent), __ADD(IF_OPER_DOWN, down), __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown), __ADD(IF_OPER_TESTING, testing), __ADD(IF_OPER_DORMANT, dormant), __ADD(IF_OPER_UP, up), }; char *rtnl_link_operstate2str(uint8_t st, char *buf, size_t len) { return __type2str(st, buf, len, link_operstates, ARRAY_SIZE(link_operstates)); } int rtnl_link_str2operstate(const char *name) { return __str2type(name, link_operstates, ARRAY_SIZE(link_operstates)); } static const struct trans_tbl link_modes[] = { __ADD(IF_LINK_MODE_DEFAULT, default), __ADD(IF_LINK_MODE_DORMANT, dormant), }; static const struct trans_tbl carrier_states[] = { __ADD(IF_CARRIER_DOWN, down), __ADD(IF_CARRIER_UP, up), }; char *rtnl_link_mode2str(uint8_t st, char *buf, size_t len) { return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes)); } int rtnl_link_str2mode(const char *name) { return __str2type(name, link_modes, ARRAY_SIZE(link_modes)); } char *rtnl_link_carrier2str(uint8_t st, char *buf, size_t len) { return __type2str(st, buf, len, carrier_states, ARRAY_SIZE(carrier_states)); } int rtnl_link_str2carrier(const char *name) { return __str2type(name, carrier_states, ARRAY_SIZE(carrier_states)); } int rtnl_link_has_vf_list(struct rtnl_link *link) { if (link->ce_mask & LINK_ATTR_VF_LIST) return 1; else return 0; } void rtnl_link_set_vf_list(struct rtnl_link *link) { int err; if (!(err = rtnl_link_has_vf_list(link))) link->ce_mask |= LINK_ATTR_VF_LIST; return; } void rtnl_link_unset_vf_list(struct rtnl_link *link) { int err; if ((err = rtnl_link_has_vf_list(link))) link->ce_mask &= ~LINK_ATTR_VF_LIST; return; } /** @} */ /** * @name Deprecated Functions */ /** * @deprecated Use of this function is deprecated, use rtnl_link_set_type() */ int rtnl_link_set_info_type(struct rtnl_link *link, const char *type) { return rtnl_link_set_type(link, type); } /** * @deprecated Use of this function is deprecated, use rtnl_link_get_type() */ char *rtnl_link_get_info_type(struct rtnl_link *link) { return rtnl_link_get_type(link); } /** * @deprecated The weight attribute is unused and obsoleted in all recent kernels */ void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight) { link->l_weight = weight; link->ce_mask |= LINK_ATTR_WEIGHT; } /** * @deprecated The weight attribute is unused and obsoleted in all recent kernels */ unsigned int rtnl_link_get_weight(struct rtnl_link *link) { return link->l_weight; } /** @} */ static struct nl_object_ops link_obj_ops = { .oo_name = "route/link", .oo_size = sizeof(struct rtnl_link), .oo_free_data = link_free_data, .oo_clone = link_clone, .oo_dump = { [NL_DUMP_LINE] = link_dump_line, [NL_DUMP_DETAILS] = link_dump_details, [NL_DUMP_STATS] = link_dump_stats, }, .oo_compare = link_compare, .oo_keygen = link_keygen, .oo_attrs2str = link_attrs2str, .oo_id_attrs = LINK_ATTR_IFINDEX | LINK_ATTR_FAMILY, }; static struct nl_af_group link_groups[] = { { AF_UNSPEC, RTNLGRP_LINK }, { AF_BRIDGE, RTNLGRP_LINK }, { END_OF_GROUP_LIST }, }; static struct nl_cache_ops rtnl_link_ops = { .co_name = "route/link", .co_hdrsize = sizeof(struct ifinfomsg), .co_msgtypes = { { RTM_NEWLINK, NL_ACT_NEW, "new" }, { RTM_DELLINK, NL_ACT_DEL, "del" }, { RTM_GETLINK, NL_ACT_GET, "get" }, { RTM_SETLINK, NL_ACT_CHANGE, "set" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_groups = link_groups, .co_request_update = link_request_update, .co_msg_parser = link_msg_parser, .co_obj_ops = &link_obj_ops, }; static void __init link_init(void) { nl_cache_mngt_register(&rtnl_link_ops); } static void __exit link_exit(void) { nl_cache_mngt_unregister(&rtnl_link_ops); } /** @} */ libnl-3.2.29/lib/route/cls/0000755000175000017500000000000013031473756012406 500000000000000libnl-3.2.29/lib/route/cls/ematch/0000755000175000017500000000000013031473756013647 500000000000000libnl-3.2.29/lib/route/cls/ematch/meta.c0000644000175000017500000002027113023014600014637 00000000000000/* * lib/route/cls/ematch/meta.c Metadata Match * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2013 Thomas Graf */ /** * @ingroup ematch * @defgroup em_meta Metadata Match * * @{ */ #include #include #include #include #include struct rtnl_meta_value { uint8_t mv_type; uint8_t mv_shift; uint16_t mv_id; size_t mv_len; }; struct meta_data { struct rtnl_meta_value * left; struct rtnl_meta_value * right; uint8_t opnd; }; static struct rtnl_meta_value *meta_alloc(uint8_t type, uint16_t id, uint8_t shift, void *data, size_t len) { struct rtnl_meta_value *value; if (!(value = calloc(1, sizeof(*value) + len))) return NULL; value->mv_type = type; value->mv_id = id; value->mv_shift = shift; value->mv_len = len; if (len) memcpy(value + 1, data, len); return value; } struct rtnl_meta_value *rtnl_meta_value_alloc_int(uint64_t value) { return meta_alloc(TCF_META_TYPE_INT, TCF_META_ID_VALUE, 0, &value, 8); } struct rtnl_meta_value *rtnl_meta_value_alloc_var(void *data, size_t len) { return meta_alloc(TCF_META_TYPE_VAR, TCF_META_ID_VALUE, 0, data, len); } struct rtnl_meta_value *rtnl_meta_value_alloc_id(uint8_t type, uint16_t id, uint8_t shift, uint64_t mask) { size_t masklen = 0; if (id > TCF_META_ID_MAX) return NULL; if (mask) { if (type == TCF_META_TYPE_VAR) return NULL; masklen = 8; } return meta_alloc(type, id, shift, &mask, masklen); } void rtnl_meta_value_put(struct rtnl_meta_value *mv) { free(mv); } void rtnl_ematch_meta_set_lvalue(struct rtnl_ematch *e, struct rtnl_meta_value *v) { struct meta_data *m = rtnl_ematch_data(e); m->left = v; } void rtnl_ematch_meta_set_rvalue(struct rtnl_ematch *e, struct rtnl_meta_value *v) { struct meta_data *m = rtnl_ematch_data(e); m->right = v; } void rtnl_ematch_meta_set_operand(struct rtnl_ematch *e, uint8_t opnd) { struct meta_data *m = rtnl_ematch_data(e); m->opnd = opnd; } static struct nla_policy meta_policy[TCA_EM_META_MAX+1] = { [TCA_EM_META_HDR] = { .minlen = sizeof(struct tcf_meta_hdr) }, [TCA_EM_META_LVALUE] = { .minlen = 1, }, [TCA_EM_META_RVALUE] = { .minlen = 1, }, }; static int meta_parse(struct rtnl_ematch *e, void *data, size_t len) { struct meta_data *m = rtnl_ematch_data(e); struct nlattr *tb[TCA_EM_META_MAX+1]; struct rtnl_meta_value *v; struct tcf_meta_hdr *hdr; void *vdata = NULL; size_t vlen = 0; int err; if ((err = nla_parse(tb, TCA_EM_META_MAX, data, len, meta_policy)) < 0) return err; if (!tb[TCA_EM_META_HDR]) return -NLE_MISSING_ATTR; hdr = nla_data(tb[TCA_EM_META_HDR]); if (tb[TCA_EM_META_LVALUE]) { vdata = nla_data(tb[TCA_EM_META_LVALUE]); vlen = nla_len(tb[TCA_EM_META_LVALUE]); } v = meta_alloc(TCF_META_TYPE(hdr->left.kind), TCF_META_ID(hdr->left.kind), hdr->left.shift, vdata, vlen); if (!v) return -NLE_NOMEM; m->left = v; vlen = 0; if (tb[TCA_EM_META_RVALUE]) { vdata = nla_data(tb[TCA_EM_META_RVALUE]); vlen = nla_len(tb[TCA_EM_META_RVALUE]); } v = meta_alloc(TCF_META_TYPE(hdr->right.kind), TCF_META_ID(hdr->right.kind), hdr->right.shift, vdata, vlen); if (!v) { rtnl_meta_value_put(m->left); return -NLE_NOMEM; } m->right = v; m->opnd = hdr->left.op; return 0; } static const struct trans_tbl meta_int[] = { __ADD(TCF_META_ID_RANDOM, random), __ADD(TCF_META_ID_LOADAVG_0, loadavg_0), __ADD(TCF_META_ID_LOADAVG_1, loadavg_1), __ADD(TCF_META_ID_LOADAVG_2, loadavg_2), __ADD(TCF_META_ID_DEV, dev), __ADD(TCF_META_ID_PRIORITY, prio), __ADD(TCF_META_ID_PROTOCOL, proto), __ADD(TCF_META_ID_PKTTYPE, pkttype), __ADD(TCF_META_ID_PKTLEN, pktlen), __ADD(TCF_META_ID_DATALEN, datalen), __ADD(TCF_META_ID_MACLEN, maclen), __ADD(TCF_META_ID_NFMARK, mark), __ADD(TCF_META_ID_TCINDEX, tcindex), __ADD(TCF_META_ID_RTCLASSID, rtclassid), __ADD(TCF_META_ID_RTIIF, rtiif), __ADD(TCF_META_ID_SK_FAMILY, sk_family), __ADD(TCF_META_ID_SK_STATE, sk_state), __ADD(TCF_META_ID_SK_REUSE, sk_reuse), __ADD(TCF_META_ID_SK_REFCNT, sk_refcnt), __ADD(TCF_META_ID_SK_RCVBUF, sk_rcvbuf), __ADD(TCF_META_ID_SK_SNDBUF, sk_sndbuf), __ADD(TCF_META_ID_SK_SHUTDOWN, sk_sutdown), __ADD(TCF_META_ID_SK_PROTO, sk_proto), __ADD(TCF_META_ID_SK_TYPE, sk_type), __ADD(TCF_META_ID_SK_RMEM_ALLOC, sk_rmem_alloc), __ADD(TCF_META_ID_SK_WMEM_ALLOC, sk_wmem_alloc), __ADD(TCF_META_ID_SK_WMEM_QUEUED, sk_wmem_queued), __ADD(TCF_META_ID_SK_RCV_QLEN, sk_rcv_qlen), __ADD(TCF_META_ID_SK_SND_QLEN, sk_snd_qlen), __ADD(TCF_META_ID_SK_ERR_QLEN, sk_err_qlen), __ADD(TCF_META_ID_SK_FORWARD_ALLOCS, sk_forward_allocs), __ADD(TCF_META_ID_SK_ALLOCS, sk_allocs), __ADD(TCF_META_ID_SK_ROUTE_CAPS, sk_route_caps), __ADD(TCF_META_ID_SK_HASH, sk_hash), __ADD(TCF_META_ID_SK_LINGERTIME, sk_lingertime), __ADD(TCF_META_ID_SK_ACK_BACKLOG, sk_ack_backlog), __ADD(TCF_META_ID_SK_MAX_ACK_BACKLOG, sk_max_ack_backlog), __ADD(TCF_META_ID_SK_PRIO, sk_prio), __ADD(TCF_META_ID_SK_RCVLOWAT, sk_rcvlowat), __ADD(TCF_META_ID_SK_RCVTIMEO, sk_rcvtimeo), __ADD(TCF_META_ID_SK_SNDTIMEO, sk_sndtimeo), __ADD(TCF_META_ID_SK_SENDMSG_OFF, sk_sendmsg_off), __ADD(TCF_META_ID_SK_WRITE_PENDING, sk_write_pending), __ADD(TCF_META_ID_VLAN_TAG, vlan), __ADD(TCF_META_ID_RXHASH, rxhash), }; static char *int_id2str(int id, char *buf, size_t size) { return __type2str(id, buf, size, meta_int, ARRAY_SIZE(meta_int)); } static const struct trans_tbl meta_var[] = { __ADD(TCF_META_ID_DEV,devname), __ADD(TCF_META_ID_SK_BOUND_IF,sk_bound_if), }; static char *var_id2str(int id, char *buf, size_t size) { return __type2str(id, buf, size, meta_var, ARRAY_SIZE(meta_var)); } static void dump_value(struct rtnl_meta_value *v, struct nl_dump_params *p) { char buf[32]; switch (v->mv_type) { case TCF_META_TYPE_INT: if (v->mv_id == TCF_META_ID_VALUE) { nl_dump(p, "%u", *(uint32_t *) (v + 1)); } else { nl_dump(p, "%s", int_id2str(v->mv_id, buf, sizeof(buf))); if (v->mv_shift) nl_dump(p, " >> %u", v->mv_shift); if (v->mv_len == 4) nl_dump(p, " & %#x", *(uint32_t *) (v + 1)); else if (v->mv_len == 8) nl_dump(p, " & %#x", *(uint64_t *) (v + 1)); } break; case TCF_META_TYPE_VAR: if (v->mv_id == TCF_META_ID_VALUE) { nl_dump(p, "%s", (char *) (v + 1)); } else { nl_dump(p, "%s", var_id2str(v->mv_id, buf, sizeof(buf))); if (v->mv_shift) nl_dump(p, " >> %u", v->mv_shift); } break; } } static void meta_dump(struct rtnl_ematch *e, struct nl_dump_params *p) { struct meta_data *m = rtnl_ematch_data(e); char buf[32]; nl_dump(p, "meta("); dump_value(m->left, p); nl_dump(p, " %s ", rtnl_ematch_opnd2txt(m->opnd, buf, sizeof(buf))); dump_value(m->right, p); nl_dump(p, ")"); } static int meta_fill(struct rtnl_ematch *e, struct nl_msg *msg) { struct meta_data *m = rtnl_ematch_data(e); struct tcf_meta_hdr hdr; if (!(m->left && m->right)) return -NLE_MISSING_ATTR; memset(&hdr, 0, sizeof(hdr)); hdr.left.kind = (m->left->mv_type << 12) & TCF_META_TYPE_MASK; hdr.left.kind |= m->left->mv_id & TCF_META_ID_MASK; hdr.left.shift = m->left->mv_shift; hdr.left.op = m->opnd; hdr.right.kind = (m->right->mv_type << 12) & TCF_META_TYPE_MASK; hdr.right.kind |= m->right->mv_id & TCF_META_ID_MASK; NLA_PUT(msg, TCA_EM_META_HDR, sizeof(hdr), &hdr); if (m->left->mv_len) NLA_PUT(msg, TCA_EM_META_LVALUE, m->left->mv_len, (m->left + 1)); if (m->right->mv_len) NLA_PUT(msg, TCA_EM_META_RVALUE, m->right->mv_len, (m->right + 1)); return 0; nla_put_failure: return -NLE_NOMEM; } static void meta_free(struct rtnl_ematch *e) { struct meta_data *m = rtnl_ematch_data(e); free(m->left); free(m->right); } static struct rtnl_ematch_ops meta_ops = { .eo_kind = TCF_EM_META, .eo_name = "meta", .eo_minlen = sizeof(struct tcf_meta_hdr), .eo_datalen = sizeof(struct meta_data), .eo_parse = meta_parse, .eo_dump = meta_dump, .eo_fill = meta_fill, .eo_free = meta_free, }; static void __init meta_init(void) { rtnl_ematch_register(&meta_ops); } /** @} */ libnl-3.2.29/lib/route/cls/ematch/text.c0000644000175000017500000001015213023014600014672 00000000000000/* * lib/route/cls/ematch/text.c Text Search * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2013 Thomas Graf */ /** * @ingroup ematch * @defgroup em_text Text Search * * @{ */ #include #include #include #include #include struct text_data { struct tcf_em_text cfg; char * pattern; }; void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer, uint16_t offset) { struct text_data *t = rtnl_ematch_data(e); t->cfg.from_offset = offset; t->cfg.from_layer = layer; } uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e) { return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset; } uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e) { return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer; } void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer, uint16_t offset) { struct text_data *t = rtnl_ematch_data(e); t->cfg.to_offset = offset; t->cfg.to_layer = layer; } uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e) { return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset; } uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e) { return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer; } void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e, char *pattern, size_t len) { struct text_data *t = rtnl_ematch_data(e); if (t->pattern) free(t->pattern); t->pattern = pattern; t->cfg.pattern_len = len; } char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e) { return ((struct text_data *) rtnl_ematch_data(e))->pattern; } size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e) { return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len; } void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo) { struct text_data *t = rtnl_ematch_data(e); strncpy(t->cfg.algo, algo, sizeof(t->cfg.algo)); } char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e) { struct text_data *t = rtnl_ematch_data(e); return t->cfg.algo[0] ? t->cfg.algo : NULL; } static int text_parse(struct rtnl_ematch *e, void *data, size_t len) { struct text_data *t = rtnl_ematch_data(e); size_t hdrlen = sizeof(struct tcf_em_text); size_t plen = len - hdrlen; memcpy(&t->cfg, data, hdrlen); if (t->cfg.pattern_len > plen) return -NLE_INVAL; if (t->cfg.pattern_len > 0) { if (!(t->pattern = calloc(1, t->cfg.pattern_len))) return -NLE_NOMEM; memcpy(t->pattern, data + hdrlen, t->cfg.pattern_len); } return 0; } static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p) { struct text_data *t = rtnl_ematch_data(e); char buf[64]; nl_dump(p, "text(%s \"%s\"", t->cfg.algo[0] ? t->cfg.algo : "no-algo", t->pattern ? : "no-pattern"); if (t->cfg.from_layer || t->cfg.from_offset) { nl_dump(p, " from %s", rtnl_ematch_offset2txt(t->cfg.from_layer, t->cfg.from_offset, buf, sizeof(buf))); } if (t->cfg.to_layer || t->cfg.to_offset) { nl_dump(p, " to %s", rtnl_ematch_offset2txt(t->cfg.to_layer, t->cfg.to_offset, buf, sizeof(buf))); } nl_dump(p, ")"); } static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg) { struct text_data *t = rtnl_ematch_data(e); int err; if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0) return err; return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0); } static void text_free(struct rtnl_ematch *e) { struct text_data *t = rtnl_ematch_data(e); free(t->pattern); } static struct rtnl_ematch_ops text_ops = { .eo_kind = TCF_EM_TEXT, .eo_name = "text", .eo_minlen = sizeof(struct tcf_em_text), .eo_datalen = sizeof(struct text_data), .eo_parse = text_parse, .eo_dump = text_dump, .eo_fill = text_fill, .eo_free = text_free, }; static void __init text_init(void) { rtnl_ematch_register(&text_ops); } /** @} */ libnl-3.2.29/lib/route/cls/ematch/nbyte.c0000644000175000017500000000566713023014600015046 00000000000000/* * lib/route/cls/ematch/nbyte.c Nbyte comparison * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2013 Thomas Graf */ /** * @ingroup ematch * @defgroup em_nbyte N-Byte Comparison * * @{ */ #include #include #include #include #include struct nbyte_data { struct tcf_em_nbyte cfg; uint8_t * pattern; }; void rtnl_ematch_nbyte_set_offset(struct rtnl_ematch *e, uint8_t layer, uint16_t offset) { struct nbyte_data *n = rtnl_ematch_data(e); n->cfg.off = offset; n->cfg.layer = layer; } uint16_t rtnl_ematch_nbyte_get_offset(struct rtnl_ematch *e) { return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.off; } uint8_t rtnl_ematch_nbyte_get_layer(struct rtnl_ematch *e) { return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.layer; } void rtnl_ematch_nbyte_set_pattern(struct rtnl_ematch *e, uint8_t *pattern, size_t len) { struct nbyte_data *n = rtnl_ematch_data(e); if (n->pattern) free(n->pattern); n->pattern = pattern; n->cfg.len = len; } uint8_t *rtnl_ematch_nbyte_get_pattern(struct rtnl_ematch *e) { return ((struct nbyte_data *) rtnl_ematch_data(e))->pattern; } size_t rtnl_ematch_nbyte_get_len(struct rtnl_ematch *e) { return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.len; } static const char *layer_txt(struct tcf_em_nbyte *nbyte) { switch (nbyte->layer) { case TCF_LAYER_LINK: return "link"; case TCF_LAYER_NETWORK: return "net"; case TCF_LAYER_TRANSPORT: return "trans"; default: return "?"; } } static int nbyte_parse(struct rtnl_ematch *e, void *data, size_t len) { struct nbyte_data *n = rtnl_ematch_data(e); size_t hdrlen = sizeof(struct tcf_em_nbyte); size_t plen = len - hdrlen; memcpy(&n->cfg, data, hdrlen); if (plen > 0) { if (!(n->pattern = calloc(1, plen))) return -NLE_NOMEM; memcpy(n->pattern, data + hdrlen, plen); } return 0; } static void nbyte_dump(struct rtnl_ematch *e, struct nl_dump_params *p) { struct nbyte_data *n = rtnl_ematch_data(e); int i; nl_dump(p, "pattern(%u:[", n->cfg.len); for (i = 0; i < n->cfg.len; i++) { nl_dump(p, "%02x", n->pattern[i]); if (i+1 < n->cfg.len) nl_dump(p, " "); } nl_dump(p, "] at %s+%u)", layer_txt(&n->cfg), n->cfg.off); } static void nbyte_free(struct rtnl_ematch *e) { struct nbyte_data *n = rtnl_ematch_data(e); free(n->pattern); } static struct rtnl_ematch_ops nbyte_ops = { .eo_kind = TCF_EM_NBYTE, .eo_name = "nbyte", .eo_minlen = sizeof(struct tcf_em_nbyte), .eo_datalen = sizeof(struct nbyte_data), .eo_parse = nbyte_parse, .eo_dump = nbyte_dump, .eo_free = nbyte_free, }; static void __init nbyte_init(void) { rtnl_ematch_register(&nbyte_ops); } /** @} */ libnl-3.2.29/lib/route/cls/ematch/container.c0000644000175000017500000000247013023014600015674 00000000000000/* * lib/route/cls/ematch/container.c Container Ematch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2013 Thomas Graf */ #include #include #include #include static int container_parse(struct rtnl_ematch *e, void *data, size_t len __attribute__((unused))) { /* The kernel may provide more than 4 bytes of data in the future and we want older libnl versions to be ok with that. We want interfaces to be growable so we only ever enforce a minimum data length and copy as much as we are aware of. Thomas Graf. */ memcpy(e->e_data, data, sizeof(uint32_t)); return 0; } static int container_fill(struct rtnl_ematch *e, struct nl_msg *msg) { return nlmsg_append(msg, e->e_data, sizeof(uint32_t), 0); } static struct rtnl_ematch_ops container_ops = { .eo_kind = TCF_EM_CONTAINER, .eo_name = "container", .eo_minlen = sizeof(uint32_t), .eo_datalen = sizeof(uint32_t), .eo_parse = container_parse, .eo_fill = container_fill, }; static void __init container_init(void) { rtnl_ematch_register(&container_ops); } libnl-3.2.29/lib/route/cls/ematch/cmp.c0000644000175000017500000000415013023014600014466 00000000000000/* * lib/route/cls/ematch/cmp.c Simple packet data comparison ematch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2013 Thomas Graf */ /** * @ingroup ematch * @defgroup em_cmp Simple packet data comparison * * @{ */ #include #include #include #include #include #include void rtnl_ematch_cmp_set(struct rtnl_ematch *e, struct tcf_em_cmp *cfg) { memcpy(rtnl_ematch_data(e), cfg, sizeof(*cfg)); } struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *e) { return rtnl_ematch_data(e); } static int cmp_parse(struct rtnl_ematch *e, void *data, size_t len) { memcpy(rtnl_ematch_data(e), data, len); return 0; } static const char *align_txt[] = { [TCF_EM_ALIGN_U8] = "u8", [TCF_EM_ALIGN_U16] = "u16", [TCF_EM_ALIGN_U32] = "u32" }; static const char *layer_txt[] = { [TCF_LAYER_LINK] = "eth", [TCF_LAYER_NETWORK] = "ip", [TCF_LAYER_TRANSPORT] = "tcp" }; static const char *operand_txt[] = { [TCF_EM_OPND_EQ] = "=", [TCF_EM_OPND_LT] = "<", [TCF_EM_OPND_GT] = ">", }; static void cmp_dump(struct rtnl_ematch *e, struct nl_dump_params *p) { struct tcf_em_cmp *cmp = rtnl_ematch_data(e); if (cmp->flags & TCF_EM_CMP_TRANS) nl_dump(p, "ntoh%c(", (cmp->align == TCF_EM_ALIGN_U32) ? 'l' : 's'); nl_dump(p, "%s at %s+%u", align_txt[cmp->align], layer_txt[cmp->layer], cmp->off); if (cmp->mask) nl_dump(p, " & 0x%x", cmp->mask); if (cmp->flags & TCF_EM_CMP_TRANS) nl_dump(p, ")"); nl_dump(p, " %s %u", operand_txt[cmp->opnd], cmp->val); } static struct rtnl_ematch_ops cmp_ops = { .eo_kind = TCF_EM_CMP, .eo_name = "cmp", .eo_minlen = sizeof(struct tcf_em_cmp), .eo_datalen = sizeof(struct tcf_em_cmp), .eo_parse = cmp_parse, .eo_dump = cmp_dump, }; static void __init cmp_init(void) { rtnl_ematch_register(&cmp_ops); } /** @} */ libnl-3.2.29/lib/route/cls/ematch_grammar.l0000644000175000017500000001021013023014600015420 00000000000000/* * lib/route/cls/ematch_grammar.l ematch expression grammar * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2013 Thomas Graf */ %{ #include #include #include #include #include #include "ematch_syntax.h" %} %option 8bit %option reentrant %option warn %option noyywrap %option noinput %option nounput %option bison-bridge %option prefix="ematch_" %x QUOTE %% [ \t\r\n]+ \" { NL_DBG(4, "Beginning of quote\n"); yylval->q.len = 32; if (!(yylval->q.data = calloc(1, yylval->q.len))) return ERROR; yylval->q.index = 0; BEGIN(QUOTE); } [^\\\n\"]+ { memcpy(yylval->q.data + yylval->q.index, yytext, strlen(yytext)); yylval->q.index += strlen(yytext); } \" { BEGIN(0); return QUOTED; } [[:digit:]]+ | 0[xX][[:xdigit:]]+ { yylval->i = strtoul(yytext, NULL, 0); return NUMBER; } eq | "=" return KW_EQ; gt | ">" return KW_GT; lt | "<" return KW_LT; [aA][nN][dD] | "&&" { yylval->i = TCF_EM_REL_AND; return LOGIC; } [oO][rR] | "||" { yylval->i = TCF_EM_REL_OR; return LOGIC; } [nN][oO][tT] | "!" return NOT; [cC][mM][pP] { yylval->i = TCF_EM_CMP; return EMATCH_CMP; } [pP][aA][tT][tT][eE][rR][nN] { yylval->i = TCF_EM_NBYTE; return EMATCH_NBYTE; } [tT][eE][xX][tT] { yylval->i = TCF_EM_TEXT; return EMATCH_TEXT; } [mM][eE][tT][aA] { yylval->i = TCF_EM_META; return EMATCH_META; } "(" return KW_OPEN; ")" return KW_CLOSE; [mM][aA][sS][kK] | "&" return KW_MASK; [sS][hH][iI][fF][tT] | ">>" return KW_SHIFT; [aA][tT] return KW_AT; "+" return KW_PLUS; [fF][rR][oO][mM] return KW_FROM; [tT][oO] return KW_TO; [uU]8 { yylval->i = TCF_EM_ALIGN_U8; return ALIGN; } [uU]16 { yylval->i = TCF_EM_ALIGN_U16; return ALIGN; } [uU]32 { yylval->i = TCF_EM_ALIGN_U32; return ALIGN; } [lL][iI][nN][kK] | [eE][tT][hH] { yylval->i = TCF_LAYER_LINK; return LAYER; } [nN][eE][tT] | [iI][pP]6 | [iI][pP] { yylval->i = TCF_LAYER_NETWORK; return LAYER; } [tT][rR][aA][nN][sS][pP][oO][rR][tT] | [tT][cC][pP] { yylval->i = TCF_LAYER_TRANSPORT; return LAYER; } random return META_RANDOM; loadavg_0 return META_LOADAVG_0; loadavg_1 return META_LOADAVG_1; loadavg_2 return META_LOADAVG_2; dev return META_DEV; prio return META_PRIO; proto return META_PROTO; pkttype return META_PKTTYPE; pktlen return META_PKTLEN; datalen return META_DATALEN; maclen return META_MACLEN; mark return META_MARK; tcindex return META_TCINDEX; rtclassid return META_RTCLASSID; rtiif return META_RTIIF; sk_family return META_SK_FAMILY; sk_state return META_SK_STATE; sk_reuse return META_SK_REUSE; sk_refcnt return META_SK_REFCNT; sk_rcvbuf return META_SK_RCVBUF; sk_sndbuf return META_SK_SNDBUF; sk_shutdown return META_SK_SHUTDOWN; sk_proto return META_SK_PROTO; sk_type return META_SK_TYPE; sk_rmem_alloc return META_SK_RMEM_ALLOC; sk_wmem_alloc return META_SK_WMEM_ALLOC; sk_wmem_queued return META_SK_WMEM_QUEUED; sk_rcv_qlen return META_SK_RCV_QLEN; sk_snd_qlen return META_SK_SND_QLEN; sk_err_qlen return META_SK_ERR_QLEN; sk_forward_allocs return META_SK_FORWARD_ALLOCS; sk_allocs return META_SK_ALLOCS; sk_route_caps return META_SK_ROUTE_CAPS; sk_hash return META_SK_HASH; sk_lingertime return META_SK_LINGERTIME; sk_ack_backlog return META_SK_ACK_BACKLOG; sk_max_ack_backlog return META_SK_MAX_ACK_BACKLOG; sk_prio return META_SK_PRIO; sk_rcvlowat return META_SK_RCVLOWAT; sk_rcvtimeo return META_SK_RCVTIMEO; sk_sndtimeo return META_SK_SNDTIMEO; sk_sendmsg_off return META_SK_SENDMSG_OFF; sk_write_pending return META_SK_WRITE_PENDING; vlan return META_VLAN; rxhash return META_RXHASH; devname return META_DEVNAME; sk_bound_if return META_SK_BOUND_IF; [^ \t\r\n+()=<>&|\"]+ { yylval->s = strdup(yytext); if (yylval->s == NULL) return ERROR; NL_DBG(4, "lex STR=%s\n", yylval->s); return STR; } libnl-3.2.29/lib/route/cls/ematch_syntax.y0000644000175000017500000002653113023014600015352 00000000000000/* * lib/route/cls/ematch_syntax.y ematch expression syntax * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2013 Thomas Graf */ %{ #include #include #include #include #include #include #include #include #include #include #define META_ALLOC rtnl_meta_value_alloc_id #define META_ID(name) TCF_META_ID_##name #define META_INT TCF_META_TYPE_INT #define META_VAR TCF_META_TYPE_VAR %} %error-verbose %define api.pure %name-prefix "ematch_" %parse-param {void *scanner} %parse-param {char **errp} %parse-param {struct nl_list_head *root} %lex-param {void *scanner} %union { struct tcf_em_cmp cmp; struct ematch_quoted q; struct rtnl_ematch * e; struct rtnl_pktloc * loc; struct rtnl_meta_value *mv; uint32_t i; uint64_t i64; char * s; } %{ extern int ematch_lex(YYSTYPE *, void *); static void yyerror(void *scanner, char **errp, struct nl_list_head *root, const char *msg) { if (msg) *errp = strdup(msg); else *errp = NULL; } %} %token ERROR LOGIC NOT OPERAND NUMBER ALIGN LAYER %token KW_OPEN "(" %token KW_CLOSE ")" %token KW_PLUS "+" %token KW_MASK "mask" %token KW_SHIFT ">>" %token KW_AT "at" %token EMATCH_CMP "cmp" %token EMATCH_NBYTE "pattern" %token EMATCH_TEXT "text" %token EMATCH_META "meta" %token KW_EQ "=" %token KW_GT ">" %token KW_LT "<" %token KW_FROM "from" %token KW_TO "to" %token META_RANDOM "random" %token META_LOADAVG_0 "loadavg_0" %token META_LOADAVG_1 "loadavg_1" %token META_LOADAVG_2 "loadavg_2" %token META_DEV "dev" %token META_PRIO "prio" %token META_PROTO "proto" %token META_PKTTYPE "pkttype" %token META_PKTLEN "pktlen" %token META_DATALEN "datalen" %token META_MACLEN "maclen" %token META_MARK "mark" %token META_TCINDEX "tcindex" %token META_RTCLASSID "rtclassid" %token META_RTIIF "rtiif" %token META_SK_FAMILY "sk_family" %token META_SK_STATE "sk_state" %token META_SK_REUSE "sk_reuse" %token META_SK_REFCNT "sk_refcnt" %token META_SK_RCVBUF "sk_rcvbuf" %token META_SK_SNDBUF "sk_sndbuf" %token META_SK_SHUTDOWN "sk_shutdown" %token META_SK_PROTO "sk_proto" %token META_SK_TYPE "sk_type" %token META_SK_RMEM_ALLOC "sk_rmem_alloc" %token META_SK_WMEM_ALLOC "sk_wmem_alloc" %token META_SK_WMEM_QUEUED "sk_wmem_queued" %token META_SK_RCV_QLEN "sk_rcv_qlen" %token META_SK_SND_QLEN "sk_snd_qlen" %token META_SK_ERR_QLEN "sk_err_qlen" %token META_SK_FORWARD_ALLOCS "sk_forward_allocs" %token META_SK_ALLOCS "sk_allocs" %token META_SK_ROUTE_CAPS "sk_route_caps" %token META_SK_HASH "sk_hash" %token META_SK_LINGERTIME "sk_lingertime" %token META_SK_ACK_BACKLOG "sk_ack_backlog" %token META_SK_MAX_ACK_BACKLOG "sk_max_ack_backlog" %token META_SK_PRIO "sk_prio" %token META_SK_RCVLOWAT "sk_rcvlowat" %token META_SK_RCVTIMEO "sk_rcvtimeo" %token META_SK_SNDTIMEO "sk_sndtimeo" %token META_SK_SENDMSG_OFF "sk_sendmsg_off" %token META_SK_WRITE_PENDING "sk_write_pending" %token META_VLAN "vlan" %token META_RXHASH "rxhash" %token META_DEVNAME "devname" %token META_SK_BOUND_IF "sk_bound_if" %token STR %token QUOTED %type align operand shift meta_int_id meta_var_id %type mask %type expr match ematch %type cmp_expr cmp_match %type pktloc text_from text_to %type pattern %type meta_value %destructor { free($$); NL_DBG(2, "string destructor\n"); } %destructor { rtnl_pktloc_put($$); NL_DBG(2, "pktloc destructor\n"); } %destructor { free($$.data); NL_DBG(2, "quoted destructor\n"); } %destructor { rtnl_meta_value_put($$); NL_DBG(2, "meta value destructor\n"); } %start input %% input: /* empty */ | expr { nl_list_add_tail(root, &$1->e_list); } ; expr: match { $$ = $1; } | match LOGIC expr { rtnl_ematch_set_flags($1, $2); /* make ematch new head */ nl_list_add_tail(&$1->e_list, &$3->e_list); $$ = $1; } ; match: NOT ematch { rtnl_ematch_set_flags($2, TCF_EM_INVERT); $$ = $2; } | ematch { $$ = $1; } ; ematch: /* CMP */ cmp_match { struct rtnl_ematch *e; if (!(e = rtnl_ematch_alloc())) { *errp = strdup("Unable to allocate ematch object"); YYABORT; } if (rtnl_ematch_set_kind(e, TCF_EM_CMP) < 0) BUG(); rtnl_ematch_cmp_set(e, &$1); $$ = e; } | EMATCH_NBYTE "(" pktloc KW_EQ pattern ")" { struct rtnl_ematch *e; if (!(e = rtnl_ematch_alloc())) { *errp = strdup("Unable to allocate ematch object"); YYABORT; } if (rtnl_ematch_set_kind(e, TCF_EM_NBYTE) < 0) BUG(); rtnl_ematch_nbyte_set_offset(e, $3->layer, $3->offset); rtnl_pktloc_put($3); rtnl_ematch_nbyte_set_pattern(e, (uint8_t *) $5.data, $5.index); $$ = e; } | EMATCH_TEXT "(" STR QUOTED text_from text_to ")" { struct rtnl_ematch *e; if (!(e = rtnl_ematch_alloc())) { *errp = strdup("Unable to allocate ematch object"); YYABORT; } if (rtnl_ematch_set_kind(e, TCF_EM_TEXT) < 0) BUG(); rtnl_ematch_text_set_algo(e, $3); rtnl_ematch_text_set_pattern(e, $4.data, $4.index); if ($5) { rtnl_ematch_text_set_from(e, $5->layer, $5->offset); rtnl_pktloc_put($5); } if ($6) { rtnl_ematch_text_set_to(e, $6->layer, $6->offset); rtnl_pktloc_put($6); } $$ = e; } | EMATCH_META "(" meta_value operand meta_value ")" { struct rtnl_ematch *e; if (!(e = rtnl_ematch_alloc())) { *errp = strdup("Unable to allocate ematch object"); YYABORT; } if (rtnl_ematch_set_kind(e, TCF_EM_META) < 0) BUG(); rtnl_ematch_meta_set_lvalue(e, $3); rtnl_ematch_meta_set_rvalue(e, $5); rtnl_ematch_meta_set_operand(e, $4); $$ = e; } /* CONTAINER */ | "(" expr ")" { struct rtnl_ematch *e; if (!(e = rtnl_ematch_alloc())) { *errp = strdup("Unable to allocate ematch object"); YYABORT; } if (rtnl_ematch_set_kind(e, TCF_EM_CONTAINER) < 0) BUG(); /* Make e->childs the list head of a the ematch sequence */ nl_list_add_tail(&e->e_childs, &$2->e_list); $$ = e; } ; /* * CMP match * * match := cmp(expr) | expr * expr := pktloc (=|>|<) NUMBER * pktloc := alias | definition * */ cmp_match: EMATCH_CMP "(" cmp_expr ")" { $$ = $3; } | cmp_expr { $$ = $1; } ; cmp_expr: pktloc operand NUMBER { if ($1->align == TCF_EM_ALIGN_U16 || $1->align == TCF_EM_ALIGN_U32) $$.flags = TCF_EM_CMP_TRANS; memset(&$$, 0, sizeof($$)); $$.mask = $1->mask; $$.off = $1->offset; $$.align = $1->align; $$.layer = $1->layer; $$.opnd = $2; $$.val = $3; rtnl_pktloc_put($1); } ; text_from: /* empty */ { $$ = NULL; } | "from" pktloc { $$ = $2; } ; text_to: /* empty */ { $$ = NULL; } | "to" pktloc { $$ = $2; } ; meta_value: QUOTED { $$ = rtnl_meta_value_alloc_var($1.data, $1.len); } | NUMBER { $$ = rtnl_meta_value_alloc_int($1); } | meta_int_id shift mask { $$ = META_ALLOC(META_INT, $1, $2, $3); } | meta_var_id shift { $$ = META_ALLOC(META_VAR, $1, $2, 0); } ; meta_int_id: META_RANDOM { $$ = META_ID(RANDOM); } |META_LOADAVG_0 { $$ = META_ID(LOADAVG_0); } |META_LOADAVG_1 { $$ = META_ID(LOADAVG_1); } |META_LOADAVG_2 { $$ = META_ID(LOADAVG_2); } | META_DEV { $$ = META_ID(DEV); } | META_PRIO { $$ = META_ID(PRIORITY); } | META_PROTO { $$ = META_ID(PROTOCOL); } | META_PKTTYPE { $$ = META_ID(PKTTYPE); } | META_PKTLEN { $$ = META_ID(PKTLEN); } | META_DATALEN { $$ = META_ID(DATALEN); } | META_MACLEN { $$ = META_ID(MACLEN); } | META_MARK { $$ = META_ID(NFMARK); } | META_TCINDEX { $$ = META_ID(TCINDEX); } | META_RTCLASSID { $$ = META_ID(RTCLASSID); } | META_RTIIF { $$ = META_ID(RTIIF); } | META_SK_FAMILY { $$ = META_ID(SK_FAMILY); } | META_SK_STATE { $$ = META_ID(SK_STATE); } | META_SK_REUSE { $$ = META_ID(SK_REUSE); } | META_SK_REFCNT { $$ = META_ID(SK_REFCNT); } | META_SK_RCVBUF { $$ = META_ID(SK_RCVBUF); } | META_SK_SNDBUF { $$ = META_ID(SK_SNDBUF); } | META_SK_SHUTDOWN { $$ = META_ID(SK_SHUTDOWN); } | META_SK_PROTO { $$ = META_ID(SK_PROTO); } | META_SK_TYPE { $$ = META_ID(SK_TYPE); } | META_SK_RMEM_ALLOC { $$ = META_ID(SK_RMEM_ALLOC); } | META_SK_WMEM_ALLOC { $$ = META_ID(SK_WMEM_ALLOC); } | META_SK_WMEM_QUEUED { $$ = META_ID(SK_WMEM_QUEUED); } | META_SK_RCV_QLEN { $$ = META_ID(SK_RCV_QLEN); } | META_SK_SND_QLEN { $$ = META_ID(SK_SND_QLEN); } | META_SK_ERR_QLEN { $$ = META_ID(SK_ERR_QLEN); } | META_SK_FORWARD_ALLOCS { $$ = META_ID(SK_FORWARD_ALLOCS); } | META_SK_ALLOCS { $$ = META_ID(SK_ALLOCS); } | META_SK_ROUTE_CAPS { $$ = META_ID(SK_ROUTE_CAPS); } | META_SK_HASH { $$ = META_ID(SK_HASH); } | META_SK_LINGERTIME { $$ = META_ID(SK_LINGERTIME); } | META_SK_ACK_BACKLOG { $$ = META_ID(SK_ACK_BACKLOG); } | META_SK_MAX_ACK_BACKLOG { $$ = META_ID(SK_MAX_ACK_BACKLOG); } | META_SK_PRIO { $$ = META_ID(SK_PRIO); } | META_SK_RCVLOWAT { $$ = META_ID(SK_RCVLOWAT); } | META_SK_RCVTIMEO { $$ = META_ID(SK_RCVTIMEO); } | META_SK_SNDTIMEO { $$ = META_ID(SK_SNDTIMEO); } | META_SK_SENDMSG_OFF { $$ = META_ID(SK_SENDMSG_OFF); } | META_SK_WRITE_PENDING { $$ = META_ID(SK_WRITE_PENDING); } | META_VLAN { $$ = META_ID(VLAN_TAG); } | META_RXHASH { $$ = META_ID(RXHASH); } ; meta_var_id: META_DEVNAME { $$ = META_ID(DEV); } | META_SK_BOUND_IF { $$ = META_ID(SK_BOUND_IF); } ; /* * pattern */ pattern: QUOTED { $$ = $1; } | STR { struct nl_addr *addr; if (nl_addr_parse($1, AF_UNSPEC, &addr) == 0) { $$.len = nl_addr_get_len(addr); $$.index = min_t(int, $$.len, nl_addr_get_prefixlen(addr)/8); if (!($$.data = calloc(1, $$.len))) { nl_addr_put(addr); YYABORT; } memcpy($$.data, nl_addr_get_binary_addr(addr), $$.len); nl_addr_put(addr); } else { if (asprintf(errp, "invalid pattern \"%s\"", $1) == -1) *errp = NULL; YYABORT; } } ; /* * packet location */ pktloc: STR { struct rtnl_pktloc *loc; if (rtnl_pktloc_lookup($1, &loc) < 0) { if (asprintf(errp, "Packet location \"%s\" not found", $1) == -1) *errp = NULL; YYABORT; } $$ = loc; } /* [u8|u16|u32|NUM at] LAYER + OFFSET [mask MASK] */ | align LAYER "+" NUMBER mask { struct rtnl_pktloc *loc; if ($5 && (!$1 || $1 > TCF_EM_ALIGN_U32)) { *errp = strdup("mask only allowed for alignments u8|u16|u32"); YYABORT; } if (!(loc = rtnl_pktloc_alloc())) { *errp = strdup("Unable to allocate packet location object"); YYABORT; } loc->name = strdup(""); loc->align = $1; loc->layer = $2; loc->offset = $4; loc->mask = $5; $$ = loc; } ; align: /* empty */ { $$ = 0; } | ALIGN "at" { $$ = $1; } | NUMBER "at" { $$ = $1; } ; mask: /* empty */ { $$ = 0; } | KW_MASK NUMBER { $$ = $2; } ; shift: /* empty */ { $$ = 0; } | KW_SHIFT NUMBER { $$ = $2; } ; operand: KW_EQ { $$ = TCF_EM_OPND_EQ; } | KW_GT { $$ = TCF_EM_OPND_GT; } | KW_LT { $$ = TCF_EM_OPND_LT; } ; libnl-3.2.29/lib/route/cls/cgroup.c0000644000175000017500000000713713023014600013755 00000000000000/* * lib/route/cls/cgroup.c Control Groups Classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2009-2013 Thomas Graf */ /** * @ingroup cls * @defgroup cls_cgroup Control Groups Classifier * * @{ */ #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define CGROUP_ATTR_EMATCH 0x001 /** @endcond */ static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = { [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, }; static int cgroup_clone(void *dst, void *src) { return -NLE_OPNOTSUPP; } static void cgroup_free_data(struct rtnl_tc *tc, void *data) { struct rtnl_cgroup *c = data; if (!c) return; rtnl_ematch_tree_free(c->cg_ematch); } static int cgroup_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_CGROUP_MAX + 1]; struct rtnl_cgroup *c = data; int err; err = tca_parse(tb, TCA_CGROUP_MAX, tc, cgroup_policy); if (err < 0) return err; if (tb[TCA_CGROUP_EMATCHES]) { if ((err = rtnl_ematch_parse_attr(tb[TCA_CGROUP_EMATCHES], &c->cg_ematch)) < 0) return err; c->cg_mask |= CGROUP_ATTR_EMATCH; } #if 0 TODO: TCA_CGROUP_ACT, TCA_CGROUP_POLICE, #endif return 0; } static void cgroup_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_cgroup *c = data; if (!c) return; if (c->cg_mask & CGROUP_ATTR_EMATCH) nl_dump(p, " ematch"); else nl_dump(p, " match-all"); } static void cgroup_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_cgroup *c = data; if (!c) return; if (c->cg_mask & CGROUP_ATTR_EMATCH) { nl_dump_line(p, " ematch "); if (c->cg_ematch) rtnl_ematch_tree_dump(c->cg_ematch, p); else nl_dump(p, ""); } else nl_dump(p, "no options"); } static int cgroup_fill_msg(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_cgroup *c = data; if (!c) BUG(); if (!(tc->ce_mask & TCA_ATTR_HANDLE)) return -NLE_MISSING_ATTR; if (c->cg_mask & CGROUP_ATTR_EMATCH) return rtnl_ematch_fill_attr(msg, TCA_CGROUP_EMATCHES, c->cg_ematch); return 0; } /** * @name Attribute Modifications * @{ */ void rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) { struct rtnl_cgroup *c; if (!(c = rtnl_tc_data(TC_CAST(cls)))) BUG(); if (c->cg_ematch) { rtnl_ematch_tree_free(c->cg_ematch); c->cg_mask &= ~CGROUP_ATTR_EMATCH; } c->cg_ematch = tree; if (tree) c->cg_mask |= CGROUP_ATTR_EMATCH; } struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls) { struct rtnl_cgroup *c; if (!(c = rtnl_tc_data(TC_CAST(cls)))) BUG(); return c->cg_ematch; } /** @} */ static struct rtnl_tc_ops cgroup_ops = { .to_kind = "cgroup", .to_type = RTNL_TC_TYPE_CLS, .to_size = sizeof(struct rtnl_cgroup), .to_clone = cgroup_clone, .to_msg_parser = cgroup_msg_parser, .to_free_data = cgroup_free_data, .to_msg_fill = cgroup_fill_msg, .to_dump = { [NL_DUMP_LINE] = cgroup_dump_line, [NL_DUMP_DETAILS] = cgroup_dump_details, }, }; static void __init cgroup_init(void) { rtnl_tc_register(&cgroup_ops); } static void __exit cgroup_exit(void) { rtnl_tc_unregister(&cgroup_ops); } /** @} */ libnl-3.2.29/lib/route/cls/ematch.c0000644000175000017500000003535713023014600013724 00000000000000/* * lib/route/cls/ematch.c Extended Matches * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2013 Thomas Graf */ /** * @ingroup cls * @defgroup ematch Extended Match * * @{ */ #include #include #include #include #include #include #include "ematch_syntax.h" #include "ematch_grammar.h" /** * @name Module API * @{ */ static NL_LIST_HEAD(ematch_ops_list); /** * Register ematch module * @arg ops Module operations. * * This function must be called by each ematch module at initialization * time. It registers the calling module as available module. * * @return 0 on success or a negative error code. */ int rtnl_ematch_register(struct rtnl_ematch_ops *ops) { if (rtnl_ematch_lookup_ops(ops->eo_kind)) return -NLE_EXIST; NL_DBG(1, "ematch module \"%s\" registered\n", ops->eo_name); nl_list_add_tail(&ops->eo_list, &ematch_ops_list); return 0; } /** * Lookup ematch module by identification number. * @arg kind Module kind. * * Searches the list of registered ematch modules for match and returns it. * * @return Module operations or NULL if not found. */ struct rtnl_ematch_ops *rtnl_ematch_lookup_ops(int kind) { struct rtnl_ematch_ops *ops; nl_list_for_each_entry(ops, &ematch_ops_list, eo_list) if (ops->eo_kind == kind) return ops; return NULL; } /** * Lookup ematch module by name * @arg name Name of ematch module. * * Searches the list of registered ematch modules for a match and returns it. * * @return Module operations or NULL if not fuond. */ struct rtnl_ematch_ops *rtnl_ematch_lookup_ops_by_name(const char *name) { struct rtnl_ematch_ops *ops; nl_list_for_each_entry(ops, &ematch_ops_list, eo_list) if (!strcasecmp(ops->eo_name, name)) return ops; return NULL; } /** @} */ /** * @name Match */ /** * Allocate ematch object. * * Allocates and initializes an ematch object. * * @return New ematch object or NULL. */ struct rtnl_ematch *rtnl_ematch_alloc(void) { struct rtnl_ematch *e; if (!(e = calloc(1, sizeof(*e)))) return NULL; NL_DBG(2, "allocated ematch %p\n", e); NL_INIT_LIST_HEAD(&e->e_list); NL_INIT_LIST_HEAD(&e->e_childs); return e; } /** * Add ematch to the end of the parent's list of children. * @arg parent parent ematch object * @arg child ematch object to be added to parent * * The parent must be a container ematch. */ int rtnl_ematch_add_child(struct rtnl_ematch *parent, struct rtnl_ematch *child) { if (parent->e_kind != TCF_EM_CONTAINER) return -NLE_OPNOTSUPP; NL_DBG(2, "added ematch %p \"%s\" to container %p\n", child, child->e_ops->eo_name, parent); nl_list_add_tail(&child->e_list, &parent->e_childs); return 0; } /** * Remove ematch from the list of ematches it is linked to. * @arg ematch ematch object */ void rtnl_ematch_unlink(struct rtnl_ematch *ematch) { NL_DBG(2, "unlinked ematch %p from any lists\n", ematch); if (!nl_list_empty(&ematch->e_childs)) NL_DBG(1, "warning: ematch %p with childs was unlinked\n", ematch); nl_list_del(&ematch->e_list); nl_init_list_head(&ematch->e_list); } void rtnl_ematch_free(struct rtnl_ematch *ematch) { NL_DBG(2, "freed ematch %p\n", ematch); rtnl_ematch_unlink(ematch); free(ematch->e_data); free(ematch); } int rtnl_ematch_set_ops(struct rtnl_ematch *ematch, struct rtnl_ematch_ops *ops) { if (ematch->e_ops) return -NLE_EXIST; ematch->e_ops = ops; ematch->e_kind = ops->eo_kind; if (ops->eo_datalen) { ematch->e_data = calloc(1, ops->eo_datalen); if (!ematch->e_data) return -NLE_NOMEM; ematch->e_datalen = ops->eo_datalen; } return 0; } int rtnl_ematch_set_kind(struct rtnl_ematch *ematch, uint16_t kind) { struct rtnl_ematch_ops *ops; if (ematch->e_kind) return -NLE_EXIST; ematch->e_kind = kind; if ((ops = rtnl_ematch_lookup_ops(kind))) rtnl_ematch_set_ops(ematch, ops); return 0; } int rtnl_ematch_set_name(struct rtnl_ematch *ematch, const char *name) { struct rtnl_ematch_ops *ops; if (ematch->e_kind) return -NLE_EXIST; if (!(ops = rtnl_ematch_lookup_ops_by_name(name))) return -NLE_OPNOTSUPP; rtnl_ematch_set_ops(ematch, ops); return 0; } void rtnl_ematch_set_flags(struct rtnl_ematch *ematch, uint16_t flags) { ematch->e_flags |= flags; } void rtnl_ematch_unset_flags(struct rtnl_ematch *ematch, uint16_t flags) { ematch->e_flags &= ~flags; } uint16_t rtnl_ematch_get_flags(struct rtnl_ematch *ematch) { return ematch->e_flags; } void *rtnl_ematch_data(struct rtnl_ematch *ematch) { return ematch->e_data; } /** @} */ /** * @name Tree */ /** * Allocate ematch tree object * @arg progid program id */ struct rtnl_ematch_tree *rtnl_ematch_tree_alloc(uint16_t progid) { struct rtnl_ematch_tree *tree; if (!(tree = calloc(1, sizeof(*tree)))) return NULL; NL_INIT_LIST_HEAD(&tree->et_list); tree->et_progid = progid; NL_DBG(2, "allocated new ematch tree %p, progid=%u\n", tree, progid); return tree; } static void free_ematch_list(struct nl_list_head *head) { struct rtnl_ematch *pos, *next; nl_list_for_each_entry_safe(pos, next, head, e_list) { if (!nl_list_empty(&pos->e_childs)) free_ematch_list(&pos->e_childs); rtnl_ematch_free(pos); } } /** * Free ematch tree object * @arg tree ematch tree object * * This function frees the ematch tree and all ematches attached to it. */ void rtnl_ematch_tree_free(struct rtnl_ematch_tree *tree) { if (!tree) return; free_ematch_list(&tree->et_list); NL_DBG(2, "Freed ematch tree %p\n", tree); free(tree); } /** * Add ematch object to the end of the ematch tree * @arg tree ematch tree object * @arg ematch ematch object to add */ void rtnl_ematch_tree_add(struct rtnl_ematch_tree *tree, struct rtnl_ematch *ematch) { nl_list_add_tail(&ematch->e_list, &tree->et_list); } static inline uint32_t container_ref(struct rtnl_ematch *ematch) { return *((uint32_t *) rtnl_ematch_data(ematch)); } static int link_tree(struct rtnl_ematch *index[], int nmatches, int pos, struct nl_list_head *root) { struct rtnl_ematch *ematch; int i; for (i = pos; i < nmatches; i++) { ematch = index[i]; nl_list_add_tail(&ematch->e_list, root); if (ematch->e_kind == TCF_EM_CONTAINER) link_tree(index, nmatches, container_ref(ematch), &ematch->e_childs); if (!(ematch->e_flags & TCF_EM_REL_MASK)) return 0; } /* Last entry in chain can't possibly have no relation */ return -NLE_INVAL; } static struct nla_policy tree_policy[TCA_EMATCH_TREE_MAX+1] = { [TCA_EMATCH_TREE_HDR] = { .minlen=sizeof(struct tcf_ematch_tree_hdr) }, [TCA_EMATCH_TREE_LIST] = { .type = NLA_NESTED }, }; /** * Parse ematch netlink attributes * * @return 0 on success or a negative error code. */ int rtnl_ematch_parse_attr(struct nlattr *attr, struct rtnl_ematch_tree **result) { struct nlattr *a, *tb[TCA_EMATCH_TREE_MAX+1]; struct tcf_ematch_tree_hdr *thdr; struct rtnl_ematch_tree *tree; struct rtnl_ematch **index; int nmatches = 0, err, remaining; NL_DBG(2, "Parsing attribute %p as ematch tree\n", attr); err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, attr, tree_policy); if (err < 0) return err; if (!tb[TCA_EMATCH_TREE_HDR]) return -NLE_MISSING_ATTR; thdr = nla_data(tb[TCA_EMATCH_TREE_HDR]); /* Ignore empty trees */ if (thdr->nmatches == 0) { NL_DBG(2, "Ignoring empty ematch configuration\n"); return 0; } if (!tb[TCA_EMATCH_TREE_LIST]) return -NLE_MISSING_ATTR; NL_DBG(2, "ematch tree found with nmatches=%u, progid=%u\n", thdr->nmatches, thdr->progid); /* * Do some basic sanity checking since we will allocate * index[thdr->nmatches]. Calculate how many ematch headers fit into * the provided data and make sure nmatches does not exceed it. */ if (thdr->nmatches > (nla_len(tb[TCA_EMATCH_TREE_LIST]) / nla_total_size(sizeof(struct tcf_ematch_hdr)))) return -NLE_INVAL; if (!(index = calloc(thdr->nmatches, sizeof(struct rtnl_ematch *)))) return -NLE_NOMEM; if (!(tree = rtnl_ematch_tree_alloc(thdr->progid))) { err = -NLE_NOMEM; goto errout; } nla_for_each_nested(a, tb[TCA_EMATCH_TREE_LIST], remaining) { struct rtnl_ematch_ops *ops; struct tcf_ematch_hdr *hdr; struct rtnl_ematch *ematch; void *data; size_t len; NL_DBG(3, "parsing ematch attribute %d, len=%u\n", nmatches+1, nla_len(a)); if (nla_len(a) < sizeof(*hdr)) { err = -NLE_INVAL; goto errout; } /* Quit as soon as we've parsed more matches than expected */ if (nmatches >= thdr->nmatches) { err = -NLE_RANGE; goto errout; } hdr = nla_data(a); data = nla_data(a) + NLA_ALIGN(sizeof(*hdr)); len = nla_len(a) - NLA_ALIGN(sizeof(*hdr)); NL_DBG(3, "ematch attribute matchid=%u, kind=%u, flags=%u\n", hdr->matchid, hdr->kind, hdr->flags); /* * Container matches contain a reference to another sequence * of matches. Ensure that the reference is within boundries. */ if (hdr->kind == TCF_EM_CONTAINER && *((uint32_t *) data) >= thdr->nmatches) { err = -NLE_INVAL; goto errout; } if (!(ematch = rtnl_ematch_alloc())) { err = -NLE_NOMEM; goto errout; } ematch->e_id = hdr->matchid; ematch->e_kind = hdr->kind; ematch->e_flags = hdr->flags; if ((ops = rtnl_ematch_lookup_ops(hdr->kind))) { if (ops->eo_minlen && len < ops->eo_minlen) { rtnl_ematch_free(ematch); err = -NLE_INVAL; goto errout; } rtnl_ematch_set_ops(ematch, ops); if (ops->eo_parse && (err = ops->eo_parse(ematch, data, len)) < 0) { rtnl_ematch_free(ematch); goto errout; } } NL_DBG(3, "index[%d] = %p\n", nmatches, ematch); index[nmatches++] = ematch; } if (nmatches != thdr->nmatches) { err = -NLE_INVAL; goto errout; } err = link_tree(index, nmatches, 0, &tree->et_list); if (err < 0) goto errout; free(index); *result = tree; return 0; errout: rtnl_ematch_tree_free(tree); free(index); return err; } static void dump_ematch_sequence(struct nl_list_head *head, struct nl_dump_params *p) { struct rtnl_ematch *match; nl_list_for_each_entry(match, head, e_list) { if (match->e_flags & TCF_EM_INVERT) nl_dump(p, "!"); if (match->e_kind == TCF_EM_CONTAINER) { nl_dump(p, "("); dump_ematch_sequence(&match->e_childs, p); nl_dump(p, ")"); } else if (!match->e_ops) { nl_dump(p, "[unknown ematch %d]", match->e_kind); } else { if (match->e_ops->eo_dump) match->e_ops->eo_dump(match, p); else nl_dump(p, "[data]"); } switch (match->e_flags & TCF_EM_REL_MASK) { case TCF_EM_REL_AND: nl_dump(p, " AND "); break; case TCF_EM_REL_OR: nl_dump(p, " OR "); break; default: /* end of first level ematch sequence */ return; } } } void rtnl_ematch_tree_dump(struct rtnl_ematch_tree *tree, struct nl_dump_params *p) { if (!tree) BUG(); dump_ematch_sequence(&tree->et_list, p); nl_dump(p, "\n"); } static int update_container_index(struct nl_list_head *list, int *index) { struct rtnl_ematch *e; nl_list_for_each_entry(e, list, e_list) e->e_index = (*index)++; nl_list_for_each_entry(e, list, e_list) { if (e->e_kind == TCF_EM_CONTAINER) { int err; if (nl_list_empty(&e->e_childs)) return -NLE_OBJ_NOTFOUND; *((uint32_t *) e->e_data) = *index; err = update_container_index(&e->e_childs, index); if (err < 0) return err; } } return 0; } static int fill_ematch_sequence(struct nl_msg *msg, struct nl_list_head *list) { struct rtnl_ematch *e; nl_list_for_each_entry(e, list, e_list) { struct tcf_ematch_hdr match = { .matchid = e->e_id, .kind = e->e_kind, .flags = e->e_flags, }; struct nlattr *attr; int err = 0; if (!(attr = nla_nest_start(msg, e->e_index + 1))) return -NLE_NOMEM; if (nlmsg_append(msg, &match, sizeof(match), 0) < 0) return -NLE_NOMEM; if (e->e_ops->eo_fill) err = e->e_ops->eo_fill(e, msg); else if (e->e_flags & TCF_EM_SIMPLE) err = nlmsg_append(msg, e->e_data, 4, 0); else if (e->e_datalen > 0) err = nlmsg_append(msg, e->e_data, e->e_datalen, 0); NL_DBG(3, "msg %p: added ematch [%d] id=%d kind=%d flags=%d\n", msg, e->e_index, match.matchid, match.kind, match.flags); if (err < 0) return -NLE_NOMEM; nla_nest_end(msg, attr); } nl_list_for_each_entry(e, list, e_list) { if (e->e_kind == TCF_EM_CONTAINER && fill_ematch_sequence(msg, &e->e_childs) < 0) return -NLE_NOMEM; } return 0; } int rtnl_ematch_fill_attr(struct nl_msg *msg, int attrid, struct rtnl_ematch_tree *tree) { struct tcf_ematch_tree_hdr thdr = { .progid = tree->et_progid, }; struct nlattr *list, *topattr; int err, index = 0; /* Assign index number to each ematch to allow for references * to be made while constructing the sequence of matches. */ err = update_container_index(&tree->et_list, &index); if (err < 0) return err; if (!(topattr = nla_nest_start(msg, attrid))) goto nla_put_failure; thdr.nmatches = index; NLA_PUT(msg, TCA_EMATCH_TREE_HDR, sizeof(thdr), &thdr); if (!(list = nla_nest_start(msg, TCA_EMATCH_TREE_LIST))) goto nla_put_failure; if (fill_ematch_sequence(msg, &tree->et_list) < 0) goto nla_put_failure; nla_nest_end(msg, list); nla_nest_end(msg, topattr); return 0; nla_put_failure: return -NLE_NOMEM; } /** @} */ extern int ematch_parse(void *, char **, struct nl_list_head *); int rtnl_ematch_parse_expr(const char *expr, char **errp, struct rtnl_ematch_tree **result) { struct rtnl_ematch_tree *tree; YY_BUFFER_STATE buf = NULL; yyscan_t scanner = NULL; int err; NL_DBG(2, "Parsing ematch expression \"%s\"\n", expr); if (!(tree = rtnl_ematch_tree_alloc(RTNL_EMATCH_PROGID))) return -NLE_FAILURE; if ((err = ematch_lex_init(&scanner)) < 0) { err = -NLE_FAILURE; goto errout; } buf = ematch__scan_string(expr, scanner); if ((err = ematch_parse(scanner, errp, &tree->et_list)) != 0) { ematch__delete_buffer(buf, scanner); err = -NLE_PARSE_ERR; goto errout; } ematch_lex_destroy(scanner); *result = tree; return 0; errout: if (scanner) ematch_lex_destroy(scanner); rtnl_ematch_tree_free(tree); return err; } static const char *layer_txt[] = { [TCF_LAYER_LINK] = "eth", [TCF_LAYER_NETWORK] = "ip", [TCF_LAYER_TRANSPORT] = "tcp", }; char *rtnl_ematch_offset2txt(uint8_t layer, uint16_t offset, char *buf, size_t len) { snprintf(buf, len, "%s+%u", (layer <= TCF_LAYER_MAX) ? layer_txt[layer] : "?", offset); return buf; } static const char *operand_txt[] = { [TCF_EM_OPND_EQ] = "=", [TCF_EM_OPND_LT] = "<", [TCF_EM_OPND_GT] = ">", }; char *rtnl_ematch_opnd2txt(uint8_t opnd, char *buf, size_t len) { snprintf(buf, len, "%s", opnd < ARRAY_SIZE(operand_txt) ? operand_txt[opnd] : "?"); return buf; } /** @} */ libnl-3.2.29/lib/route/cls/u32.c0000644000175000017500000004470013023014600013064 00000000000000/* * lib/route/cls/u32.c u32 classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf * Copyright (c) 2005-2006 Petr Gotthard * Copyright (c) 2005-2006 Siemens AG Oesterreich */ /** * @ingroup cls * @defgroup cls_u32 Universal 32-bit Classifier * * @{ */ #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define U32_ATTR_DIVISOR 0x001 #define U32_ATTR_HASH 0x002 #define U32_ATTR_CLASSID 0x004 #define U32_ATTR_LINK 0x008 #define U32_ATTR_PCNT 0x010 #define U32_ATTR_SELECTOR 0x020 #define U32_ATTR_ACTION 0x040 #define U32_ATTR_POLICE 0x080 #define U32_ATTR_INDEV 0x100 #define U32_ATTR_MARK 0x200 /** @endcond */ static inline struct tc_u32_sel *u32_selector(struct rtnl_u32 *u) { return (struct tc_u32_sel *) u->cu_selector->d_data; } static inline struct tc_u32_sel *u32_selector_alloc(struct rtnl_u32 *u) { if (!u->cu_selector) u->cu_selector = nl_data_alloc(NULL, sizeof(struct tc_u32_sel)); return u32_selector(u); } static inline struct tc_u32_mark *u32_mark_alloc(struct rtnl_u32 *u) { if (!u->cu_mark) u->cu_mark = nl_data_alloc(NULL, sizeof(struct tc_u32_mark)); return (struct tc_u32_mark *) u->cu_mark->d_data; } static struct nla_policy u32_policy[TCA_U32_MAX+1] = { [TCA_U32_DIVISOR] = { .type = NLA_U32 }, [TCA_U32_HASH] = { .type = NLA_U32 }, [TCA_U32_CLASSID] = { .type = NLA_U32 }, [TCA_U32_LINK] = { .type = NLA_U32 }, [TCA_U32_INDEV] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [TCA_U32_SEL] = { .minlen = sizeof(struct tc_u32_sel) }, [TCA_U32_PCNT] = { .minlen = sizeof(struct tc_u32_pcnt) }, [TCA_U32_MARK] = { .minlen = sizeof(struct tc_u32_mark) } }; static int u32_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_u32 *u = data; struct nlattr *tb[TCA_U32_MAX + 1]; int err; err = tca_parse(tb, TCA_U32_MAX, tc, u32_policy); if (err < 0) return err; if (tb[TCA_U32_DIVISOR]) { u->cu_divisor = nla_get_u32(tb[TCA_U32_DIVISOR]); u->cu_mask |= U32_ATTR_DIVISOR; } if (tb[TCA_U32_SEL]) { u->cu_selector = nl_data_alloc_attr(tb[TCA_U32_SEL]); if (!u->cu_selector) goto errout_nomem; u->cu_mask |= U32_ATTR_SELECTOR; } if (tb[TCA_U32_MARK]) { u->cu_mark = nl_data_alloc_attr(tb[TCA_U32_MARK]); if (!u->cu_mark) goto errout_nomem; u->cu_mask |= U32_ATTR_MARK; } if (tb[TCA_U32_HASH]) { u->cu_hash = nla_get_u32(tb[TCA_U32_HASH]); u->cu_mask |= U32_ATTR_HASH; } if (tb[TCA_U32_CLASSID]) { u->cu_classid = nla_get_u32(tb[TCA_U32_CLASSID]); u->cu_mask |= U32_ATTR_CLASSID; } if (tb[TCA_U32_LINK]) { u->cu_link = nla_get_u32(tb[TCA_U32_LINK]); u->cu_mask |= U32_ATTR_LINK; } if (tb[TCA_U32_ACT]) { u->cu_mask |= U32_ATTR_ACTION; err = rtnl_act_parse(&u->cu_act, tb[TCA_U32_ACT]); if (err) return err; } if (tb[TCA_U32_POLICE]) { u->cu_police = nl_data_alloc_attr(tb[TCA_U32_POLICE]); if (!u->cu_police) goto errout_nomem; u->cu_mask |= U32_ATTR_POLICE; } if (tb[TCA_U32_PCNT]) { struct tc_u32_sel *sel; size_t pcnt_size; if (!tb[TCA_U32_SEL]) { err = -NLE_MISSING_ATTR; goto errout; } sel = u->cu_selector->d_data; pcnt_size = sizeof(struct tc_u32_pcnt) + (sel->nkeys * sizeof(uint64_t)); if (nla_len(tb[TCA_U32_PCNT]) < pcnt_size) { err = -NLE_INVAL; goto errout; } u->cu_pcnt = nl_data_alloc_attr(tb[TCA_U32_PCNT]); if (!u->cu_pcnt) goto errout_nomem; u->cu_mask |= U32_ATTR_PCNT; } if (tb[TCA_U32_INDEV]) { nla_strlcpy(u->cu_indev, tb[TCA_U32_INDEV], IFNAMSIZ); u->cu_mask |= U32_ATTR_INDEV; } return 0; errout_nomem: err = -NLE_NOMEM; errout: return err; } static void u32_free_data(struct rtnl_tc *tc, void *data) { struct rtnl_u32 *u = data; if (u->cu_act) rtnl_act_put_all(&u->cu_act); nl_data_free(u->cu_mark); nl_data_free(u->cu_selector); nl_data_free(u->cu_police); nl_data_free(u->cu_pcnt); } static int u32_clone(void *_dst, void *_src) { struct rtnl_u32 *dst = _dst, *src = _src; if (src->cu_selector && !(dst->cu_selector = nl_data_clone(src->cu_selector))) return -NLE_NOMEM; if (src->cu_mark && !(dst->cu_mark = nl_data_clone(src->cu_mark))) return -NLE_NOMEM; if (src->cu_act) { if (!(dst->cu_act = rtnl_act_alloc())) return -NLE_NOMEM; memcpy(dst->cu_act, src->cu_act, sizeof(struct rtnl_act)); } if (src->cu_police && !(dst->cu_police = nl_data_clone(src->cu_police))) return -NLE_NOMEM; if (src->cu_pcnt && !(dst->cu_pcnt = nl_data_clone(src->cu_pcnt))) return -NLE_NOMEM; return 0; } static void u32_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_u32 *u = data; char buf[32]; if (!u) return; if (u->cu_mask & U32_ATTR_DIVISOR) nl_dump(p, " divisor %u", u->cu_divisor); else if (u->cu_mask & U32_ATTR_CLASSID) nl_dump(p, " target %s", rtnl_tc_handle2str(u->cu_classid, buf, sizeof(buf))); } static void print_selector(struct nl_dump_params *p, struct tc_u32_sel *sel, struct rtnl_u32 *u) { int i; struct tc_u32_key *key; if (sel->hmask || sel->hoff) { /* I guess this will never be used since the kernel only * exports the selector if no divisor is set but hash offset * and hash mask make only sense in hash filters with divisor * set */ nl_dump(p, " hash at %u & 0x%x", sel->hoff, sel->hmask); } if (sel->flags & (TC_U32_OFFSET | TC_U32_VAROFFSET)) { nl_dump(p, " offset at %u", sel->off); if (sel->flags & TC_U32_VAROFFSET) nl_dump(p, " variable (at %u & 0x%x) >> %u", sel->offoff, ntohs(sel->offmask), sel->offshift); } if (sel->flags) { int flags = sel->flags; nl_dump(p, " <"); #define PRINT_FLAG(f) if (flags & TC_U32_##f) { \ flags &= ~TC_U32_##f; nl_dump(p, #f "%s", flags ? "," : ""); } PRINT_FLAG(TERMINAL); PRINT_FLAG(OFFSET); PRINT_FLAG(VAROFFSET); PRINT_FLAG(EAT); #undef PRINT_FLAG nl_dump(p, ">"); } for (i = 0; i < sel->nkeys; i++) { key = (struct tc_u32_key *) ((char *) sel + sizeof(*sel)) + i; nl_dump(p, "\n"); nl_dump_line(p, " match key at %s%u ", key->offmask ? "nexthdr+" : "", key->off); if (key->offmask) nl_dump(p, "[0x%u] ", key->offmask); nl_dump(p, "& 0x%08x == 0x%08x", ntohl(key->mask), ntohl(key->val)); if (p->dp_type == NL_DUMP_STATS && (u->cu_mask & U32_ATTR_PCNT)) { struct tc_u32_pcnt *pcnt = u->cu_pcnt->d_data; nl_dump(p, " successful %" PRIu64, pcnt->kcnts[i]); } } } static void u32_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_u32 *u = data; struct tc_u32_sel *s = NULL; struct tc_u32_mark *m; if (!u) return; if (!(u->cu_mask & (U32_ATTR_SELECTOR & U32_ATTR_MARK))) { nl_dump(p, "no-selector no-mark\n"); return; } if (!(u->cu_mask & U32_ATTR_SELECTOR)) { nl_dump(p, "no-selector"); } else { s = u->cu_selector->d_data; nl_dump(p, "nkeys %u", s->nkeys); } if (!(u->cu_mask & U32_ATTR_MARK)) { nl_dump(p, " no-mark"); } else { m = u->cu_mark->d_data; nl_dump(p, " mark 0x%u 0x%u", m->val, m->mask); } if (u->cu_mask & U32_ATTR_HASH) nl_dump(p, " ht key 0x%x hash 0x%u", TC_U32_USERHTID(u->cu_hash), TC_U32_HASH(u->cu_hash)); if (u->cu_mask & U32_ATTR_LINK) nl_dump(p, " link %u", u->cu_link); if (u->cu_mask & U32_ATTR_INDEV) nl_dump(p, " indev %s", u->cu_indev); if (u->cu_mask & U32_ATTR_SELECTOR) print_selector(p, s, u); nl_dump(p, "\n"); } static void u32_dump_stats(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_u32 *u = data; if (!u) return; if (u->cu_mask & U32_ATTR_PCNT) { struct tc_u32_pcnt *pc = u->cu_pcnt->d_data; nl_dump(p, "\n"); nl_dump_line(p, " hit %8" PRIu64 " count %8" PRIu64 "\n", pc->rhit, pc->rcnt); } } static int u32_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_u32 *u = data; if (!u) return 0; if (u->cu_mask & U32_ATTR_DIVISOR) NLA_PUT_U32(msg, TCA_U32_DIVISOR, u->cu_divisor); if (u->cu_mask & U32_ATTR_HASH) NLA_PUT_U32(msg, TCA_U32_HASH, u->cu_hash); if (u->cu_mask & U32_ATTR_CLASSID) NLA_PUT_U32(msg, TCA_U32_CLASSID, u->cu_classid); if (u->cu_mask & U32_ATTR_LINK) NLA_PUT_U32(msg, TCA_U32_LINK, u->cu_link); if (u->cu_mask & U32_ATTR_SELECTOR) NLA_PUT_DATA(msg, TCA_U32_SEL, u->cu_selector); if (u->cu_mask & U32_ATTR_MARK) NLA_PUT_DATA(msg, TCA_U32_MARK, u->cu_mark); if (u->cu_mask & U32_ATTR_ACTION) { int err; err = rtnl_act_fill(msg, TCA_U32_ACT, u->cu_act); if (err) return err; } if (u->cu_mask & U32_ATTR_POLICE) NLA_PUT_DATA(msg, TCA_U32_POLICE, u->cu_police); if (u->cu_mask & U32_ATTR_INDEV) NLA_PUT_STRING(msg, TCA_U32_INDEV, u->cu_indev); return 0; nla_put_failure: return -NLE_NOMEM; } /** * @name Attribute Modifications * @{ */ void rtnl_u32_set_handle(struct rtnl_cls *cls, int htid, int hash, int nodeid) { uint32_t handle = (htid << 20) | (hash << 12) | nodeid; rtnl_tc_set_handle((struct rtnl_tc *) cls, handle ); } int rtnl_u32_set_classid(struct rtnl_cls *cls, uint32_t classid) { struct rtnl_u32 *u; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; u->cu_classid = classid; u->cu_mask |= U32_ATTR_CLASSID; return 0; } int rtnl_u32_get_classid(struct rtnl_cls *cls, uint32_t *classid) { struct rtnl_u32 *u; if (!(u = rtnl_tc_data_peek(TC_CAST(cls)))) return -NLE_INVAL; if (!(u->cu_mask & U32_ATTR_CLASSID)) return -NLE_INVAL; *classid = u->cu_classid; return 0; } int rtnl_u32_set_divisor(struct rtnl_cls *cls, uint32_t divisor) { struct rtnl_u32 *u; if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; u->cu_divisor = divisor; u->cu_mask |= U32_ATTR_DIVISOR; return 0; } int rtnl_u32_set_link(struct rtnl_cls *cls, uint32_t link) { struct rtnl_u32 *u; if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; u->cu_link = link; u->cu_mask |= U32_ATTR_LINK; return 0; } int rtnl_u32_set_hashtable(struct rtnl_cls *cls, uint32_t ht) { struct rtnl_u32 *u; if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; u->cu_hash = ht; u->cu_mask |= U32_ATTR_HASH; return 0; } int rtnl_u32_set_hashmask(struct rtnl_cls *cls, uint32_t hashmask, uint32_t offset) { struct rtnl_u32 *u; struct tc_u32_sel *sel; int err; hashmask = htonl(hashmask); if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; sel = u32_selector_alloc(u); if (!sel) return -NLE_NOMEM; err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key)); if(err < 0) return err; sel = u32_selector(u); sel->hmask = hashmask; sel->hoff = offset; return 0; } int rtnl_u32_set_selector(struct rtnl_cls *cls, int offoff, uint32_t offmask, char offshift, uint16_t off, char flags) { struct rtnl_u32 *u; struct tc_u32_sel *sel; int err; offmask = ntohs(offmask); if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; sel = u32_selector_alloc(u); if (!sel) return -NLE_NOMEM; err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key)); if(err < 0) return err; sel = u32_selector(u); sel->offoff = offoff; sel->offmask = offmask; sel->offshift = offshift; sel->flags |= TC_U32_VAROFFSET; sel->off = off; sel->flags |= flags; return 0; } int rtnl_u32_set_cls_terminal(struct rtnl_cls *cls) { struct rtnl_u32 *u; struct tc_u32_sel *sel; int err; if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; sel = u32_selector_alloc(u); if (!sel) return -NLE_NOMEM; err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key)); if(err < 0) return err; sel = u32_selector(u); sel->flags |= TC_U32_TERMINAL; return 0; } int rtnl_u32_add_action(struct rtnl_cls *cls, struct rtnl_act *act) { struct rtnl_u32 *u; if (!act) return 0; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; u->cu_mask |= U32_ATTR_ACTION; /* In case user frees it */ rtnl_act_get(act); return rtnl_act_append(&u->cu_act, act); } int rtnl_u32_del_action(struct rtnl_cls *cls, struct rtnl_act *act) { struct rtnl_u32 *u; int ret; if (!act) return 0; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; if (!(u->cu_mask & U32_ATTR_ACTION)) return -NLE_INVAL; ret = rtnl_act_remove(&u->cu_act, act); if (ret) return ret; if (!u->cu_act) u->cu_mask &= ~U32_ATTR_ACTION; rtnl_act_put(act); return 0; } /** @} */ /** * @name Selector Modifications * @{ */ int rtnl_u32_set_flags(struct rtnl_cls *cls, int flags) { struct tc_u32_sel *sel; struct rtnl_u32 *u; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; sel = u32_selector_alloc(u); if (!sel) return -NLE_NOMEM; sel->flags |= flags; u->cu_mask |= U32_ATTR_SELECTOR; return 0; } /** * Append new 32-bit key to the selector * * @arg cls classifier to be modifier * @arg val value to be matched (network byte-order) * @arg mask mask to be applied before matching (network byte-order) * @arg off offset, in bytes, to start matching * @arg offmask offset mask * * General selectors define the pattern, mask and offset the pattern will be * matched to the packet contents. Using the general selectors you can match * virtually any single bit in the IP (or upper layer) header. * */ int rtnl_u32_add_key(struct rtnl_cls *cls, uint32_t val, uint32_t mask, int off, int offmask) { struct tc_u32_sel *sel; struct rtnl_u32 *u; int err; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; sel = u32_selector_alloc(u); if (!sel) return -NLE_NOMEM; err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key)); if (err < 0) return err; /* the selector might have been moved by realloc */ sel = u32_selector(u); sel->keys[sel->nkeys].mask = mask; sel->keys[sel->nkeys].val = val & mask; sel->keys[sel->nkeys].off = off; sel->keys[sel->nkeys].offmask = offmask; sel->nkeys++; u->cu_mask |= U32_ATTR_SELECTOR; return 0; } int rtnl_u32_add_mark(struct rtnl_cls *cls, uint32_t val, uint32_t mask) { struct tc_u32_mark *mark; struct rtnl_u32 *u; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; mark = u32_mark_alloc(u); if (!mark) return -NLE_NOMEM; mark->mask = mask; mark->val = val; u->cu_mask |= U32_ATTR_MARK; return 0; } int rtnl_u32_del_mark(struct rtnl_cls *cls) { struct rtnl_u32 *u; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; if (!(u->cu_mask)) return -NLE_INVAL; if (!(u->cu_mask & U32_ATTR_MARK)) return -NLE_INVAL; nl_data_free(u->cu_mark); u->cu_mark = NULL; u->cu_mask &= ~U32_ATTR_MARK; return 0; } /** * Get the 32-bit key from the selector * * @arg cls classifier to be retrieve * @arg index the index of the array of keys, start with 0 * @arg val pointer to store value after masked (network byte-order) * @arg mask pointer to store the mask (network byte-order) * @arg off pointer to store the offset * @arg offmask pointer to store offset mask * */ int rtnl_u32_get_key(struct rtnl_cls *cls, uint8_t index, uint32_t *val, uint32_t *mask, int *off, int *offmask) { struct tc_u32_sel *sel; struct rtnl_u32 *u; if (!(u = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; if (!(u->cu_mask & U32_ATTR_SELECTOR)) return -NLE_INVAL; /* the selector might have been moved by realloc */ sel = u32_selector(u); if (index >= sel->nkeys) return -NLE_RANGE; *mask = sel->keys[index].mask; *val = sel->keys[index].val; *off = sel->keys[index].off; *offmask = sel->keys[index].offmask; return 0; } int rtnl_u32_add_key_uint8(struct rtnl_cls *cls, uint8_t val, uint8_t mask, int off, int offmask) { int shift = 24 - 8 * (off & 3); return rtnl_u32_add_key(cls, htonl((uint32_t)val << shift), htonl((uint32_t)mask << shift), off & ~3, offmask); } /** * Append new selector key to match a 16-bit number * * @arg cls classifier to be modified * @arg val value to be matched (host byte-order) * @arg mask mask to be applied before matching (host byte-order) * @arg off offset, in bytes, to start matching * @arg offmask offset mask */ int rtnl_u32_add_key_uint16(struct rtnl_cls *cls, uint16_t val, uint16_t mask, int off, int offmask) { int shift = ((off & 3) == 0 ? 16 : 0); if (off % 2) return -NLE_INVAL; return rtnl_u32_add_key(cls, htonl((uint32_t)val << shift), htonl((uint32_t)mask << shift), off & ~3, offmask); } /** * Append new selector key to match a 32-bit number * * @arg cls classifier to be modified * @arg val value to be matched (host byte-order) * @arg mask mask to be applied before matching (host byte-order) * @arg off offset, in bytes, to start matching * @arg offmask offset mask */ int rtnl_u32_add_key_uint32(struct rtnl_cls *cls, uint32_t val, uint32_t mask, int off, int offmask) { return rtnl_u32_add_key(cls, htonl(val), htonl(mask), off & ~3, offmask); } int rtnl_u32_add_key_in_addr(struct rtnl_cls *cls, const struct in_addr *addr, uint8_t bitmask, int off, int offmask) { uint32_t mask = 0xFFFFFFFF << (32 - bitmask); return rtnl_u32_add_key(cls, addr->s_addr, htonl(mask), off, offmask); } int rtnl_u32_add_key_in6_addr(struct rtnl_cls *cls, const struct in6_addr *addr, uint8_t bitmask, int off, int offmask) { int i, err; for (i = 1; i <= 4; i++) { if (32 * i - bitmask <= 0) { if ((err = rtnl_u32_add_key(cls, addr->s6_addr32[i-1], 0xFFFFFFFF, off+4*(i-1), offmask)) < 0) return err; } else if (32 * i - bitmask < 32) { uint32_t mask = 0xFFFFFFFF << (32 * i - bitmask); if ((err = rtnl_u32_add_key(cls, addr->s6_addr32[i-1], htonl(mask), off+4*(i-1), offmask)) < 0) return err; } /* otherwise, if (32*i - bitmask >= 32) no key is generated */ } return 0; } /** @} */ static struct rtnl_tc_ops u32_ops = { .to_kind = "u32", .to_type = RTNL_TC_TYPE_CLS, .to_size = sizeof(struct rtnl_u32), .to_msg_parser = u32_msg_parser, .to_free_data = u32_free_data, .to_clone = u32_clone, .to_msg_fill = u32_msg_fill, .to_dump = { [NL_DUMP_LINE] = u32_dump_line, [NL_DUMP_DETAILS] = u32_dump_details, [NL_DUMP_STATS] = u32_dump_stats, }, }; static void __init u32_init(void) { rtnl_tc_register(&u32_ops); } static void __exit u32_exit(void) { rtnl_tc_unregister(&u32_ops); } /** @} */ libnl-3.2.29/lib/route/cls/basic.c0000644000175000017500000001312313023014600013527 00000000000000/* * lib/route/cls/basic.c Basic Classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2013 Thomas Graf */ /** * @ingroup cls * @defgroup cls_basic Basic Classifier * * @par Introduction * The basic classifier is the simplest form of a classifier. It does * not have any special classification capabilities, instead it can be * used to classify exclusively based on extended matches or to * create a "catch-all" filter. * * @{ */ #include #include #include #include #include #include #include #include struct rtnl_basic { uint32_t b_target; struct rtnl_ematch_tree * b_ematch; int b_mask; struct rtnl_act * b_act; }; /** @cond SKIP */ #define BASIC_ATTR_TARGET 0x001 #define BASIC_ATTR_EMATCH 0x002 #define BASIC_ATTR_ACTION 0x004 /** @endcond */ static struct nla_policy basic_policy[TCA_BASIC_MAX+1] = { [TCA_BASIC_CLASSID] = { .type = NLA_U32 }, [TCA_BASIC_EMATCHES] = { .type = NLA_NESTED }, }; static int basic_clone(void *_dst, void *_src) { return -NLE_OPNOTSUPP; } static void basic_free_data(struct rtnl_tc *tc, void *data) { struct rtnl_basic *b = data; if (!b) return; if (b->b_act) rtnl_act_put_all(&b->b_act); rtnl_ematch_tree_free(b->b_ematch); } static int basic_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_BASIC_MAX + 1]; struct rtnl_basic *b = data; int err; err = tca_parse(tb, TCA_BASIC_MAX, tc, basic_policy); if (err < 0) return err; if (tb[TCA_BASIC_CLASSID]) { b->b_target = nla_get_u32(tb[TCA_BASIC_CLASSID]); b->b_mask |= BASIC_ATTR_TARGET; } if (tb[TCA_BASIC_EMATCHES]) { if ((err = rtnl_ematch_parse_attr(tb[TCA_BASIC_EMATCHES], &b->b_ematch)) < 0) return err; if (b->b_ematch) b->b_mask |= BASIC_ATTR_EMATCH; } if (tb[TCA_BASIC_ACT]) { b->b_mask |= BASIC_ATTR_ACTION; err = rtnl_act_parse(&b->b_act, tb[TCA_BASIC_ACT]); if (err) return err; } return 0; } static void basic_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_basic *b = data; char buf[32]; if (!b) return; if (b->b_mask & BASIC_ATTR_EMATCH) nl_dump(p, " ematch"); else nl_dump(p, " match-all"); if (b->b_mask & BASIC_ATTR_TARGET) nl_dump(p, " target %s", rtnl_tc_handle2str(b->b_target, buf, sizeof(buf))); } static void basic_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_basic *b = data; if (!b) return; if (b->b_mask & BASIC_ATTR_EMATCH) { nl_dump_line(p, " ematch "); rtnl_ematch_tree_dump(b->b_ematch, p); } else nl_dump(p, "no options.\n"); } static int basic_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_basic *b = data; if (!b) return 0; if (b->b_mask & BASIC_ATTR_TARGET) NLA_PUT_U32(msg, TCA_BASIC_CLASSID, b->b_target); if (b->b_mask & BASIC_ATTR_EMATCH && rtnl_ematch_fill_attr(msg, TCA_BASIC_EMATCHES, b->b_ematch) < 0) goto nla_put_failure; if (b->b_mask & BASIC_ATTR_ACTION) { int err; err = rtnl_act_fill(msg, TCA_BASIC_ACT, b->b_act); if (err) return err; } return 0; nla_put_failure: return -NLE_NOMEM; } /** * @name Attribute Modifications * @{ */ void rtnl_basic_set_target(struct rtnl_cls *cls, uint32_t target) { struct rtnl_basic *b; if (!(b = rtnl_tc_data(TC_CAST(cls)))) return; b->b_target = target; b->b_mask |= BASIC_ATTR_TARGET; } uint32_t rtnl_basic_get_target(struct rtnl_cls *cls) { struct rtnl_basic *b; if (!(b = rtnl_tc_data(TC_CAST(cls)))) return 0; return b->b_target; } void rtnl_basic_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) { struct rtnl_basic *b; if (!(b = rtnl_tc_data(TC_CAST(cls)))) return; if (b->b_ematch) { rtnl_ematch_tree_free(b->b_ematch); b->b_mask &= ~BASIC_ATTR_EMATCH; } b->b_ematch = tree; if (tree) b->b_mask |= BASIC_ATTR_EMATCH; } struct rtnl_ematch_tree *rtnl_basic_get_ematch(struct rtnl_cls *cls) { struct rtnl_basic *b; if (!(b = rtnl_tc_data(TC_CAST(cls)))) return NULL; return b->b_ematch; } int rtnl_basic_add_action(struct rtnl_cls *cls, struct rtnl_act *act) { struct rtnl_basic *b; if (!act) return 0; if (!(b = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; b->b_mask |= BASIC_ATTR_ACTION; /* In case user frees it */ rtnl_act_get(act); return rtnl_act_append(&b->b_act, act); } int rtnl_basic_del_action(struct rtnl_cls *cls, struct rtnl_act *act) { struct rtnl_basic *b; int ret; if (!act) return 0; if (!(b = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; if (!(b->b_mask & BASIC_ATTR_ACTION)) return -NLE_INVAL; ret = rtnl_act_remove(&b->b_act, act); if (ret) return ret; if (!b->b_act) b->b_mask &= ~BASIC_ATTR_ACTION; rtnl_act_put(act); return 0; } /** @} */ static struct rtnl_tc_ops basic_ops = { .to_kind = "basic", .to_type = RTNL_TC_TYPE_CLS, .to_size = sizeof(struct rtnl_basic), .to_msg_parser = basic_msg_parser, .to_clone = basic_clone, .to_free_data = basic_free_data, .to_msg_fill = basic_msg_fill, .to_dump = { [NL_DUMP_LINE] = basic_dump_line, [NL_DUMP_DETAILS] = basic_dump_details, }, }; static void __init basic_init(void) { rtnl_tc_register(&basic_ops); } static void __exit basic_exit(void) { rtnl_tc_unregister(&basic_ops); } /** @} */ libnl-3.2.29/lib/route/cls/fw.c0000644000175000017500000001073513023014600013070 00000000000000/* * lib/route/cls/fw.c fw classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf * Copyright (c) 2006 Petr Gotthard * Copyright (c) 2006 Siemens AG Oesterreich */ /** * @ingroup cls * @defgroup cls_fw Firewall Classifier * * @{ */ #include #include #include #include #include #include /** @cond SKIP */ #define FW_ATTR_CLASSID 0x001 #define FW_ATTR_ACTION 0x002 #define FW_ATTR_POLICE 0x004 #define FW_ATTR_INDEV 0x008 #define FW_ATTR_MASK 0x010 /** @endcond */ static struct nla_policy fw_policy[TCA_FW_MAX+1] = { [TCA_FW_CLASSID] = { .type = NLA_U32 }, [TCA_FW_INDEV] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [TCA_FW_MASK] = { .type = NLA_U32 }, }; static int fw_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_FW_MAX + 1]; struct rtnl_fw *f = data; int err; err = tca_parse(tb, TCA_FW_MAX, tc, fw_policy); if (err < 0) return err; if (tb[TCA_FW_CLASSID]) { f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]); f->cf_mask |= FW_ATTR_CLASSID; } if (tb[TCA_FW_ACT]) { f->cf_act = nl_data_alloc_attr(tb[TCA_FW_ACT]); if (!f->cf_act) return -NLE_NOMEM; f->cf_mask |= FW_ATTR_ACTION; } if (tb[TCA_FW_POLICE]) { f->cf_police = nl_data_alloc_attr(tb[TCA_FW_POLICE]); if (!f->cf_police) return -NLE_NOMEM; f->cf_mask |= FW_ATTR_POLICE; } if (tb[TCA_FW_INDEV]) { nla_strlcpy(f->cf_indev, tb[TCA_FW_INDEV], IFNAMSIZ); f->cf_mask |= FW_ATTR_INDEV; } if (tb[TCA_FW_MASK]) { f->cf_fwmask = nla_get_u32(tb[TCA_FW_MASK]); f->cf_mask |= FW_ATTR_MASK; } return 0; } static void fw_free_data(struct rtnl_tc *tc, void *data) { struct rtnl_fw *f = data; nl_data_free(f->cf_act); nl_data_free(f->cf_police); } static int fw_clone(void *_dst, void *_src) { struct rtnl_fw *dst = _dst, *src = _src; if (src->cf_act && !(dst->cf_act = nl_data_clone(src->cf_act))) return -NLE_NOMEM; if (src->cf_police && !(dst->cf_police = nl_data_clone(src->cf_police))) return -NLE_NOMEM; return 0; } static void fw_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_fw *f = data; if (!f) return; if (f->cf_mask & FW_ATTR_CLASSID) { char buf[32]; nl_dump(p, " target %s", rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf))); } if (f->cf_mask & FW_ATTR_MASK) nl_dump(p, " mask 0x%x", f->cf_fwmask); } static void fw_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_fw *f = data; if (f && f->cf_mask & FW_ATTR_INDEV) nl_dump(p, "indev %s ", f->cf_indev); } static int fw_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_fw *f = data; if (!f) return 0; if (f->cf_mask & FW_ATTR_CLASSID) NLA_PUT_U32(msg, TCA_FW_CLASSID, f->cf_classid); if (f->cf_mask & FW_ATTR_ACTION) NLA_PUT_DATA(msg, TCA_FW_ACT, f->cf_act); if (f->cf_mask & FW_ATTR_POLICE) NLA_PUT_DATA(msg, TCA_FW_POLICE, f->cf_police); if (f->cf_mask & FW_ATTR_INDEV) NLA_PUT_STRING(msg, TCA_FW_INDEV, f->cf_indev); if (f->cf_mask & FW_ATTR_MASK) NLA_PUT_U32(msg, TCA_FW_MASK, f->cf_fwmask); return 0; nla_put_failure: return -NLE_MSGSIZE; } /** * @name Attribute Modifications * @{ */ int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid) { struct rtnl_fw *f; if (!(f = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; f->cf_classid = classid; f->cf_mask |= FW_ATTR_CLASSID; return 0; } int rtnl_fw_set_mask(struct rtnl_cls *cls, uint32_t mask) { struct rtnl_fw *f; if (!(f = rtnl_tc_data(TC_CAST(cls)))) return -NLE_NOMEM; f->cf_fwmask = mask; f->cf_mask |= FW_ATTR_MASK; return 0; } /** @} */ static struct rtnl_tc_ops fw_ops = { .to_kind = "fw", .to_type = RTNL_TC_TYPE_CLS, .to_size = sizeof(struct rtnl_fw), .to_msg_parser = fw_msg_parser, .to_msg_fill = fw_msg_fill, .to_free_data = fw_free_data, .to_clone = fw_clone, .to_dump = { [NL_DUMP_LINE] = fw_dump_line, [NL_DUMP_DETAILS] = fw_dump_details, }, }; static void __init fw_init(void) { rtnl_tc_register(&fw_ops); } static void __exit fw_exit(void) { rtnl_tc_unregister(&fw_ops); } /** @} */ libnl-3.2.29/lib/route/cls/police.c0000644000175000017500000000326513023014600013727 00000000000000/* * lib/route/cls/police.c Policer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ #include #include #include #include #include #include #include /** * @name Policer Type * @{ */ static const struct trans_tbl police_types[] = { __ADD(TC_POLICE_UNSPEC,unspec), __ADD(TC_POLICE_OK,ok), __ADD(TC_POLICE_RECLASSIFY,reclassify), __ADD(TC_POLICE_SHOT,shot), #ifdef TC_POLICE_PIPE __ADD(TC_POLICE_PIPE,pipe), #endif }; /** * Transform a policer type number into a character string (Reentrant). * @arg type policer type * @arg buf destination buffer * @arg len buffer length * * Transforms a policer type number into a character string and stores * it in the provided buffer. * * @return The destination buffer or the type encoded in hex if no match was found. */ char * nl_police2str(int type, char *buf, size_t len) { return __type2str(type, buf, len, police_types, ARRAY_SIZE(police_types)); } /** * Transform a character string into a policer type number * @arg name policer type name * * Transform the provided character string specifying a policer * type into the corresponding numeric value * * @return Policer type number or a negative value. */ int nl_str2police(const char *name) { return __str2type(name, police_types, ARRAY_SIZE(police_types)); } /** @} */ libnl-3.2.29/lib/route/addr.c0000644000175000017500000007703613023014600012614 00000000000000/* * lib/route/addr.c Addresses * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf * Copyright (c) 2003-2006 Baruch Even , * Mediatrix Telecom, inc. */ /** * @ingroup rtnl * @defgroup rtaddr Addresses * @brief * * @note The maximum size of an address label is IFNAMSIZ. * * @note The address may not contain a prefix length if the peer address * has been specified already. * * @par 1) Address Addition * @code * // Allocate an empty address object to be filled out with the attributes * // of the new address. * struct rtnl_addr *addr = rtnl_addr_alloc(); * * // Fill out the mandatory attributes of the new address. Setting the * // local address will automatically set the address family and the * // prefix length to the correct values. * rtnl_addr_set_ifindex(addr, ifindex); * rtnl_addr_set_local(addr, local_addr); * * // The label of the address can be specified, currently only supported * // by IPv4 and DECnet. * rtnl_addr_set_label(addr, "mylabel"); * * // The peer address can be specified if necessary, in either case a peer * // address will be sent to the kernel in order to fullfil the interface * // requirements. If none is set, it will equal the local address. * // Note: Real peer addresses are only supported by IPv4 for now. * rtnl_addr_set_peer(addr, peer_addr); * * // In case you want to have the address have a scope other than global * // it may be overwritten using rtnl_addr_set_scope(). The scope currently * // cannot be set for IPv6 addresses. * rtnl_addr_set_scope(addr, rtnl_str2scope("site")); * * // Broadcast address may be specified using the relevant * // functions, the address family will be verified if one of the other * // addresses has been set already. Currently only works for IPv4. * rtnl_addr_set_broadcast(addr, broadcast_addr); * * // Build the netlink message and send it to the kernel, the operation will * // block until the operation has been completed. Alternatively the required * // netlink message can be built using rtnl_addr_build_add_request() to be * // sent out using nl_send_auto_complete(). * rtnl_addr_add(sk, addr, 0); * * // Free the memory * rtnl_addr_put(addr); * @endcode * * @par 2) Address Deletion * @code * // Allocate an empty address object to be filled out with the attributes * // matching the address to be deleted. Alternatively a fully equipped * // address object out of a cache can be used instead. * struct rtnl_addr *addr = rtnl_addr_alloc(); * * // The only mandatory parameter besides the address family is the interface * // index the address is on, i.e. leaving out all other parameters will * // result in all addresses of the specified address family interface tuple * // to be deleted. * rtnl_addr_set_ifindex(addr, ifindex); * * // Specyfing the address family manually is only required if neither the * // local nor peer address have been specified. * rtnl_addr_set_family(addr, AF_INET); * * // Specyfing the local address is optional but the best choice to delete * // specific addresses. * rtnl_addr_set_local(addr, local_addr); * * // The label of the address can be specified, currently only supported * // by IPv4 and DECnet. * rtnl_addr_set_label(addr, "mylabel"); * * // The peer address can be specified if necessary, in either case a peer * // address will be sent to the kernel in order to fullfil the interface * // requirements. If none is set, it will equal the local address. * // Note: Real peer addresses are only supported by IPv4 for now. * rtnl_addr_set_peer(addr, peer_addr); * * // Build the netlink message and send it to the kernel, the operation will * // block until the operation has been completed. Alternatively the required * // netlink message can be built using rtnl_addr_build_delete_request() * // to be sent out using nl_send_auto_complete(). * rtnl_addr_delete(sk, addr, 0); * * // Free the memory * rtnl_addr_put(addr); * @endcode * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define ADDR_ATTR_FAMILY 0x0001 #define ADDR_ATTR_PREFIXLEN 0x0002 #define ADDR_ATTR_FLAGS 0x0004 #define ADDR_ATTR_SCOPE 0x0008 #define ADDR_ATTR_IFINDEX 0x0010 #define ADDR_ATTR_LABEL 0x0020 #define ADDR_ATTR_CACHEINFO 0x0040 #define ADDR_ATTR_PEER 0x0080 #define ADDR_ATTR_LOCAL 0x0100 #define ADDR_ATTR_BROADCAST 0x0200 #define ADDR_ATTR_MULTICAST 0x0400 #define ADDR_ATTR_ANYCAST 0x0800 static struct nl_cache_ops rtnl_addr_ops; static struct nl_object_ops addr_obj_ops; /** @endcond */ static void addr_constructor(struct nl_object *obj) { struct rtnl_addr *addr = nl_object_priv(obj); addr->a_scope = RT_SCOPE_NOWHERE; } static void addr_free_data(struct nl_object *obj) { struct rtnl_addr *addr = nl_object_priv(obj); if (!addr) return; nl_addr_put(addr->a_peer); nl_addr_put(addr->a_local); nl_addr_put(addr->a_bcast); nl_addr_put(addr->a_multicast); nl_addr_put(addr->a_anycast); rtnl_link_put(addr->a_link); } static int addr_clone(struct nl_object *_dst, struct nl_object *_src) { struct rtnl_addr *dst = nl_object_priv(_dst); struct rtnl_addr *src = nl_object_priv(_src); if (src->a_link) { nl_object_get(OBJ_CAST(src->a_link)); dst->a_link = src->a_link; } if (src->a_peer) if (!(dst->a_peer = nl_addr_clone(src->a_peer))) return -NLE_NOMEM; if (src->a_local) if (!(dst->a_local = nl_addr_clone(src->a_local))) return -NLE_NOMEM; if (src->a_bcast) if (!(dst->a_bcast = nl_addr_clone(src->a_bcast))) return -NLE_NOMEM; if (src->a_multicast) if (!(dst->a_multicast = nl_addr_clone(src->a_multicast))) return -NLE_NOMEM; if (src->a_anycast) if (!(dst->a_anycast = nl_addr_clone(src->a_anycast))) return -NLE_NOMEM; return 0; } static struct nla_policy addr_policy[IFA_MAX+1] = { [IFA_LABEL] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [IFA_CACHEINFO] = { .minlen = sizeof(struct ifa_cacheinfo) }, }; static int addr_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct rtnl_addr *addr; struct ifaddrmsg *ifa; struct nlattr *tb[IFA_MAX+1]; int err, family; struct nl_cache *link_cache; struct nl_addr *plen_addr = NULL; addr = rtnl_addr_alloc(); if (!addr) return -NLE_NOMEM; addr->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(*ifa), tb, IFA_MAX, addr_policy); if (err < 0) goto errout; ifa = nlmsg_data(nlh); addr->a_family = family = ifa->ifa_family; addr->a_prefixlen = ifa->ifa_prefixlen; addr->a_scope = ifa->ifa_scope; addr->a_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifa->ifa_flags; addr->a_ifindex = ifa->ifa_index; addr->ce_mask = (ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN | ADDR_ATTR_FLAGS | ADDR_ATTR_SCOPE | ADDR_ATTR_IFINDEX); if (tb[IFA_LABEL]) { nla_strlcpy(addr->a_label, tb[IFA_LABEL], IFNAMSIZ); addr->ce_mask |= ADDR_ATTR_LABEL; } /* IPv6 only */ if (tb[IFA_CACHEINFO]) { struct ifa_cacheinfo *ca; ca = nla_data(tb[IFA_CACHEINFO]); addr->a_cacheinfo.aci_prefered = ca->ifa_prefered; addr->a_cacheinfo.aci_valid = ca->ifa_valid; addr->a_cacheinfo.aci_cstamp = ca->cstamp; addr->a_cacheinfo.aci_tstamp = ca->tstamp; addr->ce_mask |= ADDR_ATTR_CACHEINFO; } if (family == AF_INET) { uint32_t null = 0; /* for IPv4/AF_INET, kernel always sets IFA_LOCAL and IFA_ADDRESS, unless it * is effectively 0.0.0.0. */ if (tb[IFA_LOCAL]) addr->a_local = nl_addr_alloc_attr(tb[IFA_LOCAL], family); else addr->a_local = nl_addr_build(family, &null, sizeof (null)); if (!addr->a_local) goto errout_nomem; addr->ce_mask |= ADDR_ATTR_LOCAL; if (tb[IFA_ADDRESS]) addr->a_peer = nl_addr_alloc_attr(tb[IFA_ADDRESS], family); else addr->a_peer = nl_addr_build(family, &null, sizeof (null)); if (!addr->a_peer) goto errout_nomem; if (!nl_addr_cmp (addr->a_local, addr->a_peer)) { /* having IFA_ADDRESS equal to IFA_LOCAL does not really mean * there is no peer. It means the peer is equal to the local address, * which is the case for "normal" addresses. * * Still, clear the peer and pretend it is unset for backward * compatibility. */ nl_addr_put(addr->a_peer); addr->a_peer = NULL; } else addr->ce_mask |= ADDR_ATTR_PEER; plen_addr = addr->a_local; } else { if (tb[IFA_LOCAL]) { addr->a_local = nl_addr_alloc_attr(tb[IFA_LOCAL], family); if (!addr->a_local) goto errout_nomem; addr->ce_mask |= ADDR_ATTR_LOCAL; plen_addr = addr->a_local; } if (tb[IFA_ADDRESS]) { struct nl_addr *a; a = nl_addr_alloc_attr(tb[IFA_ADDRESS], family); if (!a) goto errout_nomem; /* IPv6 sends the local address as IFA_ADDRESS with * no IFA_LOCAL, IPv4 sends both IFA_LOCAL and IFA_ADDRESS * with IFA_ADDRESS being the peer address if they differ */ if (!tb[IFA_LOCAL] || !nl_addr_cmp(a, addr->a_local)) { nl_addr_put(addr->a_local); addr->a_local = a; addr->ce_mask |= ADDR_ATTR_LOCAL; } else { addr->a_peer = a; addr->ce_mask |= ADDR_ATTR_PEER; } plen_addr = a; } } if (plen_addr) nl_addr_set_prefixlen(plen_addr, addr->a_prefixlen); /* IPv4 only */ if (tb[IFA_BROADCAST]) { addr->a_bcast = nl_addr_alloc_attr(tb[IFA_BROADCAST], family); if (!addr->a_bcast) goto errout_nomem; addr->ce_mask |= ADDR_ATTR_BROADCAST; } /* IPv6 only */ if (tb[IFA_MULTICAST]) { addr->a_multicast = nl_addr_alloc_attr(tb[IFA_MULTICAST], family); if (!addr->a_multicast) goto errout_nomem; addr->ce_mask |= ADDR_ATTR_MULTICAST; } /* IPv6 only */ if (tb[IFA_ANYCAST]) { addr->a_anycast = nl_addr_alloc_attr(tb[IFA_ANYCAST], family); if (!addr->a_anycast) goto errout_nomem; addr->ce_mask |= ADDR_ATTR_ANYCAST; } if ((link_cache = __nl_cache_mngt_require("route/link"))) { struct rtnl_link *link; if ((link = rtnl_link_get(link_cache, addr->a_ifindex))) { rtnl_addr_set_link(addr, link); /* rtnl_addr_set_link incs refcnt */ rtnl_link_put(link); } } err = pp->pp_cb((struct nl_object *) addr, pp); errout: rtnl_addr_put(addr); return err; errout_nomem: err = -NLE_NOMEM; goto errout; } static int addr_request_update(struct nl_cache *cache, struct nl_sock *sk) { return nl_rtgen_request(sk, RTM_GETADDR, AF_UNSPEC, NLM_F_DUMP); } static void addr_dump_line(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_addr *addr = (struct rtnl_addr *) obj; struct nl_cache *link_cache; char buf[128]; link_cache = nl_cache_mngt_require_safe("route/link"); if (addr->ce_mask & ADDR_ATTR_LOCAL) nl_dump_line(p, "%s", nl_addr2str(addr->a_local, buf, sizeof(buf))); else nl_dump_line(p, "none"); if (addr->ce_mask & ADDR_ATTR_PEER) nl_dump(p, " peer %s", nl_addr2str(addr->a_peer, buf, sizeof(buf))); nl_dump(p, " %s ", nl_af2str(addr->a_family, buf, sizeof(buf))); if (link_cache) nl_dump(p, "dev %s ", rtnl_link_i2name(link_cache, addr->a_ifindex, buf, sizeof(buf))); else nl_dump(p, "dev %d ", addr->a_ifindex); nl_dump(p, "scope %s", rtnl_scope2str(addr->a_scope, buf, sizeof(buf))); rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf)); if (buf[0]) nl_dump(p, " <%s>", buf); nl_dump(p, "\n"); if (link_cache) nl_cache_put(link_cache); } static void addr_dump_details(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_addr *addr = (struct rtnl_addr *) obj; char buf[128]; addr_dump_line(obj, p); if (addr->ce_mask & (ADDR_ATTR_LABEL | ADDR_ATTR_BROADCAST | ADDR_ATTR_MULTICAST)) { nl_dump_line(p, " "); if (addr->ce_mask & ADDR_ATTR_LABEL) nl_dump(p, " label %s", addr->a_label); if (addr->ce_mask & ADDR_ATTR_BROADCAST) nl_dump(p, " broadcast %s", nl_addr2str(addr->a_bcast, buf, sizeof(buf))); if (addr->ce_mask & ADDR_ATTR_MULTICAST) nl_dump(p, " multicast %s", nl_addr2str(addr->a_multicast, buf, sizeof(buf))); if (addr->ce_mask & ADDR_ATTR_ANYCAST) nl_dump(p, " anycast %s", nl_addr2str(addr->a_anycast, buf, sizeof(buf))); nl_dump(p, "\n"); } if (addr->ce_mask & ADDR_ATTR_CACHEINFO) { struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo; nl_dump_line(p, " valid-lifetime %s", ci->aci_valid == 0xFFFFFFFFU ? "forever" : nl_msec2str(ci->aci_valid * 1000, buf, sizeof(buf))); nl_dump(p, " preferred-lifetime %s\n", ci->aci_prefered == 0xFFFFFFFFU ? "forever" : nl_msec2str(ci->aci_prefered * 1000, buf, sizeof(buf))); nl_dump_line(p, " created boot-time+%s ", nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10, buf, sizeof(buf))); nl_dump(p, "last-updated boot-time+%s\n", nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10, buf, sizeof(buf))); } } static void addr_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { addr_dump_details(obj, p); } static uint32_t addr_id_attrs_get(struct nl_object *obj) { struct rtnl_addr *addr = (struct rtnl_addr *)obj; uint32_t rv; switch (addr->a_family) { case AF_INET: rv = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN); if (addr->a_peer) rv |= ADDR_ATTR_PEER; return rv; case AF_INET6: return (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | ADDR_ATTR_LOCAL); default: return (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN); } } static uint64_t addr_compare(struct nl_object *_a, struct nl_object *_b, uint64_t attrs, int flags) { struct rtnl_addr *a = (struct rtnl_addr *) _a; struct rtnl_addr *b = (struct rtnl_addr *) _b; uint64_t diff = 0; #define ADDR_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ADDR_ATTR_##ATTR, a, b, EXPR) diff |= ADDR_DIFF(IFINDEX, a->a_ifindex != b->a_ifindex); diff |= ADDR_DIFF(FAMILY, a->a_family != b->a_family); diff |= ADDR_DIFF(SCOPE, a->a_scope != b->a_scope); diff |= ADDR_DIFF(LABEL, strcmp(a->a_label, b->a_label)); if (attrs & ADDR_ATTR_PEER) { if ( (flags & ID_COMPARISON) && a->a_family == AF_INET && b->a_family == AF_INET && a->a_peer && b->a_peer && a->a_prefixlen == b->a_prefixlen) { /* when comparing two IPv4 addresses for id-equality, the network part * of the PEER address shall be compared. */ diff |= ADDR_DIFF(PEER, nl_addr_cmp_prefix(a->a_peer, b->a_peer)); } else diff |= ADDR_DIFF(PEER, nl_addr_cmp(a->a_peer, b->a_peer)); } diff |= ADDR_DIFF(LOCAL, nl_addr_cmp(a->a_local, b->a_local)); diff |= ADDR_DIFF(MULTICAST, nl_addr_cmp(a->a_multicast, b->a_multicast)); diff |= ADDR_DIFF(BROADCAST, nl_addr_cmp(a->a_bcast, b->a_bcast)); diff |= ADDR_DIFF(ANYCAST, nl_addr_cmp(a->a_anycast, b->a_anycast)); diff |= ADDR_DIFF(CACHEINFO, memcmp(&a->a_cacheinfo, &b->a_cacheinfo, sizeof (a->a_cacheinfo))); if (flags & LOOSE_COMPARISON) diff |= ADDR_DIFF(FLAGS, (a->a_flags ^ b->a_flags) & b->a_flag_mask); else diff |= ADDR_DIFF(FLAGS, a->a_flags != b->a_flags); #undef ADDR_DIFF return diff; } static const struct trans_tbl addr_attrs[] = { __ADD(ADDR_ATTR_FAMILY, family), __ADD(ADDR_ATTR_PREFIXLEN, prefixlen), __ADD(ADDR_ATTR_FLAGS, flags), __ADD(ADDR_ATTR_SCOPE, scope), __ADD(ADDR_ATTR_IFINDEX, ifindex), __ADD(ADDR_ATTR_LABEL, label), __ADD(ADDR_ATTR_CACHEINFO, cacheinfo), __ADD(ADDR_ATTR_PEER, peer), __ADD(ADDR_ATTR_LOCAL, local), __ADD(ADDR_ATTR_BROADCAST, broadcast), __ADD(ADDR_ATTR_MULTICAST, multicast), }; static char *addr_attrs2str(int attrs, char *buf, size_t len) { return __flags2str(attrs, buf, len, addr_attrs, ARRAY_SIZE(addr_attrs)); } /** * @name Allocation/Freeing * @{ */ struct rtnl_addr *rtnl_addr_alloc(void) { return (struct rtnl_addr *) nl_object_alloc(&addr_obj_ops); } void rtnl_addr_put(struct rtnl_addr *addr) { nl_object_put((struct nl_object *) addr); } /** @} */ /** * @name Cache Management * @{ */ int rtnl_addr_alloc_cache(struct nl_sock *sk, struct nl_cache **result) { return nl_cache_alloc_and_fill(&rtnl_addr_ops, sk, result); } /** * Search address in cache * @arg cache Address cache * @arg ifindex Interface index of address * @arg addr Local address part * * Searches address cache previously allocated with rtnl_addr_alloc_cache() * for an address with a matching local address. * * The reference counter is incremented before returning the address, therefore * the reference must be given back with rtnl_addr_put() after usage. * * @return Address object or NULL if no match was found. */ struct rtnl_addr *rtnl_addr_get(struct nl_cache *cache, int ifindex, struct nl_addr *addr) { struct rtnl_addr *a; if (cache->c_ops != &rtnl_addr_ops) return NULL; nl_list_for_each_entry(a, &cache->c_items, ce_list) { if (ifindex && a->a_ifindex != ifindex) continue; if (a->ce_mask & ADDR_ATTR_LOCAL && !nl_addr_cmp(a->a_local, addr)) { nl_object_get((struct nl_object *) a); return a; } } return NULL; } /** @} */ static int build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; struct ifaddrmsg am = { .ifa_family = tmpl->a_family, .ifa_index = tmpl->a_ifindex, .ifa_prefixlen = tmpl->a_prefixlen, .ifa_flags = tmpl->a_flags, }; if (tmpl->ce_mask & ADDR_ATTR_SCOPE) am.ifa_scope = tmpl->a_scope; else { /* compatibility hack */ if (tmpl->a_family == AF_INET && tmpl->ce_mask & ADDR_ATTR_LOCAL && *((char *) nl_addr_get_binary_addr(tmpl->a_local)) == 127) am.ifa_scope = RT_SCOPE_HOST; else am.ifa_scope = RT_SCOPE_UNIVERSE; } msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &am, sizeof(am), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tmpl->ce_mask & ADDR_ATTR_LOCAL) NLA_PUT_ADDR(msg, IFA_LOCAL, tmpl->a_local); if (tmpl->ce_mask & ADDR_ATTR_PEER) NLA_PUT_ADDR(msg, IFA_ADDRESS, tmpl->a_peer); else if (tmpl->ce_mask & ADDR_ATTR_LOCAL) NLA_PUT_ADDR(msg, IFA_ADDRESS, tmpl->a_local); if (tmpl->ce_mask & ADDR_ATTR_LABEL) NLA_PUT_STRING(msg, IFA_LABEL, tmpl->a_label); if (tmpl->ce_mask & ADDR_ATTR_BROADCAST) NLA_PUT_ADDR(msg, IFA_BROADCAST, tmpl->a_bcast); if (tmpl->ce_mask & ADDR_ATTR_CACHEINFO) { struct ifa_cacheinfo ca = { .ifa_valid = tmpl->a_cacheinfo.aci_valid, .ifa_prefered = tmpl->a_cacheinfo.aci_prefered, }; NLA_PUT(msg, IFA_CACHEINFO, sizeof(ca), &ca); } if (tmpl->a_flags & ~0xFF) { /* only set the IFA_FLAGS attribute, if they actually contain additional * flags that are not already set to am.ifa_flags. * * Older kernels refuse RTM_NEWADDR and RTM_NEWROUTE messages with EINVAL * if they contain unknown netlink attributes. See net/core/rtnetlink.c, which * was fixed by kernel commit 661d2967b3f1b34eeaa7e212e7b9bbe8ee072b59. * * With this workaround, libnl will function correctly with older kernels, * unless there is a new libnl user that wants to set these flags. In this * case it's up to the user to workaround this issue. */ NLA_PUT_U32(msg, IFA_FLAGS, tmpl->a_flags); } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * @name Addition * @{ */ /** * Build netlink request message to request addition of new address * @arg addr Address object representing the new address. * @arg flags Additional netlink message flags. * @arg result Pointer to store resulting message. * * Builds a new netlink message requesting the addition of a new * address. The netlink message header isn't fully equipped with * all relevant fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. * * Minimal required attributes: * - interface index (rtnl_addr_set_ifindex()) * - local address (rtnl_addr_set_local()) * * The scope will default to universe except for loopback addresses in * which case a host scope is used if not specified otherwise. * * @note Free the memory after usage using nlmsg_free(). * * @return 0 on success or a negative error code. */ int rtnl_addr_build_add_request(struct rtnl_addr *addr, int flags, struct nl_msg **result) { uint32_t required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN | ADDR_ATTR_LOCAL; if ((addr->ce_mask & required) != required) return -NLE_MISSING_ATTR; return build_addr_msg(addr, RTM_NEWADDR, NLM_F_CREATE | flags, result); } /** * Request addition of new address * @arg sk Netlink socket. * @arg addr Address object representing the new address. * @arg flags Additional netlink message flags. * * Builds a netlink message by calling rtnl_addr_build_add_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @see rtnl_addr_build_add_request() * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_addr_add(struct nl_sock *sk, struct rtnl_addr *addr, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_addr_build_add_request(addr, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ /** * @name Deletion * @{ */ /** * Build a netlink request message to request deletion of an address * @arg addr Address object to be deleteted. * @arg flags Additional netlink message flags. * @arg result Pointer to store resulting message. * * Builds a new netlink message requesting a deletion of an address. * The netlink message header isn't fully equipped with all relevant * fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. * * Minimal required attributes: * - interface index (rtnl_addr_set_ifindex()) * - address family (rtnl_addr_set_family()) * * Optional attributes: * - local address (rtnl_addr_set_local()) * - label (rtnl_addr_set_label(), IPv4/DECnet only) * - peer address (rtnl_addr_set_peer(), IPv4 only) * * @note Free the memory after usage using nlmsg_free(). * * @return 0 on success or a negative error code. */ int rtnl_addr_build_delete_request(struct rtnl_addr *addr, int flags, struct nl_msg **result) { uint32_t required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY; if ((addr->ce_mask & required) != required) return -NLE_MISSING_ATTR; return build_addr_msg(addr, RTM_DELADDR, flags, result); } /** * Request deletion of an address * @arg sk Netlink socket. * @arg addr Address object to be deleted. * @arg flags Additional netlink message flags. * * Builds a netlink message by calling rtnl_addr_build_delete_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @see rtnl_addr_build_delete_request(); * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_addr_delete(struct nl_sock *sk, struct rtnl_addr *addr, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_addr_build_delete_request(addr, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ /** * @name Attributes * @{ */ int rtnl_addr_set_label(struct rtnl_addr *addr, const char *label) { if (strlen(label) > sizeof(addr->a_label) - 1) return -NLE_RANGE; strcpy(addr->a_label, label); addr->ce_mask |= ADDR_ATTR_LABEL; return 0; } char *rtnl_addr_get_label(struct rtnl_addr *addr) { if (addr->ce_mask & ADDR_ATTR_LABEL) return addr->a_label; else return NULL; } void rtnl_addr_set_ifindex(struct rtnl_addr *addr, int ifindex) { addr->a_ifindex = ifindex; addr->ce_mask |= ADDR_ATTR_IFINDEX; } int rtnl_addr_get_ifindex(struct rtnl_addr *addr) { return addr->a_ifindex; } void rtnl_addr_set_link(struct rtnl_addr *addr, struct rtnl_link *link) { rtnl_link_put(addr->a_link); if (!link) return; nl_object_get(OBJ_CAST(link)); addr->a_link = link; addr->a_ifindex = link->l_index; addr->ce_mask |= ADDR_ATTR_IFINDEX; } struct rtnl_link *rtnl_addr_get_link(struct rtnl_addr *addr) { if (addr->a_link) { nl_object_get(OBJ_CAST(addr->a_link)); return addr->a_link; } return NULL; } void rtnl_addr_set_family(struct rtnl_addr *addr, int family) { addr->a_family = family; addr->ce_mask |= ADDR_ATTR_FAMILY; } int rtnl_addr_get_family(struct rtnl_addr *addr) { return addr->a_family; } /** * Set the prefix length / netmask * @arg addr Address * @arg prefixlen Length of prefix (netmask) * * Modifies the length of the prefix. If the address object contains a peer * address the prefix length will apply to it, otherwise the prefix length * will apply to the local address of the address. * * If the address object contains a peer or local address the corresponding * `struct nl_addr` will be updated with the new prefix length. * * @note Specifying a length of 0 will remove the prefix length alltogether. * * @see rtnl_addr_get_prefixlen() */ void rtnl_addr_set_prefixlen(struct rtnl_addr *addr, int prefixlen) { addr->a_prefixlen = prefixlen; if (prefixlen) addr->ce_mask |= ADDR_ATTR_PREFIXLEN; else addr->ce_mask &= ~ADDR_ATTR_PREFIXLEN; /* * The prefix length always applies to the peer address if * a peer address is present. */ if (addr->a_peer) nl_addr_set_prefixlen(addr->a_peer, prefixlen); else if (addr->a_local) nl_addr_set_prefixlen(addr->a_local, prefixlen); } int rtnl_addr_get_prefixlen(struct rtnl_addr *addr) { return addr->a_prefixlen; } void rtnl_addr_set_scope(struct rtnl_addr *addr, int scope) { addr->a_scope = scope; addr->ce_mask |= ADDR_ATTR_SCOPE; } int rtnl_addr_get_scope(struct rtnl_addr *addr) { return addr->a_scope; } void rtnl_addr_set_flags(struct rtnl_addr *addr, unsigned int flags) { addr->a_flag_mask |= flags; addr->a_flags |= flags; addr->ce_mask |= ADDR_ATTR_FLAGS; } void rtnl_addr_unset_flags(struct rtnl_addr *addr, unsigned int flags) { addr->a_flag_mask |= flags; addr->a_flags &= ~flags; addr->ce_mask |= ADDR_ATTR_FLAGS; } unsigned int rtnl_addr_get_flags(struct rtnl_addr *addr) { return addr->a_flags; } static inline int __assign_addr(struct rtnl_addr *addr, struct nl_addr **pos, struct nl_addr *new, int flag) { if (new) { if (addr->ce_mask & ADDR_ATTR_FAMILY) { if (new->a_family != addr->a_family) return -NLE_AF_MISMATCH; } else addr->a_family = new->a_family; if (*pos) nl_addr_put(*pos); *pos = nl_addr_get(new); addr->ce_mask |= (flag | ADDR_ATTR_FAMILY); } else { if (*pos) nl_addr_put(*pos); *pos = NULL; addr->ce_mask &= ~flag; } return 0; } int rtnl_addr_set_local(struct rtnl_addr *addr, struct nl_addr *local) { int err; /* Prohibit local address with prefix length if peer address is present */ if ((addr->ce_mask & ADDR_ATTR_PEER) && local && nl_addr_get_prefixlen(local)) return -NLE_INVAL; err = __assign_addr(addr, &addr->a_local, local, ADDR_ATTR_LOCAL); if (err < 0) return err; /* Never overwrite the prefix length if a peer address is present */ if (!(addr->ce_mask & ADDR_ATTR_PEER)) rtnl_addr_set_prefixlen(addr, local ? nl_addr_get_prefixlen(local) : 0); return 0; } struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *addr) { return addr->a_local; } int rtnl_addr_set_peer(struct rtnl_addr *addr, struct nl_addr *peer) { int err; if (peer && peer->a_family != AF_INET) return -NLE_AF_NOSUPPORT; err = __assign_addr(addr, &addr->a_peer, peer, ADDR_ATTR_PEER); if (err < 0) return err; rtnl_addr_set_prefixlen(addr, peer ? nl_addr_get_prefixlen(peer) : 0); return 0; } struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *addr) { return addr->a_peer; } int rtnl_addr_set_broadcast(struct rtnl_addr *addr, struct nl_addr *bcast) { if (bcast && bcast->a_family != AF_INET) return -NLE_AF_NOSUPPORT; return __assign_addr(addr, &addr->a_bcast, bcast, ADDR_ATTR_BROADCAST); } struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *addr) { return addr->a_bcast; } int rtnl_addr_set_multicast(struct rtnl_addr *addr, struct nl_addr *multicast) { if (multicast && multicast->a_family != AF_INET6) return -NLE_AF_NOSUPPORT; return __assign_addr(addr, &addr->a_multicast, multicast, ADDR_ATTR_MULTICAST); } struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr) { return addr->a_multicast; } int rtnl_addr_set_anycast(struct rtnl_addr *addr, struct nl_addr *anycast) { if (anycast && anycast->a_family != AF_INET6) return -NLE_AF_NOSUPPORT; return __assign_addr(addr, &addr->a_anycast, anycast, ADDR_ATTR_ANYCAST); } struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *addr) { return addr->a_anycast; } uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *addr) { if (addr->ce_mask & ADDR_ATTR_CACHEINFO) return addr->a_cacheinfo.aci_valid; else return 0xFFFFFFFFU; } void rtnl_addr_set_valid_lifetime(struct rtnl_addr *addr, uint32_t lifetime) { addr->a_cacheinfo.aci_valid = lifetime; addr->ce_mask |= ADDR_ATTR_CACHEINFO; } uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *addr) { if (addr->ce_mask & ADDR_ATTR_CACHEINFO) return addr->a_cacheinfo.aci_prefered; else return 0xFFFFFFFFU; } void rtnl_addr_set_preferred_lifetime(struct rtnl_addr *addr, uint32_t lifetime) { addr->a_cacheinfo.aci_prefered = lifetime; addr->ce_mask |= ADDR_ATTR_CACHEINFO; } uint32_t rtnl_addr_get_create_time(struct rtnl_addr *addr) { return addr->a_cacheinfo.aci_cstamp; } uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *addr) { return addr->a_cacheinfo.aci_tstamp; } /** @} */ /** * @name Flags Translations * @{ */ static const struct trans_tbl addr_flags[] = { __ADD(IFA_F_SECONDARY, secondary), __ADD(IFA_F_NODAD, nodad), __ADD(IFA_F_OPTIMISTIC, optimistic), __ADD(IFA_F_HOMEADDRESS, homeaddress), __ADD(IFA_F_DEPRECATED, deprecated), __ADD(IFA_F_TENTATIVE, tentative), __ADD(IFA_F_PERMANENT, permanent), __ADD(IFA_F_MANAGETEMPADDR, mngtmpaddr), __ADD(IFA_F_NOPREFIXROUTE, noprefixroute), }; char *rtnl_addr_flags2str(int flags, char *buf, size_t size) { return __flags2str(flags, buf, size, addr_flags, ARRAY_SIZE(addr_flags)); } int rtnl_addr_str2flags(const char *name) { return __str2flags(name, addr_flags, ARRAY_SIZE(addr_flags)); } /** @} */ static struct nl_object_ops addr_obj_ops = { .oo_name = "route/addr", .oo_size = sizeof(struct rtnl_addr), .oo_constructor = addr_constructor, .oo_free_data = addr_free_data, .oo_clone = addr_clone, .oo_dump = { [NL_DUMP_LINE] = addr_dump_line, [NL_DUMP_DETAILS] = addr_dump_details, [NL_DUMP_STATS] = addr_dump_stats, }, .oo_compare = addr_compare, .oo_attrs2str = addr_attrs2str, .oo_id_attrs_get = addr_id_attrs_get, .oo_id_attrs = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN), }; static struct nl_af_group addr_groups[] = { { AF_INET, RTNLGRP_IPV4_IFADDR }, { AF_INET6, RTNLGRP_IPV6_IFADDR }, { END_OF_GROUP_LIST }, }; static struct nl_cache_ops rtnl_addr_ops = { .co_name = "route/addr", .co_hdrsize = sizeof(struct ifaddrmsg), .co_msgtypes = { { RTM_NEWADDR, NL_ACT_NEW, "new" }, { RTM_DELADDR, NL_ACT_DEL, "del" }, { RTM_GETADDR, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_groups = addr_groups, .co_request_update = addr_request_update, .co_msg_parser = addr_msg_parser, .co_obj_ops = &addr_obj_ops, }; static void __init addr_init(void) { nl_cache_mngt_register(&rtnl_addr_ops); } static void __exit addr_exit(void) { nl_cache_mngt_unregister(&rtnl_addr_ops); } /** @} */ libnl-3.2.29/lib/route/link/0000755000175000017500000000000013031473756012562 500000000000000libnl-3.2.29/lib/route/link/ipvlan.c0000644000175000017500000001263013023014600014115 00000000000000/* * lib/route/link/ipvlan.c IPVLAN Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2015 Cong Wang */ /** * @ingroup link * @defgroup ipvlan IPVLAN * IP-based Virtual LAN link module * * @details * \b Link Type Name: "ipvlan" * * @route_doc{link_ipvlan, IPVLAN Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define IPVLAN_HAS_MODE (1<<0) struct ipvlan_info { uint16_t ipi_mode; uint32_t ipi_mask; }; /** @endcond */ static struct nla_policy ipvlan_policy[IFLA_IPVLAN_MAX+1] = { [IFLA_IPVLAN_MODE] = { .type = NLA_U16 }, }; static int ipvlan_alloc(struct rtnl_link *link) { struct ipvlan_info *ipi; if (link->l_info) memset(link->l_info, 0, sizeof(*ipi)); else { if ((ipi = calloc(1, sizeof(*ipi))) == NULL) return -NLE_NOMEM; link->l_info = ipi; } return 0; } static int ipvlan_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_IPVLAN_MAX+1]; struct ipvlan_info *ipi; int err; NL_DBG(3, "Parsing IPVLAN link info\n"); if ((err = nla_parse_nested(tb, IFLA_IPVLAN_MAX, data, ipvlan_policy)) < 0) goto errout; if ((err = ipvlan_alloc(link)) < 0) goto errout; ipi = link->l_info; if (tb[IFLA_IPVLAN_MODE]) { ipi->ipi_mode = nla_get_u16(tb[IFLA_IPVLAN_MODE]); ipi->ipi_mask |= IPVLAN_HAS_MODE; } err = 0; errout: return err; } static void ipvlan_free(struct rtnl_link *link) { free(link->l_info); link->l_info = NULL; } static void ipvlan_dump(struct rtnl_link *link, struct nl_dump_params *p) { char buf[64]; struct ipvlan_info *ipi = link->l_info; if (ipi->ipi_mask & IPVLAN_HAS_MODE) { rtnl_link_ipvlan_mode2str(ipi->ipi_mode, buf, sizeof(buf)); nl_dump(p, "ipvlan-mode %s", buf); } } static int ipvlan_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct ipvlan_info *vdst, *vsrc = src->l_info; int err; dst->l_info = NULL; if ((err = rtnl_link_set_type(dst, "ipvlan")) < 0) return err; vdst = dst->l_info; if (!vdst || !vsrc) return -NLE_NOMEM; memcpy(vdst, vsrc, sizeof(struct ipvlan_info)); return 0; } static int ipvlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct ipvlan_info *ipi = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; if (ipi->ipi_mask & IPVLAN_HAS_MODE) NLA_PUT_U16(msg, IFLA_IPVLAN_MODE, ipi->ipi_mode); nla_nest_end(msg, data); nla_put_failure: return 0; } static struct rtnl_link_info_ops ipvlan_info_ops = { .io_name = "ipvlan", .io_alloc = ipvlan_alloc, .io_parse = ipvlan_parse, .io_dump = { [NL_DUMP_LINE] = ipvlan_dump, [NL_DUMP_DETAILS] = ipvlan_dump, }, .io_clone = ipvlan_clone, .io_put_attrs = ipvlan_put_attrs, .io_free = ipvlan_free, }; /** @cond SKIP */ #define IS_IPVLAN_LINK_ASSERT(link) \ if ((link)->l_info_ops != &ipvlan_info_ops) { \ APPBUG("Link is not a ipvlan link. set type \"ipvlan\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ /** * @name IPVLAN Object * @{ */ /** * Allocate link object of type IPVLAN * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_ipvlan_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "ipvlan")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a IPVLAN link * @arg link Link object * * @return True if link is a IPVLAN link, otherwise false is returned. */ int rtnl_link_is_ipvlan(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ipvlan"); } /** * Set IPVLAN MODE * @arg link Link object * @arg mode IPVLAN mode * * @return 0 on success or a negative error code */ int rtnl_link_ipvlan_set_mode(struct rtnl_link *link, uint16_t mode) { struct ipvlan_info *ipi = link->l_info; IS_IPVLAN_LINK_ASSERT(link); ipi->ipi_mode = mode; ipi->ipi_mask |= IPVLAN_HAS_MODE; return 0; } /** * Get IPVLAN Mode * @arg link Link object * @arg out_mode on success, return the mode * * @return 0 on success or a negative error code. */ int rtnl_link_ipvlan_get_mode(struct rtnl_link *link, uint16_t *out_mode) { struct ipvlan_info *ipi = link->l_info; IS_IPVLAN_LINK_ASSERT(link); if (!(ipi->ipi_mask & IPVLAN_HAS_MODE)) return -NLE_INVAL; *out_mode = ipi->ipi_mode; return 0; } /** @} */ static const struct trans_tbl ipvlan_modes[] = { __ADD(IPVLAN_MODE_L2, l2), __ADD(IPVLAN_MODE_L3, l3), }; /** * @name Mode Translation * @{ */ char *rtnl_link_ipvlan_mode2str(int mode, char *buf, size_t len) { return __type2str(mode, buf, len, ipvlan_modes, ARRAY_SIZE(ipvlan_modes)); } int rtnl_link_ipvlan_str2mode(const char *name) { return __str2type(name, ipvlan_modes, ARRAY_SIZE(ipvlan_modes)); } /** @} */ static void __init ipvlan_init(void) { rtnl_link_register_info(&ipvlan_info_ops); } static void __exit ipvlan_exit(void) { rtnl_link_unregister_info(&ipvlan_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/dummy.c0000644000175000017500000000143313023014600013756 00000000000000/* * lib/route/link/dummy.c Dummy Interfaces * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2011 Thomas Graf */ /** * @ingroup link * @defgroup dummy Dummy * * @details * \b Link Type Name: "dummy" * * @{ */ #include #include #include static struct rtnl_link_info_ops dummy_info_ops = { .io_name = "dummy", }; static void __init dummy_init(void) { rtnl_link_register_info(&dummy_info_ops); } static void __exit dummy_exit(void) { rtnl_link_unregister_info(&dummy_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/vrf.c0000644000175000017500000001211513023014600013417 00000000000000/* * lib/route/link/vrf.c VRF Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2015 Cumulus Networks. All rights reserved. * Copyright (c) 2015 David Ahern */ /** * @ingroup link * @defgroup vrf VRF * Virtual Routing and Forwarding link module * * @details * \b Link Type Name: "vrf" * * @route_doc{link_vrf, VRF Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include #include #define VRF_TABLE_ID_MAX RT_TABLE_MAX /** @cond SKIP */ #define VRF_HAS_TABLE_ID (1<<0) struct vrf_info { uint32_t table_id; uint32_t vi_mask; }; /** @endcond */ static struct nla_policy vrf_policy[IFLA_VRF_MAX + 1] = { [IFLA_VRF_TABLE] = { .type = NLA_U32 }, }; static int vrf_alloc(struct rtnl_link *link) { struct vrf_info *vi; if (link->l_info) { memset(link->l_info, 0, sizeof (*vi)); return 0; } if ((vi = calloc(1, sizeof(*vi))) == NULL) return -NLE_NOMEM; link->l_info = vi; return 0; } static int vrf_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_VRF_MAX+1]; struct vrf_info *vi; int err; NL_DBG(3, "Parsing VRF link info"); if ((err = nla_parse_nested(tb, IFLA_VRF_MAX, data, vrf_policy)) < 0) goto errout; if ((err = vrf_alloc(link)) < 0) goto errout; vi = link->l_info; if (tb[IFLA_VRF_TABLE]) { vi->table_id = nla_get_u32(tb[IFLA_VRF_TABLE]); vi->vi_mask |= VRF_HAS_TABLE_ID; } err = 0; errout: return err; } static void vrf_free(struct rtnl_link *link) { free(link->l_info); link->l_info = NULL; } static int vrf_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct vrf_info *vdst, *vsrc = src->l_info; int err; if ((err = rtnl_link_set_type(dst, "vrf")) < 0) return err; vdst = dst->l_info; BUG_ON(!vdst || !vsrc); memcpy(vdst, vsrc, sizeof(struct vrf_info)); return 0; } static int vrf_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct vrf_info *vi = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_NOMEM; if (vi->vi_mask & VRF_HAS_TABLE_ID) { NLA_PUT_U32(msg, IFLA_VRF_TABLE, vi->table_id); } nla_nest_end(msg, data); nla_put_failure: return 0; } static void vrf_dump(struct rtnl_link *link, struct nl_dump_params *p) { struct vrf_info *vi = link->l_info; if (vi->vi_mask & VRF_HAS_TABLE_ID) { nl_dump(p, "table-id %u", vi->table_id); } } static struct rtnl_link_info_ops vrf_info_ops = { .io_name = "vrf", .io_alloc = vrf_alloc, .io_parse = vrf_parse, .io_dump = { [NL_DUMP_LINE] = vrf_dump, [NL_DUMP_DETAILS] = vrf_dump, }, .io_clone = vrf_clone, .io_put_attrs = vrf_put_attrs, .io_free = vrf_free, }; /** @cond SKIP */ #define IS_VRF_LINK_ASSERT(link) \ if ((link)->l_info_ops != &vrf_info_ops) { \ APPBUG("Link is not a VRF link. set type \"vrf\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ /** * @name VRF Object * @{ */ /** * Allocate link object of type VRF * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_vrf_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "vrf")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a VRF link * @arg link Link object * * @return True if link is a VRF link, otherwise false is returned. */ int rtnl_link_is_vrf(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vrf"); } /** * Get VRF table id * @arg link Link object * @arg id Pointer to store table identifier * * @return 0 on success or a negative error code */ int rtnl_link_vrf_get_tableid(struct rtnl_link *link, uint32_t *id) { struct vrf_info *vi = link->l_info; IS_VRF_LINK_ASSERT(link); if(!id) return -NLE_INVAL; if (vi->vi_mask & VRF_HAS_TABLE_ID) *id = vi->table_id; else return -NLE_AGAIN; return 0; } /** * Set VRF table id * @arg link Link object * @arg id Table identifier associated with VRF link * * @return 0 on success or a negative error code */ int rtnl_link_vrf_set_tableid(struct rtnl_link *link, uint32_t id) { struct vrf_info *vi = link->l_info; IS_VRF_LINK_ASSERT(link); if(id > VRF_TABLE_ID_MAX) return -NLE_INVAL; vi->table_id = id; vi->vi_mask |= VRF_HAS_TABLE_ID; return 0; } /** @} */ static void __init vrf_init(void) { rtnl_link_register_info(&vrf_info_ops); } static void __exit vrf_exit(void) { rtnl_link_unregister_info(&vrf_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/inet.c0000644000175000017500000001705713023014600013573 00000000000000/* * lib/route/link/inet.c AF_INET link operations * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ /** * @ingroup link_API * @defgroup link_inet IPv4 Link Module * @brief Implementation of IPv4 specific link attributes * * * * @par Example: Reading the value of IPV4_DEVCONF_FORWARDING * @code * struct nl_cache *cache; * struct rtnl_link *link; * uint32_t value; * * // Allocate a link cache * rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache); * * // Search for the link we wish to see the value from * link = rtnl_link_get_by_name(cache, "eth0"); * * // Read the value of the setting IPV4_DEVCONF_FORWARDING * if (rtnl_link_inet_get_conf(link, IPV4_DEVCONF_FORWARDING, &value) < 0) * // Error: Unable to read config setting * * printf("forwarding is %s\n", value ? "enabled" : "disabled"); * @endcode * * @par Example: Changing the value of IPV4_DEVCONF_FOWARDING * @code * // * // ... Continueing from the previous example ... * // * * struct rtnl_link *new; * * // Allocate a new link to store the changes we wish to make. * new = rtnl_link_alloc(); * * // Set IPV4_DEVCONF_FORWARDING to '1' * rtnl_link_inet_set_conf(new, IPV4_DEVCONF_FORWARDING, 1); * * // Send the change request to the kernel. * rtnl_link_change(sock, link, new, 0); * @endcode * * @{ */ #include #include #include #include #include #include /** @cond SKIP */ struct inet_data { uint8_t i_confset[IPV4_DEVCONF_MAX]; uint32_t i_conf[IPV4_DEVCONF_MAX]; }; /** @endcond */ static void *inet_alloc(struct rtnl_link *link) { return calloc(1, sizeof(struct inet_data)); } static void *inet_clone(struct rtnl_link *link, void *data) { struct inet_data *id; if ((id = inet_alloc(link))) memcpy(id, data, sizeof(*id)); return id; } static void inet_free(struct rtnl_link *link, void *data) { free(data); } static struct nla_policy inet_policy[IFLA_INET_MAX+1] = { [IFLA_INET_CONF] = { .minlen = 4 }, }; static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data) { struct inet_data *id = data; struct nlattr *tb[IFLA_INET_MAX+1]; int err; err = nla_parse_nested(tb, IFLA_INET_MAX, attr, inet_policy); if (err < 0) return err; if (tb[IFLA_INET_CONF] && nla_len(tb[IFLA_INET_CONF]) % 4) return -EINVAL; if (tb[IFLA_INET_CONF]) { int i; int len = min_t(int, IPV4_DEVCONF_MAX, nla_len(tb[IFLA_INET_CONF]) / 4); for (i = 0; i < len; i++) id->i_confset[i] = 1; nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf)); } return 0; } static int inet_fill_af(struct rtnl_link *link, struct nl_msg *msg, void *data) { struct inet_data *id = data; struct nlattr *nla; int i; if (!(nla = nla_nest_start(msg, IFLA_INET_CONF))) return -NLE_MSGSIZE; for (i = 0; i < IPV4_DEVCONF_MAX; i++) if (id->i_confset[i]) NLA_PUT_U32(msg, i+1, id->i_conf[i]); nla_nest_end(msg, nla); return 0; nla_put_failure: return -NLE_MSGSIZE; } static const struct trans_tbl inet_devconf[] = { __ADD(IPV4_DEVCONF_FORWARDING, forwarding), __ADD(IPV4_DEVCONF_MC_FORWARDING, mc_forwarding), __ADD(IPV4_DEVCONF_PROXY_ARP, proxy_arp), __ADD(IPV4_DEVCONF_ACCEPT_REDIRECTS, accept_redirects), __ADD(IPV4_DEVCONF_SECURE_REDIRECTS, secure_redirects), __ADD(IPV4_DEVCONF_SEND_REDIRECTS, send_redirects), __ADD(IPV4_DEVCONF_SHARED_MEDIA, shared_media), __ADD(IPV4_DEVCONF_RP_FILTER, rp_filter), __ADD(IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route), __ADD(IPV4_DEVCONF_BOOTP_RELAY, bootp_relay), __ADD(IPV4_DEVCONF_LOG_MARTIANS, log_martians), __ADD(IPV4_DEVCONF_TAG, tag), __ADD(IPV4_DEVCONF_ARPFILTER, arpfilter), __ADD(IPV4_DEVCONF_MEDIUM_ID, medium_id), __ADD(IPV4_DEVCONF_NOXFRM, noxfrm), __ADD(IPV4_DEVCONF_NOPOLICY, nopolicy), __ADD(IPV4_DEVCONF_FORCE_IGMP_VERSION, force_igmp_version), __ADD(IPV4_DEVCONF_ARP_ANNOUNCE, arp_announce), __ADD(IPV4_DEVCONF_ARP_IGNORE, arp_ignore), __ADD(IPV4_DEVCONF_PROMOTE_SECONDARIES, promote_secondaries), __ADD(IPV4_DEVCONF_ARP_ACCEPT, arp_accept), __ADD(IPV4_DEVCONF_ARP_NOTIFY, arp_notify), __ADD(IPV4_DEVCONF_ACCEPT_LOCAL, accept_local), __ADD(IPV4_DEVCONF_SRC_VMARK, src_vmark), __ADD(IPV4_DEVCONF_PROXY_ARP_PVLAN, proxy_arp_pvlan), __ADD(IPV4_DEVCONF_ROUTE_LOCALNET, route_localnet), __ADD(IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL, igmpv2_unsolicited_report_interval), __ADD(IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL, igmpv3_unsolicited_report_interval), }; const char *rtnl_link_inet_devconf2str(int type, char *buf, size_t len) { return __type2str(type, buf, len, inet_devconf, ARRAY_SIZE(inet_devconf)); } int rtnl_link_inet_str2devconf(const char *name) { return __str2type(name, inet_devconf, ARRAY_SIZE(inet_devconf)); } static void inet_dump_details(struct rtnl_link *link, struct nl_dump_params *p, void *data) { struct inet_data *id = data; char buf[64]; int i, n = 0; nl_dump_line(p, " ipv4 devconf:\n"); nl_dump_line(p, " "); for (i = 0; i < IPV4_DEVCONF_MAX; i++) { nl_dump_line(p, "%-19s %3u", rtnl_link_inet_devconf2str(i+1, buf, sizeof(buf)), id->i_confset[i] ? id->i_conf[i] : 0); if (++n == 3) { nl_dump(p, "\n"); nl_dump_line(p, " "); n = 0; } else nl_dump(p, " "); } if (n != 0) nl_dump(p, "\n"); } static struct rtnl_link_af_ops inet_ops = { .ao_family = AF_INET, .ao_alloc = &inet_alloc, .ao_clone = &inet_clone, .ao_free = &inet_free, .ao_parse_af = &inet_parse_af, .ao_fill_af = &inet_fill_af, .ao_dump[NL_DUMP_DETAILS] = &inet_dump_details, }; /** * Get value of a ipv4 link configuration setting * @arg link Link object * @arg cfgid Configuration identifier * @arg res Result pointer * * Stores the value of the specified configuration setting in the provided * result pointer. * * @return 0 on success or a negative error code. * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX * @return -NLE_NOATTR configuration setting not available * @return -NLE_INVAL cfgid not set. If the link was received via netlink, * it means that the cfgid is not supported. */ int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid, uint32_t *res) { struct inet_data *id; if (cfgid == 0 || cfgid > IPV4_DEVCONF_MAX) return -NLE_RANGE; if (!(id = rtnl_link_af_data(link, &inet_ops))) return -NLE_NOATTR; if (!id->i_confset[cfgid - 1]) return -NLE_INVAL; *res = id->i_conf[cfgid - 1]; return 0; } /** * Change value of a ipv4 link configuration setting * @arg link Link object * @arg cfgid Configuration identifier * @arg value New value * * Changes the value in the per link ipv4 configuration array. * * @return 0 on success or a negative error code. * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX * @return -NLE_NOMEM memory allocation failed */ int rtnl_link_inet_set_conf(struct rtnl_link *link, const unsigned int cfgid, uint32_t value) { struct inet_data *id; if (!(id = rtnl_link_af_alloc(link, &inet_ops))) return -NLE_NOMEM; if (cfgid == 0 || cfgid > IPV4_DEVCONF_MAX) return -NLE_RANGE; id->i_confset[cfgid - 1] = 1; id->i_conf[cfgid - 1] = value; return 0; } static void __init inet_init(void) { rtnl_link_af_register(&inet_ops); } static void __exit inet_exit(void) { rtnl_link_af_unregister(&inet_ops); } /** @} */ libnl-3.2.29/lib/route/link/veth.c0000644000175000017500000001540313023014600013573 00000000000000/* * lib/route/link/veth.c Virtual Ethernet * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ /** * @ingroup link * @defgroup veth VETH * Virtual Ethernet * * @details * \b Link Type Name: "veth" * * @route_doc{link_veth, VETH Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include #include static struct nla_policy veth_policy[VETH_INFO_MAX+1] = { [VETH_INFO_PEER] = { .minlen = sizeof(struct ifinfomsg) }, }; static int veth_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[VETH_INFO_MAX+1]; struct nlattr *peer_tb[IFLA_MAX + 1]; struct rtnl_link *peer = link->l_info; int err; NL_DBG(3, "Parsing veth link info\n"); if ((err = nla_parse_nested(tb, VETH_INFO_MAX, data, veth_policy)) < 0) goto errout; if (tb[VETH_INFO_PEER]) { struct nlattr *nla_peer; struct ifinfomsg *ifi; nla_peer = tb[VETH_INFO_PEER]; ifi = nla_data(nla_peer); peer->l_family = ifi->ifi_family; peer->l_arptype = ifi->ifi_type; peer->l_index = ifi->ifi_index; peer->l_flags = ifi->ifi_flags; peer->l_change = ifi->ifi_change; err = nla_parse(peer_tb, IFLA_MAX, nla_data(nla_peer) + sizeof(struct ifinfomsg), nla_len(nla_peer) - sizeof(struct ifinfomsg), rtln_link_policy); if (err < 0) goto errout; err = rtnl_link_info_parse(peer, peer_tb); if (err < 0) goto errout; } err = 0; errout: return err; } static void veth_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { } static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct rtnl_link *peer = link->l_info; char *name; name = rtnl_link_get_name(peer); nl_dump(p, " peer "); if (name) nl_dump_line(p, "%s\n", name); else nl_dump_line(p, "%u\n", peer->l_index); } static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info; /* we are calling nl_object_clone() recursively, this should * happen only once */ if (src_peer) { src_peer->l_info = NULL; dst_peer = (struct rtnl_link *)nl_object_clone(OBJ_CAST(src_peer)); if (!dst_peer) return -NLE_NOMEM; src_peer->l_info = src; dst_peer->l_info = dst; } dst->l_info = dst_peer; return 0; } static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct rtnl_link *peer = link->l_info; struct ifinfomsg ifi; struct nlattr *data, *info_peer; memset(&ifi, 0, sizeof ifi); ifi.ifi_family = peer->l_family; ifi.ifi_type = peer->l_arptype; ifi.ifi_index = peer->l_index; ifi.ifi_flags = peer->l_flags; ifi.ifi_change = peer->l_change; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; if (!(info_peer = nla_nest_start(msg, VETH_INFO_PEER))) return -NLE_MSGSIZE; if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) return -NLE_MSGSIZE; rtnl_link_fill_info(msg, peer); nla_nest_end(msg, info_peer); nla_nest_end(msg, data); return 0; } static int veth_alloc(struct rtnl_link *link) { struct rtnl_link *peer; int err; /* return early if we are in recursion */ if (link->l_info) return 0; if (!(peer = rtnl_link_alloc())) return -NLE_NOMEM; /* We don't need to hold a reference here, as link and * its peer should always be freed together. */ peer->l_info = link; if ((err = rtnl_link_set_type(peer, "veth")) < 0) { rtnl_link_put(peer); return err; } link->l_info = peer; return 0; } static void veth_free(struct rtnl_link *link) { struct rtnl_link *peer = link->l_info; if (peer) { link->l_info = NULL; /* avoid calling this recursively */ peer->l_info = NULL; rtnl_link_put(peer); } /* the caller should finally free link */ } static struct rtnl_link_info_ops veth_info_ops = { .io_name = "veth", .io_parse = veth_parse, .io_dump = { [NL_DUMP_LINE] = veth_dump_line, [NL_DUMP_DETAILS] = veth_dump_details, }, .io_alloc = veth_alloc, .io_clone = veth_clone, .io_put_attrs = veth_put_attrs, .io_free = veth_free, }; /** @cond SKIP */ #define IS_VETH_LINK_ASSERT(link) \ if ((link)->l_info_ops != &veth_info_ops) { \ APPBUG("Link is not a veth link. set type \"veth\" first."); \ return NULL; \ } /** @endcond */ /** * @name VETH Object * @{ */ /** * Allocate link object of type veth * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_veth_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "veth")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Get the peer link of a veth link * * @return the peer link object. */ struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link) { IS_VETH_LINK_ASSERT(link); nl_object_get(OBJ_CAST(link->l_info)); return link->l_info; } /** * Release a veth link and its peer * */ void rtnl_link_veth_release(struct rtnl_link *link) { veth_free(link); rtnl_link_put(link); } /** * Check if link is a veth link * @arg link Link object * * @return True if link is a veth link, otherwise false is returned. */ int rtnl_link_is_veth(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "veth"); } /** * Create a new kernel veth device * @arg sock netlink socket * @arg name name of the veth device or NULL * @arg peer_name name of its peer or NULL * @arg pid pid of the process in the new netns * * Creates a new veth device pair in the kernel and move the peer * to the network namespace where the process is. If no name is * provided, the kernel will automatically pick a name of the * form "veth%d" (e.g. veth0, veth1, etc.) * * @return 0 on success or a negative error code */ int rtnl_link_veth_add(struct nl_sock *sock, const char *name, const char *peer_name, pid_t pid) { struct rtnl_link *link, *peer; int err = -NLE_NOMEM; if (!(link = rtnl_link_veth_alloc())) return -NLE_NOMEM; peer = link->l_info; if (name && peer_name) { rtnl_link_set_name(link, name); rtnl_link_set_name(peer, peer_name); } rtnl_link_set_ns_pid(peer, pid); err = rtnl_link_add(sock, link, NLM_F_CREATE | NLM_F_EXCL); rtnl_link_put(link); return err; } /** @} */ static void __init veth_init(void) { rtnl_link_register_info(&veth_info_ops); } static void __exit veth_exit(void) { rtnl_link_unregister_info(&veth_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/inet6.c0000644000175000017500000005614613023014600013663 00000000000000/* * lib/route/link/inet6.c AF_INET6 link operations * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010 Thomas Graf */ #include #include #include #include #include #define I6_ADDR_GEN_MODE_UNKNOWN UINT8_MAX struct inet6_data { uint32_t i6_flags; struct ifla_cacheinfo i6_cacheinfo; uint32_t i6_conf[DEVCONF_MAX]; struct in6_addr i6_token; uint8_t i6_addr_gen_mode; }; static void *inet6_alloc(struct rtnl_link *link) { struct inet6_data *i6; i6 = calloc(1, sizeof(struct inet6_data)); if (i6) i6->i6_addr_gen_mode = I6_ADDR_GEN_MODE_UNKNOWN; return i6; } static void *inet6_clone(struct rtnl_link *link, void *data) { struct inet6_data *i6; if ((i6 = inet6_alloc(link))) memcpy(i6, data, sizeof(*i6)); return i6; } static void inet6_free(struct rtnl_link *link, void *data) { free(data); } static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = { [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, [IFLA_INET6_CACHEINFO] = { .minlen = sizeof(struct ifla_cacheinfo) }, [IFLA_INET6_CONF] = { .minlen = 4 }, [IFLA_INET6_STATS] = { .minlen = 8 }, [IFLA_INET6_ICMP6STATS] = { .minlen = 8 }, [IFLA_INET6_TOKEN] = { .minlen = sizeof(struct in6_addr) }, [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 }, }; static const uint8_t map_stat_id_from_IPSTATS_MIB_v1[__IPSTATS_MIB_MAX] = { /* 14a196807482e6fc74f15fc03176d5c08880588f^:include/linux/snmp.h * version before the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f. * This version was valid since commit edf391ff17232f097d72441c9ad467bcb3b5db18, which * predates support for parsing IFLA_PROTINFO in libnl3. Such an even older meaning of * the flags is not supported in libnl3. */ [ 1] = RTNL_LINK_IP6_INPKTS, /* IPSTATS_MIB_INPKTS */ [ 2] = RTNL_LINK_IP6_INHDRERRORS, /* IPSTATS_MIB_INHDRERRORS */ [ 3] = RTNL_LINK_IP6_INTOOBIGERRORS, /* IPSTATS_MIB_INTOOBIGERRORS */ [ 4] = RTNL_LINK_IP6_INNOROUTES, /* IPSTATS_MIB_INNOROUTES */ [ 5] = RTNL_LINK_IP6_INADDRERRORS, /* IPSTATS_MIB_INADDRERRORS */ [ 6] = RTNL_LINK_IP6_INUNKNOWNPROTOS, /* IPSTATS_MIB_INUNKNOWNPROTOS */ [ 7] = RTNL_LINK_IP6_INTRUNCATEDPKTS, /* IPSTATS_MIB_INTRUNCATEDPKTS */ [ 8] = RTNL_LINK_IP6_INDISCARDS, /* IPSTATS_MIB_INDISCARDS */ [ 9] = RTNL_LINK_IP6_INDELIVERS, /* IPSTATS_MIB_INDELIVERS */ [10] = RTNL_LINK_IP6_OUTFORWDATAGRAMS, /* IPSTATS_MIB_OUTFORWDATAGRAMS */ [11] = RTNL_LINK_IP6_OUTPKTS, /* IPSTATS_MIB_OUTPKTS */ [12] = RTNL_LINK_IP6_OUTDISCARDS, /* IPSTATS_MIB_OUTDISCARDS */ [13] = RTNL_LINK_IP6_OUTNOROUTES, /* IPSTATS_MIB_OUTNOROUTES */ [14] = RTNL_LINK_IP6_REASMTIMEOUT, /* IPSTATS_MIB_REASMTIMEOUT */ [15] = RTNL_LINK_IP6_REASMREQDS, /* IPSTATS_MIB_REASMREQDS */ [16] = RTNL_LINK_IP6_REASMOKS, /* IPSTATS_MIB_REASMOKS */ [17] = RTNL_LINK_IP6_REASMFAILS, /* IPSTATS_MIB_REASMFAILS */ [18] = RTNL_LINK_IP6_FRAGOKS, /* IPSTATS_MIB_FRAGOKS */ [19] = RTNL_LINK_IP6_FRAGFAILS, /* IPSTATS_MIB_FRAGFAILS */ [20] = RTNL_LINK_IP6_FRAGCREATES, /* IPSTATS_MIB_FRAGCREATES */ [21] = RTNL_LINK_IP6_INMCASTPKTS, /* IPSTATS_MIB_INMCASTPKTS */ [22] = RTNL_LINK_IP6_OUTMCASTPKTS, /* IPSTATS_MIB_OUTMCASTPKTS */ [23] = RTNL_LINK_IP6_INBCASTPKTS, /* IPSTATS_MIB_INBCASTPKTS */ [24] = RTNL_LINK_IP6_OUTBCASTPKTS, /* IPSTATS_MIB_OUTBCASTPKTS */ [25] = RTNL_LINK_IP6_INOCTETS, /* IPSTATS_MIB_INOCTETS */ [26] = RTNL_LINK_IP6_OUTOCTETS, /* IPSTATS_MIB_OUTOCTETS */ [27] = RTNL_LINK_IP6_INMCASTOCTETS, /* IPSTATS_MIB_INMCASTOCTETS */ [28] = RTNL_LINK_IP6_OUTMCASTOCTETS, /* IPSTATS_MIB_OUTMCASTOCTETS */ [29] = RTNL_LINK_IP6_INBCASTOCTETS, /* IPSTATS_MIB_INBCASTOCTETS */ [30] = RTNL_LINK_IP6_OUTBCASTOCTETS, /* IPSTATS_MIB_OUTBCASTOCTETS */ }; static const uint8_t map_stat_id_from_IPSTATS_MIB_v2[__IPSTATS_MIB_MAX] = { /* d8ec26d7f8287f5788a494f56e8814210f0e64be:include/uapi/linux/snmp.h * version since the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f */ [ 1] = RTNL_LINK_IP6_INPKTS, /* IPSTATS_MIB_INPKTS */ [ 2] = RTNL_LINK_IP6_INOCTETS, /* IPSTATS_MIB_INOCTETS */ [ 3] = RTNL_LINK_IP6_INDELIVERS, /* IPSTATS_MIB_INDELIVERS */ [ 4] = RTNL_LINK_IP6_OUTFORWDATAGRAMS, /* IPSTATS_MIB_OUTFORWDATAGRAMS */ [ 5] = RTNL_LINK_IP6_OUTPKTS, /* IPSTATS_MIB_OUTPKTS */ [ 6] = RTNL_LINK_IP6_OUTOCTETS, /* IPSTATS_MIB_OUTOCTETS */ [ 7] = RTNL_LINK_IP6_INHDRERRORS, /* IPSTATS_MIB_INHDRERRORS */ [ 8] = RTNL_LINK_IP6_INTOOBIGERRORS, /* IPSTATS_MIB_INTOOBIGERRORS */ [ 9] = RTNL_LINK_IP6_INNOROUTES, /* IPSTATS_MIB_INNOROUTES */ [10] = RTNL_LINK_IP6_INADDRERRORS, /* IPSTATS_MIB_INADDRERRORS */ [11] = RTNL_LINK_IP6_INUNKNOWNPROTOS, /* IPSTATS_MIB_INUNKNOWNPROTOS */ [12] = RTNL_LINK_IP6_INTRUNCATEDPKTS, /* IPSTATS_MIB_INTRUNCATEDPKTS */ [13] = RTNL_LINK_IP6_INDISCARDS, /* IPSTATS_MIB_INDISCARDS */ [14] = RTNL_LINK_IP6_OUTDISCARDS, /* IPSTATS_MIB_OUTDISCARDS */ [15] = RTNL_LINK_IP6_OUTNOROUTES, /* IPSTATS_MIB_OUTNOROUTES */ [16] = RTNL_LINK_IP6_REASMTIMEOUT, /* IPSTATS_MIB_REASMTIMEOUT */ [17] = RTNL_LINK_IP6_REASMREQDS, /* IPSTATS_MIB_REASMREQDS */ [18] = RTNL_LINK_IP6_REASMOKS, /* IPSTATS_MIB_REASMOKS */ [19] = RTNL_LINK_IP6_REASMFAILS, /* IPSTATS_MIB_REASMFAILS */ [20] = RTNL_LINK_IP6_FRAGOKS, /* IPSTATS_MIB_FRAGOKS */ [21] = RTNL_LINK_IP6_FRAGFAILS, /* IPSTATS_MIB_FRAGFAILS */ [22] = RTNL_LINK_IP6_FRAGCREATES, /* IPSTATS_MIB_FRAGCREATES */ [23] = RTNL_LINK_IP6_INMCASTPKTS, /* IPSTATS_MIB_INMCASTPKTS */ [24] = RTNL_LINK_IP6_OUTMCASTPKTS, /* IPSTATS_MIB_OUTMCASTPKTS */ [25] = RTNL_LINK_IP6_INBCASTPKTS, /* IPSTATS_MIB_INBCASTPKTS */ [26] = RTNL_LINK_IP6_OUTBCASTPKTS, /* IPSTATS_MIB_OUTBCASTPKTS */ [27] = RTNL_LINK_IP6_INMCASTOCTETS, /* IPSTATS_MIB_INMCASTOCTETS */ [28] = RTNL_LINK_IP6_OUTMCASTOCTETS, /* IPSTATS_MIB_OUTMCASTOCTETS */ [29] = RTNL_LINK_IP6_INBCASTOCTETS, /* IPSTATS_MIB_INBCASTOCTETS */ [30] = RTNL_LINK_IP6_OUTBCASTOCTETS, /* IPSTATS_MIB_OUTBCASTOCTETS */ [31] = RTNL_LINK_IP6_CSUMERRORS, /* IPSTATS_MIB_CSUMERRORS */ [32] = RTNL_LINK_IP6_NOECTPKTS, /* IPSTATS_MIB_NOECTPKTS */ [33] = RTNL_LINK_IP6_ECT1PKTS, /* IPSTATS_MIB_ECT1PKTS */ [34] = RTNL_LINK_IP6_ECT0PKTS, /* IPSTATS_MIB_ECT0PKTS */ [35] = RTNL_LINK_IP6_CEPKTS, /* IPSTATS_MIB_CEPKTS */ }; static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, void *data) { struct inet6_data *i6 = data; struct nlattr *tb[IFLA_INET6_MAX+1]; int err; err = nla_parse_nested(tb, IFLA_INET6_MAX, attr, inet6_policy); if (err < 0) return err; if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4) return -EINVAL; if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8) return -EINVAL; if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8) return -EINVAL; if (tb[IFLA_INET6_FLAGS]) i6->i6_flags = nla_get_u32(tb[IFLA_INET6_FLAGS]); if (tb[IFLA_INET6_CACHEINFO]) nla_memcpy(&i6->i6_cacheinfo, tb[IFLA_INET6_CACHEINFO], sizeof(i6->i6_cacheinfo)); if (tb[IFLA_INET6_CONF]) nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF], sizeof(i6->i6_conf)); if (tb[IFLA_INET6_TOKEN]) nla_memcpy(&i6->i6_token, tb[IFLA_INET6_TOKEN], sizeof(struct in6_addr)); if (tb[IFLA_INET6_ADDR_GEN_MODE]) i6->i6_addr_gen_mode = nla_get_u8 (tb[IFLA_INET6_ADDR_GEN_MODE]); /* * Due to 32bit data alignment, these addresses must be copied to an * aligned location prior to access. */ if (tb[IFLA_INET6_STATS]) { unsigned char *cnt = nla_data(tb[IFLA_INET6_STATS]); uint64_t stat; int i; int len = nla_len(tb[IFLA_INET6_STATS]) / 8; const uint8_t *map_stat_id = map_stat_id_from_IPSTATS_MIB_v2; if (len < 32 || (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) < 6)) { /* kernel commit 14a196807482e6fc74f15fc03176d5c08880588f reordered the values. * The later commit 6a5dc9e598fe90160fee7de098fa319665f5253e added values * IPSTATS_MIB_CSUMERRORS/ICMP6_MIB_CSUMERRORS. If the netlink is shorter * then this, assume that the kernel uses the previous meaning of the * enumeration. */ map_stat_id = map_stat_id_from_IPSTATS_MIB_v1; } len = min_t(int, __IPSTATS_MIB_MAX, len); for (i = 1; i < len; i++) { memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat)); rtnl_link_set_stat(link, map_stat_id[i], stat); } } if (tb[IFLA_INET6_ICMP6STATS]) { unsigned char *cnt = nla_data(tb[IFLA_INET6_ICMP6STATS]); uint64_t stat; int i; int len = min_t(int, __ICMP6_MIB_MAX, nla_len(tb[IFLA_INET6_ICMP6STATS]) / 8); for (i = 1; i < len; i++) { memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat)); rtnl_link_set_stat(link, RTNL_LINK_ICMP6_INMSGS + i - 1, stat); } } return 0; } static int inet6_fill_af(struct rtnl_link *link, struct nl_msg *msg, void *data) { struct inet6_data *id = data; if (id->i6_addr_gen_mode != I6_ADDR_GEN_MODE_UNKNOWN) NLA_PUT_U8(msg, IFLA_INET6_ADDR_GEN_MODE, id->i6_addr_gen_mode); return 0; nla_put_failure: return -NLE_MSGSIZE; } /* These live in include/net/if_inet6.h and should be moved to include/linux */ #define IF_RA_OTHERCONF 0x80 #define IF_RA_MANAGED 0x40 #define IF_RA_RCVD 0x20 #define IF_RS_SENT 0x10 #define IF_READY 0x80000000 static const struct trans_tbl inet6_flags[] = { __ADD(IF_RA_OTHERCONF, ra_otherconf), __ADD(IF_RA_MANAGED, ra_managed), __ADD(IF_RA_RCVD, ra_rcvd), __ADD(IF_RS_SENT, rs_sent), __ADD(IF_READY, ready), }; static char *inet6_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, inet6_flags, ARRAY_SIZE(inet6_flags)); } static const struct trans_tbl inet6_devconf[] = { __ADD(DEVCONF_FORWARDING, forwarding), __ADD(DEVCONF_HOPLIMIT, hoplimit), __ADD(DEVCONF_MTU6, mtu6), __ADD(DEVCONF_ACCEPT_RA, accept_ra), __ADD(DEVCONF_ACCEPT_REDIRECTS, accept_redirects), __ADD(DEVCONF_AUTOCONF, autoconf), __ADD(DEVCONF_DAD_TRANSMITS, dad_transmits), __ADD(DEVCONF_RTR_SOLICITS, rtr_solicits), __ADD(DEVCONF_RTR_SOLICIT_INTERVAL, rtr_solicit_interval), __ADD(DEVCONF_RTR_SOLICIT_DELAY, rtr_solicit_delay), __ADD(DEVCONF_USE_TEMPADDR, use_tempaddr), __ADD(DEVCONF_TEMP_VALID_LFT, temp_valid_lft), __ADD(DEVCONF_TEMP_PREFERED_LFT, temp_prefered_lft), __ADD(DEVCONF_REGEN_MAX_RETRY, regen_max_retry), __ADD(DEVCONF_MAX_DESYNC_FACTOR, max_desync_factor), __ADD(DEVCONF_MAX_ADDRESSES, max_addresses), __ADD(DEVCONF_FORCE_MLD_VERSION, force_mld_version), __ADD(DEVCONF_ACCEPT_RA_DEFRTR, accept_ra_defrtr), __ADD(DEVCONF_ACCEPT_RA_PINFO, accept_ra_pinfo), __ADD(DEVCONF_ACCEPT_RA_RTR_PREF, accept_ra_rtr_pref), __ADD(DEVCONF_RTR_PROBE_INTERVAL, rtr_probe_interval), __ADD(DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, accept_ra_rt_info), __ADD(DEVCONF_PROXY_NDP, proxy_ndp), __ADD(DEVCONF_OPTIMISTIC_DAD, optimistic_dad), __ADD(DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route), __ADD(DEVCONF_MC_FORWARDING, mc_forwarding), __ADD(DEVCONF_DISABLE_IPV6, disable_ipv6), __ADD(DEVCONF_ACCEPT_DAD, accept_dad), __ADD(DEVCONF_FORCE_TLLAO, force_tllao), }; static char *inet6_devconf2str(int type, char *buf, size_t len) { return __type2str(type, buf, len, inet6_devconf, ARRAY_SIZE(inet6_devconf)); } static const struct trans_tbl inet6_addr_gen_mode[] = { __ADD(IN6_ADDR_GEN_MODE_EUI64, eui64), __ADD(IN6_ADDR_GEN_MODE_NONE, none), __ADD(IN6_ADDR_GEN_MODE_STABLE_PRIVACY, stable_privacy), }; const char *rtnl_link_inet6_addrgenmode2str(uint8_t mode, char *buf, size_t len) { return __type2str(mode, buf, len, inet6_addr_gen_mode, ARRAY_SIZE(inet6_addr_gen_mode)); } uint8_t rtnl_link_inet6_str2addrgenmode(const char *mode) { return (uint8_t) __str2type(mode, inet6_addr_gen_mode, ARRAY_SIZE(inet6_addr_gen_mode)); } static void inet6_dump_details(struct rtnl_link *link, struct nl_dump_params *p, void *data) { struct inet6_data *i6 = data; struct nl_addr *addr; char buf[64], buf2[64]; int i, n = 0; nl_dump_line(p, " ipv6 max-reasm-len %s", nl_size2str(i6->i6_cacheinfo.max_reasm_len, buf, sizeof(buf))); nl_dump(p, " <%s>\n", inet6_flags2str(i6->i6_flags, buf, sizeof(buf))); nl_dump_line(p, " create-stamp %.2fs reachable-time %s", (double) i6->i6_cacheinfo.tstamp / 100., nl_msec2str(i6->i6_cacheinfo.reachable_time, buf, sizeof(buf))); nl_dump(p, " retrans-time %s\n", nl_msec2str(i6->i6_cacheinfo.retrans_time, buf, sizeof(buf))); addr = nl_addr_build(AF_INET6, &i6->i6_token, sizeof(i6->i6_token)); nl_dump(p, " token %s\n", nl_addr2str(addr, buf, sizeof(buf))); nl_addr_put(addr); nl_dump(p, " link-local address mode %s\n", rtnl_link_inet6_addrgenmode2str(i6->i6_addr_gen_mode, buf, sizeof(buf))); nl_dump_line(p, " devconf:\n"); nl_dump_line(p, " "); for (i = 0; i < DEVCONF_MAX; i++) { uint32_t value = i6->i6_conf[i]; int x, offset; switch (i) { case DEVCONF_TEMP_VALID_LFT: case DEVCONF_TEMP_PREFERED_LFT: nl_msec2str((uint64_t) value * 1000., buf2, sizeof(buf2)); break; case DEVCONF_RTR_PROBE_INTERVAL: case DEVCONF_RTR_SOLICIT_INTERVAL: case DEVCONF_RTR_SOLICIT_DELAY: nl_msec2str(value, buf2, sizeof(buf2)); break; default: snprintf(buf2, sizeof(buf2), "%u", value); break; } inet6_devconf2str(i, buf, sizeof(buf)); offset = 23 - strlen(buf2); if (offset < 0) offset = 0; for (x = strlen(buf); x < offset; x++) buf[x] = ' '; strncpy(&buf[offset], buf2, strlen(buf2)); nl_dump_line(p, "%s", buf); if (++n == 3) { nl_dump(p, "\n"); nl_dump_line(p, " "); n = 0; } else nl_dump(p, " "); } if (n != 0) nl_dump(p, "\n"); } static void inet6_dump_stats(struct rtnl_link *link, struct nl_dump_params *p, void *data) { double octets; char *octetsUnit; nl_dump(p, " IPv6: InPkts InOctets " " InDiscards InDelivers\n"); nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_INPKTS]); octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INOCTETS], &octetsUnit); if (octets) nl_dump(p, "%14.2f %3s ", octets, octetsUnit); else nl_dump(p, "%16" PRIu64 " B ", 0); nl_dump(p, "%18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_IP6_INDISCARDS], link->l_stats[RTNL_LINK_IP6_INDELIVERS]); nl_dump(p, " OutPkts OutOctets " " OutDiscards OutForwards\n"); nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_OUTPKTS]); octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTOCTETS], &octetsUnit); if (octets) nl_dump(p, "%14.2f %3s ", octets, octetsUnit); else nl_dump(p, "%16" PRIu64 " B ", 0); nl_dump(p, "%18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_IP6_OUTDISCARDS], link->l_stats[RTNL_LINK_IP6_OUTFORWDATAGRAMS]); nl_dump(p, " InMcastPkts InMcastOctets " " InBcastPkts InBcastOctests\n"); nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_INMCASTPKTS]); octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INMCASTOCTETS], &octetsUnit); if (octets) nl_dump(p, "%14.2f %3s ", octets, octetsUnit); else nl_dump(p, "%16" PRIu64 " B ", 0); nl_dump(p, "%18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_INBCASTPKTS]); octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INBCASTOCTETS], &octetsUnit); if (octets) nl_dump(p, "%14.2f %3s\n", octets, octetsUnit); else nl_dump(p, "%16" PRIu64 " B\n", 0); nl_dump(p, " OutMcastPkts OutMcastOctets " " OutBcastPkts OutBcastOctests\n"); nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_OUTMCASTPKTS]); octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTMCASTOCTETS], &octetsUnit); if (octets) nl_dump(p, "%14.2f %3s ", octets, octetsUnit); else nl_dump(p, "%16" PRIu64 " B ", 0); nl_dump(p, "%18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_OUTBCASTPKTS]); octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTBCASTOCTETS], &octetsUnit); if (octets) nl_dump(p, "%14.2f %3s\n", octets, octetsUnit); else nl_dump(p, "%16" PRIu64 " B\n", 0); nl_dump(p, " ReasmOKs ReasmFails " " ReasmReqds ReasmTimeout\n"); nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_IP6_REASMOKS], link->l_stats[RTNL_LINK_IP6_REASMFAILS], link->l_stats[RTNL_LINK_IP6_REASMREQDS], link->l_stats[RTNL_LINK_IP6_REASMTIMEOUT]); nl_dump(p, " FragOKs FragFails " " FragCreates\n"); nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_IP6_FRAGOKS], link->l_stats[RTNL_LINK_IP6_FRAGFAILS], link->l_stats[RTNL_LINK_IP6_FRAGCREATES]); nl_dump(p, " InHdrErrors InTooBigErrors " " InNoRoutes InAddrErrors\n"); nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_IP6_INHDRERRORS], link->l_stats[RTNL_LINK_IP6_INTOOBIGERRORS], link->l_stats[RTNL_LINK_IP6_INNOROUTES], link->l_stats[RTNL_LINK_IP6_INADDRERRORS]); nl_dump(p, " InUnknownProtos InTruncatedPkts " " OutNoRoutes InCsumErrors\n"); nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_IP6_INUNKNOWNPROTOS], link->l_stats[RTNL_LINK_IP6_INTRUNCATEDPKTS], link->l_stats[RTNL_LINK_IP6_OUTNOROUTES], link->l_stats[RTNL_LINK_IP6_CSUMERRORS]); nl_dump(p, " InNoECTPkts InECT1Pkts " " InECT0Pkts InCEPkts\n"); nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_IP6_NOECTPKTS], link->l_stats[RTNL_LINK_IP6_ECT1PKTS], link->l_stats[RTNL_LINK_IP6_ECT0PKTS], link->l_stats[RTNL_LINK_IP6_CEPKTS]); nl_dump(p, " ICMPv6: InMsgs InErrors " " OutMsgs OutErrors InCsumErrors\n"); nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", link->l_stats[RTNL_LINK_ICMP6_INMSGS], link->l_stats[RTNL_LINK_ICMP6_INERRORS], link->l_stats[RTNL_LINK_ICMP6_OUTMSGS], link->l_stats[RTNL_LINK_ICMP6_OUTERRORS], link->l_stats[RTNL_LINK_ICMP6_CSUMERRORS]); } static const struct nla_policy protinfo_policy = { .type = NLA_NESTED, }; static struct rtnl_link_af_ops inet6_ops = { .ao_family = AF_INET6, .ao_alloc = &inet6_alloc, .ao_clone = &inet6_clone, .ao_free = &inet6_free, .ao_parse_protinfo = &inet6_parse_protinfo, .ao_parse_af = &inet6_parse_protinfo, .ao_fill_af = &inet6_fill_af, .ao_dump[NL_DUMP_DETAILS] = &inet6_dump_details, .ao_dump[NL_DUMP_STATS] = &inet6_dump_stats, .ao_protinfo_policy = &protinfo_policy, }; /** * Get IPv6 tokenized interface identifier * @arg link Link object * @arg token Tokenized interface identifier on success * * Returns the link's IPv6 tokenized interface identifier. * * @return 0 on success * @return -NLE_NOMEM failure to allocate struct nl_addr result * @return -NLE_NOATTR configuration setting not available * @return -NLE_NOADDR tokenized interface identifier is not set */ int rtnl_link_inet6_get_token(struct rtnl_link *link, struct nl_addr **addr) { struct inet6_data *id; if (!(id = rtnl_link_af_data(link, &inet6_ops))) return -NLE_NOATTR; *addr = nl_addr_build(AF_INET6, &id->i6_token, sizeof(id->i6_token)); if (!*addr) return -NLE_NOMEM; if (nl_addr_iszero(*addr)) { nl_addr_put(*addr); *addr = NULL; return -NLE_NOADDR; } return 0; } /** * Set IPv6 tokenized interface identifier * @arg link Link object * @arg token Tokenized interface identifier * * Sets the link's IPv6 tokenized interface identifier. * * @return 0 on success * @return -NLE_NOMEM could not allocate inet6 data * @return -NLE_INVAL addr is not a valid inet6 address */ int rtnl_link_inet6_set_token(struct rtnl_link *link, struct nl_addr *addr) { struct inet6_data *id; if ((nl_addr_get_family(addr) != AF_INET6) || (nl_addr_get_len(addr) != sizeof(id->i6_token))) return -NLE_INVAL; if (!(id = rtnl_link_af_alloc(link, &inet6_ops))) return -NLE_NOMEM; memcpy(&id->i6_token, nl_addr_get_binary_addr(addr), sizeof(id->i6_token)); return 0; } /** * Get IPv6 link-local address generation mode * @arg link Link object * @arg mode Generation mode on success * * Returns the link's IPv6 link-local address generation mode. * * @return 0 on success * @return -NLE_NOATTR configuration setting not available * @return -NLE_INVAL generation mode unknown. If the link was received via * netlink, it means that address generation mode is not * supported by the kernel. */ int rtnl_link_inet6_get_addr_gen_mode(struct rtnl_link *link, uint8_t *mode) { struct inet6_data *id; if (!(id = rtnl_link_af_data(link, &inet6_ops))) return -NLE_NOATTR; if (id->i6_addr_gen_mode == I6_ADDR_GEN_MODE_UNKNOWN) return -NLE_INVAL; *mode = id->i6_addr_gen_mode; return 0; } /** * Set IPv6 link-local address generation mode * @arg link Link object * @arg mode Generation mode * * Sets the link's IPv6 link-local address generation mode. * * @return 0 on success * @return -NLE_NOMEM could not allocate inet6 data */ int rtnl_link_inet6_set_addr_gen_mode(struct rtnl_link *link, uint8_t mode) { struct inet6_data *id; if (!(id = rtnl_link_af_alloc(link, &inet6_ops))) return -NLE_NOMEM; id->i6_addr_gen_mode = mode; return 0; } static void __init inet6_init(void) { rtnl_link_af_register(&inet6_ops); } static void __exit inet6_exit(void) { rtnl_link_af_unregister(&inet6_ops); } libnl-3.2.29/lib/route/link/macsec.c0000644000175000017500000004560313024722721014100 00000000000000/* * lib/route/link/macsec.c MACsec Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Sabrina Dubroca */ /** * @ingroup link * @defgroup macsec MACsec * MACsec link module * * @details * \b Link Type Name: "macsec" * * @route_doc{link_macsec, MACsec Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define MACSEC_ATTR_SCI (1 << 0) #define MACSEC_ATTR_ICV_LEN (1 << 1) #define MACSEC_ATTR_CIPHER_SUITE (1 << 2) #define MACSEC_ATTR_WINDOW (1 << 3) #define MACSEC_ATTR_ENCODING_SA (1 << 4) #define MACSEC_ATTR_ENCRYPT (1 << 5) #define MACSEC_ATTR_PROTECT (1 << 6) #define MACSEC_ATTR_INC_SCI (1 << 7) #define MACSEC_ATTR_ES (1 << 8) #define MACSEC_ATTR_SCB (1 << 9) #define MACSEC_ATTR_REPLAY_PROTECT (1 << 10) #define MACSEC_ATTR_VALIDATION (1 << 11) #define MACSEC_ATTR_PORT (1 << 12) struct macsec_info { int ifindex; uint64_t sci; uint16_t port; uint64_t cipher_suite; uint16_t icv_len; uint32_t window; enum macsec_validation_type validate; uint8_t encoding_sa; uint8_t send_sci, end_station, scb, replay_protect, protect, encrypt; uint32_t ce_mask; }; #define DEFAULT_ICV_LEN 16 /** @endcond */ static struct nla_policy macsec_policy[IFLA_MACSEC_MAX+1] = { [IFLA_MACSEC_SCI] = { .type = NLA_U64 }, [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 }, [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 }, [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 }, [IFLA_MACSEC_ENCODING_SA] = { .type = NLA_U8 }, [IFLA_MACSEC_ENCRYPT] = { .type = NLA_U8 }, [IFLA_MACSEC_PROTECT] = { .type = NLA_U8 }, [IFLA_MACSEC_INC_SCI] = { .type = NLA_U8 }, [IFLA_MACSEC_ES] = { .type = NLA_U8 }, [IFLA_MACSEC_SCB] = { .type = NLA_U8 }, [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 }, [IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 }, }; /** * @name MACsec Object * @{ */ /** * Allocate link object of type MACsec * * @return Allocated link object or NULL. */ static int macsec_alloc(struct rtnl_link *link) { struct macsec_info *info; if (!link->l_info) { link->l_info = malloc(sizeof(struct macsec_info)); if (!link->l_info) return -NLE_NOMEM; } memset(link->l_info, 0, sizeof(struct macsec_info)); info = link->l_info; info->cipher_suite = MACSEC_DEFAULT_CIPHER_ID; info->icv_len = DEFAULT_ICV_LEN; info->ce_mask = MACSEC_ATTR_CIPHER_SUITE | MACSEC_ATTR_ICV_LEN; return 0; } static int macsec_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_MACSEC_MAX+1]; struct macsec_info *info; int err; NL_DBG(3, "Parsing MACsec link info\n"); if ((err = nla_parse_nested(tb, IFLA_MACSEC_MAX, data, macsec_policy)) < 0) goto errout; if ((err = macsec_alloc(link)) < 0) goto errout; info = link->l_info; if (tb[IFLA_MACSEC_SCI]) { info->sci = nla_get_u64(tb[IFLA_MACSEC_SCI]); info->ce_mask |= MACSEC_ATTR_SCI; } if (tb[IFLA_MACSEC_PROTECT]) { info->protect = nla_get_u8(tb[IFLA_MACSEC_PROTECT]); info->ce_mask |= MACSEC_ATTR_PROTECT; } if (tb[IFLA_MACSEC_CIPHER_SUITE]) { info->cipher_suite = nla_get_u64(tb[IFLA_MACSEC_CIPHER_SUITE]); info->ce_mask |= MACSEC_ATTR_CIPHER_SUITE; } if (tb[IFLA_MACSEC_ICV_LEN]) { info->icv_len = nla_get_u8(tb[IFLA_MACSEC_ICV_LEN]); info->ce_mask |= MACSEC_ATTR_ICV_LEN; } if (tb[IFLA_MACSEC_ENCODING_SA]) { info->encoding_sa = nla_get_u8(tb[IFLA_MACSEC_ENCODING_SA]); info->ce_mask |= MACSEC_ATTR_ENCODING_SA; } if (tb[IFLA_MACSEC_VALIDATION]) { info->validate = nla_get_u8(tb[IFLA_MACSEC_VALIDATION]); info->ce_mask |= MACSEC_ATTR_VALIDATION; } if (tb[IFLA_MACSEC_ENCRYPT]) { info->encrypt = nla_get_u8(tb[IFLA_MACSEC_ENCRYPT]); info->ce_mask |= MACSEC_ATTR_ENCRYPT; } if (tb[IFLA_MACSEC_INC_SCI]) { info->send_sci = nla_get_u8(tb[IFLA_MACSEC_INC_SCI]); info->ce_mask |= MACSEC_ATTR_INC_SCI; } if (tb[IFLA_MACSEC_ES]) { info->end_station = nla_get_u8(tb[IFLA_MACSEC_ES]); info->ce_mask |= MACSEC_ATTR_ES; } if (tb[IFLA_MACSEC_SCB]) { info->scb = nla_get_u8(tb[IFLA_MACSEC_SCB]); info->ce_mask |= MACSEC_ATTR_SCB; } if (tb[IFLA_MACSEC_REPLAY_PROTECT]) { info->replay_protect = nla_get_u8(tb[IFLA_MACSEC_REPLAY_PROTECT]); info->ce_mask |= MACSEC_ATTR_REPLAY_PROTECT; } if (tb[IFLA_MACSEC_WINDOW]) { info->window = nla_get_u32(tb[IFLA_MACSEC_WINDOW]); info->ce_mask |= MACSEC_ATTR_WINDOW; } err = 0; errout: return err; } static void macsec_free(struct rtnl_link *link) { free(link->l_info); link->l_info = NULL; } static const char *values_on_off[] = { "off", "on" }; static const char *VALIDATE_STR[] = { [MACSEC_VALIDATE_DISABLED] = "disabled", [MACSEC_VALIDATE_CHECK] = "check", [MACSEC_VALIDATE_STRICT] = "strict", }; static char *replay_protect_str(char *buf, uint8_t replay_protect, uint8_t window) { if (replay_protect == 1) { sprintf(buf, "replay_protect on window %d", window); } else if (replay_protect == 0) { sprintf(buf, "replay_protect off"); } else { buf[0] = '\0'; } return buf; } /** @cond SKIP */ #define PRINT_FLAG(buf, i, field, c) ({ if (i->field == 1) *buf++ = c; }) /** @endcond */ static char *flags_str(char *buf, unsigned char len, struct macsec_info *info) { char *tmp = buf; memset(tmp, 0, len); PRINT_FLAG(tmp, info, protect, 'P'); PRINT_FLAG(tmp, info, encrypt, 'E'); PRINT_FLAG(tmp, info, send_sci, 'S'); PRINT_FLAG(tmp, info, end_station, 'e'); PRINT_FLAG(tmp, info, scb, 's'); PRINT_FLAG(tmp, info, replay_protect, 'R'); *tmp++ = ' '; *tmp++ = 'v'; switch (info->validate) { case MACSEC_VALIDATE_DISABLED: *tmp++ = 'd'; break; case MACSEC_VALIDATE_CHECK: *tmp++ = 'c'; break; case MACSEC_VALIDATE_STRICT: *tmp++ = 's'; break; default: break; } sprintf(tmp, " %d", info->encoding_sa); return buf; } static void macsec_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { struct macsec_info *info = link->l_info; char tmp[128]; nl_dump(p, "sci %016llx <%s>", ntohll(info->sci), flags_str(tmp, sizeof(tmp), info)); } static void macsec_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct macsec_info *info = link->l_info; char tmp[128]; nl_dump(p, " sci %016llx protect %s encoding_sa %d encrypt %s send_sci %s validate %s %s\n", ntohll(info->sci), values_on_off[info->protect], info->encoding_sa, values_on_off[info->encrypt], values_on_off[info->send_sci], VALIDATE_STR[info->validate], replay_protect_str(tmp, info->replay_protect, info->window)); nl_dump(p, " cipher suite: %016llx, icv_len %d\n", info->cipher_suite, info->icv_len); } static int macsec_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct macsec_info *copy, *info = src->l_info; int err; dst->l_info = NULL; if ((err = rtnl_link_set_type(dst, "macsec")) < 0) return err; copy = dst->l_info; if (!info || !copy) return -NLE_NOMEM; memcpy(copy, info, sizeof(struct macsec_info)); return 0; } static int macsec_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct macsec_info *info = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; if (info->ce_mask & MACSEC_ATTR_SCI) NLA_PUT_U64(msg, IFLA_MACSEC_SCI, info->sci); else if (info->ce_mask & MACSEC_ATTR_PORT) NLA_PUT_U16(msg, IFLA_MACSEC_PORT, htons(info->port)); if ((info->ce_mask & MACSEC_ATTR_ENCRYPT)) NLA_PUT_U8(msg, IFLA_MACSEC_ENCRYPT, info->encrypt); if (info->cipher_suite != MACSEC_DEFAULT_CIPHER_ID || info->icv_len != DEFAULT_ICV_LEN) { NLA_PUT_U64(msg, IFLA_MACSEC_CIPHER_SUITE, info->cipher_suite); NLA_PUT_U8(msg, IFLA_MACSEC_ICV_LEN, info->icv_len); } if ((info->ce_mask & MACSEC_ATTR_INC_SCI)) NLA_PUT_U8(msg, IFLA_MACSEC_INC_SCI, info->send_sci); if ((info->ce_mask & MACSEC_ATTR_ES)) NLA_PUT_U8(msg, IFLA_MACSEC_ES, info->end_station); if ((info->ce_mask & MACSEC_ATTR_SCB)) NLA_PUT_U8(msg, IFLA_MACSEC_SCB, info->scb); if ((info->ce_mask & MACSEC_ATTR_PROTECT)) NLA_PUT_U8(msg, IFLA_MACSEC_PROTECT, info->protect); if ((info->ce_mask & MACSEC_ATTR_REPLAY_PROTECT)) { if (info->replay_protect && !(info->ce_mask & MACSEC_ATTR_WINDOW)) return -NLE_INVAL; NLA_PUT_U8(msg, IFLA_MACSEC_REPLAY_PROTECT, info->replay_protect); NLA_PUT_U32(msg, IFLA_MACSEC_WINDOW, info->window); } if ((info->ce_mask & MACSEC_ATTR_VALIDATION)) NLA_PUT_U8(msg, IFLA_MACSEC_VALIDATION, info->validate); if ((info->ce_mask & MACSEC_ATTR_ENCODING_SA)) NLA_PUT_U8(msg, IFLA_MACSEC_ENCODING_SA, info->encoding_sa); nla_nest_end(msg, data); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int macsec_compare(struct rtnl_link *link_a, struct rtnl_link *link_b, int flags) { struct macsec_info *a = link_a->l_info; struct macsec_info *b = link_b->l_info; int diff = 0; uint32_t attrs = flags & LOOSE_COMPARISON ? b->ce_mask : ~0; #define MACSEC_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MACSEC_ATTR_##ATTR, a, b, EXPR) if (a->ce_mask & MACSEC_ATTR_SCI && b->ce_mask & MACSEC_ATTR_SCI) diff |= MACSEC_DIFF(SCI, a->sci != b->sci); else if (a->ce_mask & MACSEC_ATTR_PORT && b->ce_mask & MACSEC_ATTR_PORT) diff |= MACSEC_DIFF(PORT, a->port != b->port); if (a->ce_mask & MACSEC_ATTR_CIPHER_SUITE && b->ce_mask & MACSEC_ATTR_CIPHER_SUITE) { diff |= MACSEC_DIFF(ICV_LEN, a->icv_len != b->icv_len); diff |= MACSEC_DIFF(CIPHER_SUITE, a->cipher_suite != b->cipher_suite); } if (a->ce_mask & MACSEC_ATTR_REPLAY_PROTECT && b->ce_mask & MACSEC_ATTR_REPLAY_PROTECT) { int d = MACSEC_DIFF(REPLAY_PROTECT, a->replay_protect != b->replay_protect); if (a->replay_protect && b->replay_protect) d |= MACSEC_DIFF(WINDOW, a->window != b->window); diff |= d; } diff |= MACSEC_DIFF(ENCODING_SA, a->encoding_sa != b->encoding_sa); diff |= MACSEC_DIFF(ENCRYPT, a->encrypt != b->encrypt); diff |= MACSEC_DIFF(PROTECT, a->protect != b->protect); diff |= MACSEC_DIFF(INC_SCI, a->send_sci != b->send_sci); diff |= MACSEC_DIFF(ES, a->end_station != b->end_station); diff |= MACSEC_DIFF(SCB, a->scb != b->scb); diff |= MACSEC_DIFF(VALIDATION, a->validate != b->validate); #undef MACSEC_DIFF return diff; } static struct rtnl_link_info_ops macsec_info_ops = { .io_name = "macsec", .io_alloc = macsec_alloc, .io_parse = macsec_parse, .io_dump = { [NL_DUMP_LINE] = macsec_dump_line, [NL_DUMP_DETAILS] = macsec_dump_details, }, .io_clone = macsec_clone, .io_put_attrs = macsec_put_attrs, .io_free = macsec_free, .io_compare = macsec_compare, }; static void __init macsec_init(void) { rtnl_link_register_info(&macsec_info_ops); } static void __exit macsec_exit(void) { rtnl_link_unregister_info(&macsec_info_ops); } /** @cond SKIP */ #define IS_MACSEC_LINK_ASSERT(link) \ if ((link)->l_info_ops != &macsec_info_ops) { \ APPBUG("Link is not a MACsec link. set type \"macsec\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ struct rtnl_link *rtnl_link_macsec_alloc(void) { struct rtnl_link *link = rtnl_link_alloc(); if (!link) return NULL; if (rtnl_link_set_type(link, "macsec") < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Set SCI * @arg link Link object * @arg sci Secure Channel Identifier in network byte order * * @return 0 on success or a negative error code. */ int rtnl_link_macsec_set_sci(struct rtnl_link *link, uint64_t sci) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); info->sci = sci; info->ce_mask |= MACSEC_ATTR_SCI; return 0; } /** * Get SCI * @arg link Link object * @arg sci On return points to the Secure Channel Identifier * in network byte order * * @return 0 on success or a negative error code. */ int rtnl_link_macsec_get_sci(struct rtnl_link *link, uint64_t *sci) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_SCI)) return -NLE_NOATTR; if (sci) *sci = info->sci; return 0; } /** * Set port identifier * @arg link Link object * @arg port Port identifier in host byte order * * @return 0 on success or a negative error code. */ int rtnl_link_macsec_set_port(struct rtnl_link *link, uint16_t port) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); info->port = port; info->ce_mask |= MACSEC_ATTR_PORT; return 0; } /** * Get port identifier * @arg link Link object * @arg port On return points to the port identifier in host byte order * * @return 0 on success or a negative error code. */ int rtnl_link_macsec_get_port(struct rtnl_link *link, uint16_t *port) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_PORT)) return -NLE_NOATTR; if (port) *port = info->port; return 0; } int rtnl_link_macsec_set_cipher_suite(struct rtnl_link *link, uint64_t cipher_suite) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); info->cipher_suite = cipher_suite; info->ce_mask |= MACSEC_ATTR_CIPHER_SUITE; return 0; } int rtnl_link_macsec_get_cipher_suite(struct rtnl_link *link, uint64_t *cs) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_CIPHER_SUITE)) return -NLE_NOATTR; if (cs) *cs = info->cipher_suite; return 0; } int rtnl_link_macsec_set_icv_len(struct rtnl_link *link, uint16_t icv_len) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (icv_len > MACSEC_STD_ICV_LEN) return -NLE_INVAL; info->icv_len = icv_len; info->ce_mask |= MACSEC_ATTR_ICV_LEN; return 0; } int rtnl_link_macsec_get_icv_len(struct rtnl_link *link, uint16_t *icv_len) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_ICV_LEN)) return -NLE_NOATTR; if (icv_len) *icv_len = info->icv_len; return 0; } int rtnl_link_macsec_set_protect(struct rtnl_link *link, uint8_t protect) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (protect > 1) return -NLE_INVAL; info->protect = protect; info->ce_mask |= MACSEC_ATTR_PROTECT; return 0; } int rtnl_link_macsec_get_protect(struct rtnl_link *link, uint8_t *protect) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_PROTECT)) return -NLE_NOATTR; if (protect) *protect = info->protect; return 0; } int rtnl_link_macsec_set_encrypt(struct rtnl_link *link, uint8_t encrypt) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (encrypt > 1) return -NLE_INVAL; info->encrypt = encrypt; info->ce_mask |= MACSEC_ATTR_ENCRYPT; return 0; } int rtnl_link_macsec_get_encrypt(struct rtnl_link *link, uint8_t *encrypt) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_ENCRYPT)) return -NLE_NOATTR; if (encrypt) *encrypt = info->encrypt; return 0; } int rtnl_link_macsec_set_encoding_sa(struct rtnl_link *link, uint8_t encoding_sa) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (encoding_sa > 3) return -NLE_INVAL; info->encoding_sa = encoding_sa; info->ce_mask |= MACSEC_ATTR_ENCODING_SA; return 0; } int rtnl_link_macsec_get_encoding_sa(struct rtnl_link *link, uint8_t *encoding_sa) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_ENCODING_SA)) return -NLE_NOATTR; if (encoding_sa) *encoding_sa = info->encoding_sa; return 0; } int rtnl_link_macsec_set_validation_type(struct rtnl_link *link, enum macsec_validation_type validate) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (validate > 1) return -NLE_INVAL; info->validate = validate; info->ce_mask |= MACSEC_ATTR_VALIDATION; return 0; } int rtnl_link_macsec_get_validation_type(struct rtnl_link *link, enum macsec_validation_type *validate) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_VALIDATION)) return -NLE_NOATTR; if (validate) *validate = info->validate; return 0; } int rtnl_link_macsec_set_replay_protect(struct rtnl_link *link, uint8_t replay_protect) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (replay_protect > 1) return -NLE_INVAL; info->replay_protect = replay_protect; info->ce_mask |= MACSEC_ATTR_REPLAY_PROTECT; return 0; } int rtnl_link_macsec_get_replay_protect(struct rtnl_link *link, uint8_t *replay_protect) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_REPLAY_PROTECT)) return -NLE_NOATTR; if (replay_protect) *replay_protect = info->replay_protect; return 0; } int rtnl_link_macsec_set_window(struct rtnl_link *link, uint32_t window) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); info->window = window; info->ce_mask |= MACSEC_ATTR_WINDOW; return 0; } int rtnl_link_macsec_get_window(struct rtnl_link *link, uint32_t *window) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_WINDOW)) return -NLE_NOATTR; if (window) *window = info->window; return 0; } int rtnl_link_macsec_set_send_sci(struct rtnl_link *link, uint8_t send_sci) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (send_sci > 1) return -NLE_INVAL; info->send_sci = send_sci; info->ce_mask |= MACSEC_ATTR_INC_SCI; return 0; } int rtnl_link_macsec_get_send_sci(struct rtnl_link *link, uint8_t *send_sci) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_INC_SCI)) return -NLE_NOATTR; if (send_sci) *send_sci = info->send_sci; return 0; } int rtnl_link_macsec_set_end_station(struct rtnl_link *link, uint8_t end_station) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (end_station > 1) return -NLE_INVAL; info->end_station = end_station; info->ce_mask |= MACSEC_ATTR_ES; return 0; } int rtnl_link_macsec_get_end_station(struct rtnl_link *link, uint8_t *es) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_ES)) return -NLE_NOATTR; if (es) *es = info->end_station; return 0; } int rtnl_link_macsec_set_scb(struct rtnl_link *link, uint8_t scb) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (scb > 1) return -NLE_INVAL; info->scb = scb; info->ce_mask |= MACSEC_ATTR_SCB; return 0; } int rtnl_link_macsec_get_scb(struct rtnl_link *link, uint8_t *scb) { struct macsec_info *info = link->l_info; IS_MACSEC_LINK_ASSERT(link); if (!(info->ce_mask & MACSEC_ATTR_SCB)) return -NLE_NOATTR; if (scb) *scb = info->scb; return 0; } /** @} */ /** @} */ libnl-3.2.29/lib/route/link/ppp.c0000644000175000017500000001000613023014600013416 00000000000000/* * lib/route/link/ppp.c PPP Link Module * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Jonas Johansson */ /** * @ingroup link * @defgroup ppp PPP * * @details * \b Link Type Name: "ppp" * * @route_doc{link_ppp, PPP Documentation} * @{ */ #include #include #include #include /** @cond SKIP */ #define PPP_ATTR_FD (1<<0) struct ppp_info { int32_t pi_fd; uint32_t ce_mask; }; /** @endcond */ static struct nla_policy ppp_nl_policy[IFLA_PPP_MAX+1] = { [IFLA_PPP_DEV_FD] = { .type = NLA_S32 }, }; static int ppp_alloc(struct rtnl_link *link) { struct ppp_info *info; if (link->l_info) memset(link->l_info, 0, sizeof(*info)); else { if ((info = calloc(1, sizeof(*info))) == NULL) return -NLE_NOMEM; link->l_info = info; } return 0; } static int ppp_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_PPP_MAX+1]; struct ppp_info *info; int err; NL_DBG(3, "Parsing PPP link info\n"); if ((err = nla_parse_nested(tb, IFLA_PPP_MAX, data, ppp_nl_policy)) < 0) goto errout; if ((err = ppp_alloc(link)) < 0) goto errout; info = link->l_info; if (tb[IFLA_PPP_DEV_FD]) { info->pi_fd = nla_get_s32(tb[IFLA_PPP_DEV_FD]); info->ce_mask |= PPP_ATTR_FD; } err = 0; errout: return err; } static void ppp_free(struct rtnl_link *link) { free(link->l_info); link->l_info = NULL; } static int ppp_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct ppp_info *vdst, *vsrc = src->l_info; int err; dst->l_info = NULL; if ((err = rtnl_link_set_type(dst, "ppp")) < 0) return err; vdst = dst->l_info; if (!vdst || !vsrc) return -NLE_NOMEM; memcpy(vdst, vsrc, sizeof(struct ppp_info)); return 0; } static int ppp_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct ppp_info *info = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; if (info->ce_mask & PPP_ATTR_FD) NLA_PUT_S32(msg, IFLA_PPP_DEV_FD, info->pi_fd); nla_nest_end(msg, data); nla_put_failure: return 0; } static struct rtnl_link_info_ops ppp_info_ops = { .io_name = "ppp", .io_alloc = ppp_alloc, .io_parse = ppp_parse, .io_clone = ppp_clone, .io_put_attrs = ppp_put_attrs, .io_free = ppp_free, }; /** @cond SKIP */ #define IS_PPP_LINK_ASSERT(link) \ if ((link)->l_info_ops != &ppp_info_ops) { \ APPBUG("Link is not a PPP link. set type \"ppp\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ /** * @name PPP Object * @{ */ /** * Allocate link object of type PPP * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_ppp_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "ppp")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Set PPP file descriptor * @arg link Link object * @arg flags PPP file descriptor * * @return 0 on success or a negative error code. */ int rtnl_link_ppp_set_fd(struct rtnl_link *link, int32_t fd) { struct ppp_info *info = link->l_info; IS_PPP_LINK_ASSERT(link); info->pi_fd |= fd; info->ce_mask |= PPP_ATTR_FD; return 0; } /** * Get PPP file descriptor * @arg link Link object * * @return PPP file descriptor, 0 if not set or a negative error code. */ int rtnl_link_ppp_get_fd(struct rtnl_link *link, int32_t *fd) { struct ppp_info *info = link->l_info; IS_PPP_LINK_ASSERT(link); if (!(info->ce_mask & PPP_ATTR_FD)) return -NLE_NOATTR; if (fd) *fd = info->pi_fd; return 0; } /** @} */ static void __init ppp_init(void) { rtnl_link_register_info(&ppp_info_ops); } static void __exit ppp_exit(void) { rtnl_link_unregister_info(&ppp_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/api.c0000644000175000017500000002314713023014600013402 00000000000000/* * lib/route/link/api.c Link Info API * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup link * @defgroup link_API Link Modules API * @brief API for modules implementing specific link types/semantics. * * @par 1) Registering/Unregistering a new link info type * @code * static struct rtnl_link_info_ops vlan_info_ops = { * .io_name = "vlan", * .io_alloc = vlan_alloc, * .io_parse = vlan_parse, * .io_dump[NL_DUMP_BRIEF] = vlan_dump_brief, * .io_dump[NL_DUMP_FULL] = vlan_dump_full, * .io_free = vlan_free, * }; * * static void __init vlan_init(void) * { * rtnl_link_register_info(&vlan_info_ops); * } * * static void __exit vlan_exit(void) * { * rtnl_link_unregister_info(&vlan_info_ops); * } * @endcode * * @{ */ #include #include #include #include #include static NL_LIST_HEAD(info_ops); /* lock protecting info_ops and af_ops */ static NL_RW_LOCK(info_lock); static struct rtnl_link_info_ops *__rtnl_link_info_ops_lookup(const char *name) { struct rtnl_link_info_ops *ops; nl_list_for_each_entry(ops, &info_ops, io_list) if (!strcmp(ops->io_name, name)) return ops; return NULL; } /** * @name Link Info Modules * @{ */ /** * Return operations of a specific link info type * @arg name Name of link info type. * * @note The returned pointer must be given back using rtnl_link_info_ops_put() * * @return Pointer to operations or NULL if unavailable. */ struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *name) { struct rtnl_link_info_ops *ops; nl_write_lock(&info_lock); if ((ops = __rtnl_link_info_ops_lookup(name))) ops->io_refcnt++; nl_write_unlock(&info_lock); return ops; } /** * Give back reference to a set of operations. * @arg ops Link info operations. */ void rtnl_link_info_ops_put(struct rtnl_link_info_ops *ops) { if (ops) ops->io_refcnt--; } /** * Register operations for a link info type * @arg ops Link info operations * * This function must be called by modules implementing a specific link * info type. It will make the operations implemented by the module * available for everyone else. * * @return 0 on success or a negative error code. * @return -NLE_INVAL Link info name not specified. * @return -NLE_EXIST Operations for address family already registered. */ int rtnl_link_register_info(struct rtnl_link_info_ops *ops) { int err = 0; if (ops->io_name == NULL) return -NLE_INVAL; nl_write_lock(&info_lock); if (__rtnl_link_info_ops_lookup(ops->io_name)) { err = -NLE_EXIST; goto errout; } NL_DBG(1, "Registered link info operations %s\n", ops->io_name); nl_list_add_tail(&ops->io_list, &info_ops); errout: nl_write_unlock(&info_lock); return err; } /** * Unregister operations for a link info type * @arg ops Link info operations * * This function must be called if a module implementing a specific link * info type is unloaded or becomes unavailable. It must provide a * set of operations which have previously been registered using * rtnl_link_register_info(). * * @return 0 on success or a negative error code * @return _NLE_OPNOTSUPP Link info operations not registered. * @return -NLE_BUSY Link info operations still in use. */ int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops) { struct rtnl_link_info_ops *t; int err = -NLE_OPNOTSUPP; nl_write_lock(&info_lock); nl_list_for_each_entry(t, &info_ops, io_list) { if (t == ops) { if (t->io_refcnt > 0) { err = -NLE_BUSY; goto errout; } nl_list_del(&t->io_list); NL_DBG(1, "Unregistered link info operations %s\n", ops->io_name); err = 0; goto errout; } } errout: nl_write_unlock(&info_lock); return err; } /** @} */ /** * @name Link Address Family Modules * @{ */ static struct rtnl_link_af_ops *af_ops[AF_MAX]; /** * Return operations of a specific link address family * @arg family Address family * * @note The returned pointer must be given back using rtnl_link_af_ops_put() * * @return Pointer to operations or NULL if unavailable. */ struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(const unsigned int family) { if (family == AF_UNSPEC || family >= AF_MAX) return NULL; nl_write_lock(&info_lock); if (af_ops[family]) af_ops[family]->ao_refcnt++; nl_write_unlock(&info_lock); return af_ops[family]; } /** * Give back reference to a set of operations. * @arg ops Address family operations. */ void rtnl_link_af_ops_put(struct rtnl_link_af_ops *ops) { if (ops) ops->ao_refcnt--; } /** * Allocate and return data buffer for link address family modules * @arg link Link object * @arg ops Address family operations * * This function must be called by link address family modules in all * cases where the API does not provide the data buffer as argument * already. This typically includes set functions the module provides. * Calling this function is strictly required to ensure proper allocation * of the buffer upon first use. Link objects will NOT proactively * allocate a data buffer for each registered link address family. * * @return Pointer to data buffer or NULL on error. */ void *rtnl_link_af_alloc(struct rtnl_link *link, const struct rtnl_link_af_ops *ops) { int family; if (!link || !ops) BUG(); family = ops->ao_family; if (!link->l_af_data[family]) { if (!ops->ao_alloc) BUG(); link->l_af_data[family] = ops->ao_alloc(link); if (!link->l_af_data[family]) return NULL; } return link->l_af_data[family]; } /** * Return data buffer for link address family modules * @arg link Link object * @arg ops Address family operations * * This function returns a pointer to the data buffer for the specified link * address family module or NULL if the buffer was not allocated yet. This * function is typically used by get functions of modules which are not * interested in having the data buffer allocated if no values have been set * yet. * * @return Pointer to data buffer or NULL on error. */ void *rtnl_link_af_data(const struct rtnl_link *link, const struct rtnl_link_af_ops *ops) { if (!link || !ops) BUG(); return link->l_af_data[ops->ao_family]; } /** * Register operations for a link address family * @arg ops Address family operations * * This function must be called by modules implementing a specific link * address family. It will make the operations implemented by the module * available for everyone else. * * @return 0 on success or a negative error code. * @return -NLE_INVAL Address family is out of range (0..AF_MAX) * @return -NLE_EXIST Operations for address family already registered. */ int rtnl_link_af_register(struct rtnl_link_af_ops *ops) { int err = 0; if (ops->ao_family == AF_UNSPEC || ops->ao_family >= AF_MAX) return -NLE_INVAL; nl_write_lock(&info_lock); if (af_ops[ops->ao_family]) { err = -NLE_EXIST; goto errout; } ops->ao_refcnt = 0; af_ops[ops->ao_family] = ops; NL_DBG(1, "Registered link address family operations %u\n", ops->ao_family); errout: nl_write_unlock(&info_lock); return err; } /** * Unregister operations for a link address family * @arg ops Address family operations * * This function must be called if a module implementing a specific link * address family is unloaded or becomes unavailable. It must provide a * set of operations which have previously been registered using * rtnl_link_af_register(). * * @return 0 on success or a negative error code * @return -NLE_INVAL ops is NULL * @return -NLE_OBJ_NOTFOUND Address family operations not registered. * @return -NLE_BUSY Address family operations still in use. */ int rtnl_link_af_unregister(struct rtnl_link_af_ops *ops) { int err = -NLE_INVAL; if (!ops) return err; nl_write_lock(&info_lock); if (!af_ops[ops->ao_family]) { err = -NLE_OBJ_NOTFOUND; goto errout; } if (ops->ao_refcnt > 0) { err = -NLE_BUSY; goto errout; } af_ops[ops->ao_family] = NULL; NL_DBG(1, "Unregistered link address family operations %u\n", ops->ao_family); errout: nl_write_unlock(&info_lock); return err; } /** * Compare af data for a link address family * @arg a Link object a * @arg b Link object b * @arg family af data family * * This function will compare af_data between two links * a and b of family given by arg family * * @return 0 if address family specific data matches or is not present * or != 0 if it mismatches. */ int rtnl_link_af_data_compare(struct rtnl_link *a, struct rtnl_link *b, int family) { struct rtnl_link_af_ops *af_ops; int ret = 0; if (!a->l_af_data[family] && !b->l_af_data[family]) return 0; if (!a->l_af_data[family] || !b->l_af_data[family]) return ~0; af_ops = rtnl_link_af_ops_lookup(family); if (!af_ops) return ~0; if (af_ops->ao_compare == NULL) { ret = ~0; goto out; } ret = af_ops->ao_compare(a, b, family, ~0, 0); out: rtnl_link_af_ops_put(af_ops); return ret; } /** * Compare link info data * @arg a Link object a * @arg b Link object b * * This function will compare link_info data between two links * a and b * * @return 0 if link_info data matches or is not present * or != 0 if it mismatches. */ int rtnl_link_info_data_compare(struct rtnl_link *a, struct rtnl_link *b, int flags) { if (a->l_info_ops != b->l_info_ops) return ~0; if (!a->l_info_ops || !a->l_info_ops->io_compare) return 0; return a->l_info_ops->io_compare(a, b, flags); } /** @} */ /** @} */ libnl-3.2.29/lib/route/link/macvlan.c0000644000175000017500000004641613023014600014256 00000000000000/* * lib/route/link/macvlan.c MACVLAN Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Michael Braun */ /** * @ingroup link * @defgroup macvlan MACVLAN/MACVTAP * MAC-based Virtual LAN link module * * @details * \b Link Type Name: "macvlan" * * @route_doc{link_macvlan, MACVLAN Documentation} * @route_doc{link_macvtap, MACVTAP Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define MACVLAN_HAS_MODE (1<<0) #define MACVLAN_HAS_FLAGS (1<<1) #define MACVLAN_HAS_MACADDR (1<<2) struct macvlan_info { uint32_t mvi_mode; uint16_t mvi_flags; // there currently is only one flag and kernel has no flags_mask yet uint32_t mvi_mask; uint32_t mvi_maccount; uint32_t mvi_macmode; struct nl_addr **mvi_macaddr; }; /** @endcond */ static struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX+1] = { [IFLA_MACVLAN_MODE] = { .type = NLA_U32 }, [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 }, [IFLA_MACVLAN_MACADDR_MODE] = { .type = NLA_U32 }, [IFLA_MACVLAN_MACADDR] = { .type = NLA_UNSPEC }, [IFLA_MACVLAN_MACADDR_DATA] = { .type = NLA_NESTED }, [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NLA_U32 }, }; static int macvlan_alloc(struct rtnl_link *link) { struct macvlan_info *mvi; uint32_t i; if (link->l_info) { mvi = link->l_info; for (i = 0; i < mvi->mvi_maccount; i++) nl_addr_put(mvi->mvi_macaddr[i]); free(mvi->mvi_macaddr); memset(mvi, 0, sizeof(*mvi)); } else { if ((mvi = calloc(1, sizeof(*mvi))) == NULL) return -NLE_NOMEM; link->l_info = mvi; } mvi->mvi_macmode = MACVLAN_MACADDR_SET; return 0; } static int macvlan_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_MACVLAN_MAX+1]; struct macvlan_info *mvi; struct nlattr *nla; int len; int err; NL_DBG(3, "Parsing %s link info", link->l_info_ops->io_name); if ((err = nla_parse_nested(tb, IFLA_MACVLAN_MAX, data, macvlan_policy)) < 0) goto errout; if ((err = macvlan_alloc(link)) < 0) goto errout; mvi = link->l_info; if (tb[IFLA_MACVLAN_MODE]) { mvi->mvi_mode = nla_get_u32(tb[IFLA_MACVLAN_MODE]); mvi->mvi_mask |= MACVLAN_HAS_MODE; } if (tb[IFLA_MACVLAN_FLAGS]) { mvi->mvi_mode = nla_get_u16(tb[IFLA_MACVLAN_FLAGS]); mvi->mvi_mask |= MACVLAN_HAS_FLAGS; } if ( tb[IFLA_MACVLAN_MACADDR_COUNT] && tb[IFLA_MACVLAN_MACADDR_DATA]) { mvi->mvi_maccount = nla_get_u32(tb[IFLA_MACVLAN_MACADDR_COUNT]); if (mvi->mvi_maccount > 0) { uint32_t i; nla = nla_data(tb[IFLA_MACVLAN_MACADDR_DATA]); len = nla_len(tb[IFLA_MACVLAN_MACADDR_DATA]); mvi->mvi_macaddr = calloc(mvi->mvi_maccount, sizeof(*(mvi->mvi_macaddr))); i = 0; for (; nla_ok(nla, len); nla = nla_next(nla, &len)) { if (i >= mvi->mvi_maccount) break; if (nla_type(nla) != IFLA_MACVLAN_MACADDR || nla_len(nla) < ETH_ALEN) continue; mvi->mvi_macaddr[i] = nl_addr_alloc_attr(nla, AF_LLC); i++; } } mvi->mvi_mask |= MACVLAN_HAS_MACADDR; } err = 0; errout: return err; } static void macvlan_free(struct rtnl_link *link) { struct macvlan_info *mvi; uint32_t i; mvi = link->l_info; for (i = 0; i < mvi->mvi_maccount; i++) nl_addr_put(mvi->mvi_macaddr[i]); free(mvi->mvi_macaddr); free(mvi); link->l_info = NULL; } static void macvlan_dump(struct rtnl_link *link, struct nl_dump_params *p) { char buf[64]; uint32_t i; struct macvlan_info *mvi = link->l_info; if (mvi->mvi_mask & MACVLAN_HAS_MODE) { rtnl_link_macvlan_mode2str(mvi->mvi_mode, buf, sizeof(buf)); nl_dump(p, "%s-mode %s", link->l_info_ops->io_name, buf); } if (mvi->mvi_mask & MACVLAN_HAS_FLAGS) { rtnl_link_macvlan_flags2str(mvi->mvi_flags, buf, sizeof(buf)); nl_dump(p, "%s-flags %s", link->l_info_ops->io_name, buf); } if (mvi->mvi_mask & MACVLAN_HAS_MACADDR) { nl_dump(p, "macvlan-count %u", (unsigned) mvi->mvi_maccount); for (i = 0; i < mvi->mvi_maccount; i++) { nl_dump(p, "macvlan-sourcemac %s", nl_addr2str(mvi->mvi_macaddr[i], buf, sizeof(buf))); } } } static int macvlan_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct macvlan_info *vdst, *vsrc = src->l_info; int err; uint32_t i; dst->l_info = NULL; if ((err = rtnl_link_set_type(dst, "macvlan")) < 0) return err; vdst = dst->l_info; if (!vdst || !vsrc) return -NLE_NOMEM; memcpy(vdst, vsrc, sizeof(struct macvlan_info)); if ( vsrc->mvi_mask & MACVLAN_HAS_MACADDR && vsrc->mvi_maccount > 0) { vdst->mvi_macaddr = calloc(vdst->mvi_maccount, sizeof(*(vdst->mvi_macaddr))); for (i = 0; i < vdst->mvi_maccount; i++) vdst->mvi_macaddr[i] = nl_addr_clone(vsrc->mvi_macaddr[i]); } else vdst->mvi_macaddr = NULL; return 0; } static int macvlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct macvlan_info *mvi = link->l_info; struct nlattr *data, *datamac = NULL; int i, ret; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; ret = -NLE_NOMEM; if (mvi->mvi_mask & MACVLAN_HAS_MODE) NLA_PUT_U32(msg, IFLA_MACVLAN_MODE, mvi->mvi_mode); if (mvi->mvi_mask & MACVLAN_HAS_FLAGS) NLA_PUT_U16(msg, IFLA_MACVLAN_FLAGS, mvi->mvi_flags); if (mvi->mvi_mask & MACVLAN_HAS_MACADDR) { NLA_PUT_U32(msg, IFLA_MACVLAN_MACADDR_MODE, mvi->mvi_macmode); datamac = nla_nest_start(msg, IFLA_MACVLAN_MACADDR_DATA); if (!datamac) goto nla_put_failure; for (i = 0; i < mvi->mvi_maccount; i++) { NLA_PUT_ADDR(msg, IFLA_MACVLAN_MACADDR, mvi->mvi_macaddr[i]); } } ret = 0; nla_put_failure: if (datamac) nla_nest_end(msg, datamac); nla_nest_end(msg, data); return ret; } static struct rtnl_link_info_ops macvlan_info_ops = { .io_name = "macvlan", .io_alloc = macvlan_alloc, .io_parse = macvlan_parse, .io_dump = { [NL_DUMP_LINE] = macvlan_dump, [NL_DUMP_DETAILS] = macvlan_dump, }, .io_clone = macvlan_clone, .io_put_attrs = macvlan_put_attrs, .io_free = macvlan_free, }; static struct rtnl_link_info_ops macvtap_info_ops = { .io_name = "macvtap", .io_alloc = macvlan_alloc, .io_parse = macvlan_parse, .io_dump = { [NL_DUMP_LINE] = macvlan_dump, [NL_DUMP_DETAILS] = macvlan_dump, }, .io_clone = macvlan_clone, .io_put_attrs = macvlan_put_attrs, .io_free = macvlan_free, }; /** @cond SKIP */ #define IS_MACVLAN_LINK_ASSERT(link) \ if ((link)->l_info_ops != &macvlan_info_ops) { \ APPBUG("Link is not a macvlan link. set type \"macvlan\" first."); \ return -NLE_OPNOTSUPP; \ } #define IS_MACVTAP_LINK_ASSERT(link) \ if ((link)->l_info_ops != &macvtap_info_ops) { \ APPBUG("Link is not a macvtap link. set type \"macvtap\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ /** * @name MACVLAN Object * @{ */ /** * Allocate link object of type MACVLAN * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_macvlan_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "macvlan")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a MACVLAN link * @arg link Link object * * @return True if link is a MACVLAN link, otherwise false is returned. */ int rtnl_link_is_macvlan(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "macvlan"); } /** * Set MACVLAN MODE * @arg link Link object * @arg mode MACVLAN mode * * @return 0 on success or a negative error code */ int rtnl_link_macvlan_set_mode(struct rtnl_link *link, uint32_t mode) { struct macvlan_info *mvi = link->l_info; int i; IS_MACVLAN_LINK_ASSERT(link); mvi->mvi_mode = mode; mvi->mvi_mask |= MACVLAN_HAS_MODE; if (mode != MACVLAN_MODE_SOURCE) { for (i = 0; i < mvi->mvi_maccount; i++) nl_addr_put(mvi->mvi_macaddr[i]); free(mvi->mvi_macaddr); mvi->mvi_maccount = 0; mvi->mvi_macaddr = NULL; mvi->mvi_macmode = MACVLAN_MACADDR_SET; mvi->mvi_mask &= ~MACVLAN_HAS_MACADDR; } return 0; } /** * Get MACVLAN Mode * @arg link Link object * * @return MACVLAN mode, 0 if not set or a negative error code. */ uint32_t rtnl_link_macvlan_get_mode(struct rtnl_link *link) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); if (mvi->mvi_mask & MACVLAN_HAS_MODE) return mvi->mvi_mode; else return 0; } /** * Set MACVLAN MACMODE * @arg link Link object * @arg mode MACVLAN mac list modification mode * * Only for macvlan SOURCE mode. * * @return 0 on success or a negative error code */ int rtnl_link_macvlan_set_macmode(struct rtnl_link *link, uint32_t macmode) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); if (!(mvi->mvi_mask & MACVLAN_HAS_MODE) || (mvi->mvi_mode != MACVLAN_MODE_SOURCE)) return -NLE_INVAL; mvi->mvi_macmode = macmode; mvi->mvi_mask |= MACVLAN_HAS_MACADDR; return 0; } /** * Get MACVLAN MACMODE * @arg link Link object * @arg out_macmode mac list modification mode * * Only for SOURCE mode. * * @return 0 on success or a negative error code. */ int rtnl_link_macvlan_get_macmode(struct rtnl_link *link, uint32_t *out_macmode) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); if (!(mvi->mvi_mask & MACVLAN_HAS_MODE) || (mvi->mvi_mode != MACVLAN_MODE_SOURCE)) return -NLE_INVAL; if (!(mvi->mvi_mask & MACVLAN_HAS_MACADDR)) return -NLE_INVAL; *out_macmode = mvi->mvi_macmode; return 0; } /** * Set MACVLAN flags * @arg link Link object * @arg flags MACVLAN flags * * @return 0 on success or a negative error code. */ int rtnl_link_macvlan_set_flags(struct rtnl_link *link, uint16_t flags) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); mvi->mvi_flags |= flags; mvi->mvi_mask |= MACVLAN_HAS_FLAGS; return 0; } /** * Unset MACVLAN flags * @arg link Link object * @arg flags MACVLAN flags * * Note: kernel currently only has a single flag and lacks flags_mask to * indicate which flags shall be changed (it always all). * * @return 0 on success or a negative error code. */ int rtnl_link_macvlan_unset_flags(struct rtnl_link *link, uint16_t flags) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); mvi->mvi_flags &= ~flags; mvi->mvi_mask |= MACVLAN_HAS_FLAGS; return 0; } /** * Get MACVLAN flags * @arg link Link object * * @return MACVLAN flags, 0 if none set, or a negative error code. */ uint16_t rtnl_link_macvlan_get_flags(struct rtnl_link *link) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); return mvi->mvi_flags; } /** * Get number of MAC-Addr for MACVLAN device in source mode * @arg link Link object * @arg out_count number of mac addresses * * @return 0 on success or a negative error code. */ int rtnl_link_macvlan_count_macaddr(struct rtnl_link *link, uint32_t *out_count) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); if (!(mvi->mvi_mask & MACVLAN_HAS_MODE) || (mvi->mvi_mode != MACVLAN_MODE_SOURCE)) return -NLE_INVAL; if (!(mvi->mvi_mask & MACVLAN_HAS_MACADDR)) return -NLE_INVAL; *out_count = mvi->mvi_maccount; return 0; } /** * Get configured remote MAC-Addr from MACVLAN device in source mode * @arg link Link object * @arg out_addr address object * * The returned nl_addr struct needs NOT to be released using nl_addr_put. * It is only valid until the address is not removed from this link object * or its mode is changed to non-source. * * @return 0 on success or negative error code */ int rtnl_link_macvlan_get_macaddr(struct rtnl_link *link, uint32_t idx, const struct nl_addr **out_addr) { struct macvlan_info *mvi = link->l_info; IS_MACVLAN_LINK_ASSERT(link); if (!(mvi->mvi_mask & MACVLAN_HAS_MODE) || (mvi->mvi_mode != MACVLAN_MODE_SOURCE)) return -NLE_INVAL; if (!(mvi->mvi_mask & MACVLAN_HAS_MACADDR)) return -NLE_INVAL; if (idx >= mvi->mvi_maccount) return -NLE_INVAL; *out_addr = mvi->mvi_macaddr[idx]; return 0; } /** * Add MAC-Addr to MACVLAN device in source mode * @arg link Link object * @arg addr MAC-Addr * * addr is not release but cloned by this method. * * @return 0 on success or a negative error code. */ int rtnl_link_macvlan_add_macaddr(struct rtnl_link *link, struct nl_addr *addr) { struct macvlan_info *mvi = link->l_info; struct nl_addr **mvi_macaddr; size_t newsize; IS_MACVLAN_LINK_ASSERT(link); if (nl_addr_get_family(addr) != AF_LLC) return -NLE_INVAL; if (!(mvi->mvi_mask & MACVLAN_HAS_MODE) || (mvi->mvi_mode != MACVLAN_MODE_SOURCE)) return -NLE_INVAL; if (!(mvi->mvi_mask & MACVLAN_HAS_MACADDR)) return -NLE_INVAL; if (mvi->mvi_maccount >= UINT32_MAX) return -NLE_INVAL; newsize = (mvi->mvi_maccount + 1) * sizeof(*(mvi->mvi_macaddr)); mvi_macaddr = realloc(mvi->mvi_macaddr, newsize); if (!mvi_macaddr) return -NLE_NOMEM; mvi->mvi_macaddr = mvi_macaddr; mvi->mvi_macaddr[mvi->mvi_maccount] = nl_addr_clone(addr); mvi->mvi_maccount++; mvi->mvi_mask |= MACVLAN_HAS_MACADDR; return 0; } /** * Remove MAC-Addr from MACVLAN device in source mode * @arg link Link object * @arg addr MAC-Addr * * addr is not release by this method. * * @return a negative error code on failure, or the number * of deleted addresses on success. */ int rtnl_link_macvlan_del_macaddr(struct rtnl_link *link, struct nl_addr *addr) { struct macvlan_info *mvi = link->l_info; uint32_t found, i; IS_MACVLAN_LINK_ASSERT(link); if (nl_addr_get_family(addr) != AF_LLC) return -NLE_INVAL; if (!(mvi->mvi_mask & MACVLAN_HAS_MODE) || (mvi->mvi_mode != MACVLAN_MODE_SOURCE)) return -NLE_INVAL; if (!(mvi->mvi_mask & MACVLAN_HAS_MACADDR)) return -NLE_INVAL; nl_addr_get(addr); found = 0; i = 0; while (i + found < mvi->mvi_maccount) { mvi->mvi_macaddr[i] = mvi->mvi_macaddr[i + found]; if (found > 0) mvi->mvi_macaddr[i + found] = NULL; if (nl_addr_cmp(addr, mvi->mvi_macaddr[i]) == 0) { nl_addr_put(mvi->mvi_macaddr[i]); mvi->mvi_macaddr[i] = NULL; found++; } else i++; } nl_addr_put(addr); mvi->mvi_maccount -= found; return found > INT_MAX ? INT_MAX : (int) found; } /** @} */ /** * @name MACVTAP Object * @{ */ /** * Allocate link object of type MACVTAP * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_macvtap_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "macvtap")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a MACVTAP link * @arg link Link object * * @return True if link is a MACVTAP link, otherwise false is returned. */ int rtnl_link_is_macvtap(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "macvtap"); } /** * Set MACVTAP MODE * @arg link Link object * @arg mode MACVTAP mode * * @return 0 on success or a negative error code */ int rtnl_link_macvtap_set_mode(struct rtnl_link *link, uint32_t mode) { struct macvlan_info *mvi = link->l_info; IS_MACVTAP_LINK_ASSERT(link); mvi->mvi_mode = mode; mvi->mvi_mask |= MACVLAN_HAS_MODE; return 0; } /** * Get MACVTAP Mode * @arg link Link object * * @return MACVTAP mode, 0 if not set or a negative error code. */ uint32_t rtnl_link_macvtap_get_mode(struct rtnl_link *link) { struct macvlan_info *mvi = link->l_info; IS_MACVTAP_LINK_ASSERT(link); if (mvi->mvi_mask & MACVLAN_HAS_MODE) return mvi->mvi_mode; else return 0; } /** * Set MACVTAP flags * @arg link Link object * @arg flags MACVTAP flags * * @return 0 on success or a negative error code. */ int rtnl_link_macvtap_set_flags(struct rtnl_link *link, uint16_t flags) { struct macvlan_info *mvi = link->l_info; IS_MACVTAP_LINK_ASSERT(link); mvi->mvi_flags |= flags; mvi->mvi_mask |= MACVLAN_HAS_FLAGS; return 0; } /** * Unset MACVTAP flags * @arg link Link object * @arg flags MACVTAP flags * * Note: kernel currently only has a single flag and lacks flags_mask to * indicate which flags shall be changed (it always all). * * @return 0 on success or a negative error code. */ int rtnl_link_macvtap_unset_flags(struct rtnl_link *link, uint16_t flags) { struct macvlan_info *mvi = link->l_info; IS_MACVTAP_LINK_ASSERT(link); mvi->mvi_flags &= ~flags; mvi->mvi_mask |= MACVLAN_HAS_FLAGS; return 0; } /** * Get MACVTAP flags * @arg link Link object * * @return MACVTAP flags, 0 if none set, or a negative error code. */ uint16_t rtnl_link_macvtap_get_flags(struct rtnl_link *link) { struct macvlan_info *mvi = link->l_info; IS_MACVTAP_LINK_ASSERT(link); return mvi->mvi_flags; } /** @} */ static const struct trans_tbl macvlan_flags[] = { __ADD(MACVLAN_FLAG_NOPROMISC, nopromisc), }; static const struct trans_tbl macvlan_modes[] = { __ADD(MACVLAN_MODE_PRIVATE, private), __ADD(MACVLAN_MODE_VEPA, vepa), __ADD(MACVLAN_MODE_BRIDGE, bridge), __ADD(MACVLAN_MODE_PASSTHRU, passthru), __ADD(MACVLAN_MODE_SOURCE, source), }; static const struct trans_tbl macvlan_macmodes[] = { __ADD(MACVLAN_MACADDR_ADD, "add"), __ADD(MACVLAN_MACADDR_DEL, "del"), __ADD(MACVLAN_MACADDR_SET, "set"), __ADD(MACVLAN_MACADDR_FLUSH, "flush"), }; /** * @name Flag Translation * @{ */ char *rtnl_link_macvlan_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, macvlan_flags, ARRAY_SIZE(macvlan_flags)); } int rtnl_link_macvlan_str2flags(const char *name) { return __str2flags(name, macvlan_flags, ARRAY_SIZE(macvlan_flags)); } char *rtnl_link_macvtap_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, macvlan_flags, ARRAY_SIZE(macvlan_flags)); } int rtnl_link_macvtap_str2flags(const char *name) { return __str2flags(name, macvlan_flags, ARRAY_SIZE(macvlan_flags)); } /** @} */ /** * @name Mode Translation * @{ */ char *rtnl_link_macvlan_mode2str(int mode, char *buf, size_t len) { return __type2str(mode, buf, len, macvlan_modes, ARRAY_SIZE(macvlan_modes)); } int rtnl_link_macvlan_str2mode(const char *name) { return __str2type(name, macvlan_modes, ARRAY_SIZE(macvlan_modes)); } char *rtnl_link_macvlan_macmode2str(int mode, char *buf, size_t len) { return __type2str(mode, buf, len, macvlan_macmodes, ARRAY_SIZE(macvlan_macmodes)); } int rtnl_link_macvlan_str2macmode(const char *name) { return __str2type(name, macvlan_macmodes, ARRAY_SIZE(macvlan_macmodes)); } char *rtnl_link_macvtap_mode2str(int mode, char *buf, size_t len) { return __type2str(mode, buf, len, macvlan_modes, ARRAY_SIZE(macvlan_modes)); } int rtnl_link_macvtap_str2mode(const char *name) { return __str2type(name, macvlan_modes, ARRAY_SIZE(macvlan_modes)); } /** @} */ static void __init macvlan_init(void) { rtnl_link_register_info(&macvlan_info_ops); rtnl_link_register_info(&macvtap_info_ops); } static void __exit macvlan_exit(void) { rtnl_link_unregister_info(&macvlan_info_ops); rtnl_link_unregister_info(&macvtap_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/ifb.c0000644000175000017500000000145013023014600013362 00000000000000/* * lib/route/link/ifb.c IFB Interfaces * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Cong Wang */ /** * @ingroup link * @defgroup ifb Intermediate Functional Block * * @details * \b Link Type Name: "ifb" * * @{ */ #include #include #include static struct rtnl_link_info_ops ifb_info_ops = { .io_name = "ifb", }; static void __init ifb_init(void) { rtnl_link_register_info(&ifb_info_ops); } static void __exit ifb_exit(void) { rtnl_link_unregister_info(&ifb_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/bonding.c0000644000175000017500000001367413023014600014255 00000000000000/* * lib/route/link/bonding.c Bonding Link Module * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2011-2013 Thomas Graf */ /** * @ingroup link * @defgroup bonding Bonding * * @details * \b Link Type Name: "bond" * * @route_doc{link_bonding, Bonding Documentation} * @{ */ #include #include #include #include /** * Allocate link object of type bond * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_bond_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "bond")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Create a new kernel bonding device * @arg sock netlink socket * @arg name name of bonding device or NULL * @arg opts bonding options (currently unused) * * Creates a new bonding device in the kernel. If no name is * provided, the kernel will automatically pick a name of the * form "type%d" (e.g. bond0, vlan1, etc.) * * The \a opts argument is currently unused. In the future, it * may be used to carry additional bonding options to be set * when creating the bonding device. * * @note When letting the kernel assign a name, it will become * difficult to retrieve the interface afterwards because * you have to guess the name the kernel has chosen. It is * therefore not recommended to not provide a device name. * * @see rtnl_link_bond_enslave() * @see rtnl_link_bond_release() * * @return 0 on success or a negative error code */ int rtnl_link_bond_add(struct nl_sock *sock, const char *name, struct rtnl_link *opts) { struct rtnl_link *link; int err; if (!(link = rtnl_link_bond_alloc())) return -NLE_NOMEM; if (!name && opts) name = rtnl_link_get_name(opts); if (name) rtnl_link_set_name(link, name); err = rtnl_link_add(sock, link, NLM_F_CREATE); rtnl_link_put(link); return err; } /** * Add a link to a bond (enslave) * @arg sock netlink socket * @arg master ifindex of bonding master * @arg slave ifindex of slave link to add to bond * * This function is identical to rtnl_link_bond_enslave() except that * it takes interface indices instead of rtnl_link objcets. * * @see rtnl_link_bond_enslave() * * @return 0 on success or a negative error code. */ int rtnl_link_bond_enslave_ifindex(struct nl_sock *sock, int master, int slave) { struct rtnl_link *link; int err; if (!(link = rtnl_link_bond_alloc())) return -NLE_NOMEM; rtnl_link_set_ifindex(link, slave); rtnl_link_set_master(link, master); if ((err = rtnl_link_change(sock, link, link, 0)) < 0) goto errout; rtnl_link_put(link); /* * Due to the kernel not signaling whether this opertion is * supported or not, we will retrieve the attribute to see if the * request was successful. If the master assigned remains unchanged * we will return NLE_OPNOTSUPP to allow performing backwards * compatibility of some sort. */ if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0) return err; if (rtnl_link_get_master(link) != master) err = -NLE_OPNOTSUPP; errout: rtnl_link_put(link); return err; } /** * Add a link to a bond (enslave) * @arg sock netlink socket * @arg master bonding master * @arg slave slave link to add to bond * * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to * the master and sends the request via the specified netlink socket. * * @note The feature of enslaving/releasing via netlink has only been added * recently to the kernel (Feb 2011). Also, the kernel does not signal * if the operation is not supported. Therefore this function will * verify if the master assignment has changed and will return * -NLE_OPNOTSUPP if it did not. * * @see rtnl_link_bond_enslave_ifindex() * @see rtnl_link_bond_release() * * @return 0 on success or a negative error code. */ int rtnl_link_bond_enslave(struct nl_sock *sock, struct rtnl_link *master, struct rtnl_link *slave) { return rtnl_link_bond_enslave_ifindex(sock, rtnl_link_get_ifindex(master), rtnl_link_get_ifindex(slave)); } /** * Release a link from a bond * @arg sock netlink socket * @arg slave slave link to be released * * This function is identical to rtnl_link_bond_release() except that * it takes an interface index instead of a rtnl_link object. * * @see rtnl_link_bond_release() * * @return 0 on success or a negative error code. */ int rtnl_link_bond_release_ifindex(struct nl_sock *sock, int slave) { return rtnl_link_bond_enslave_ifindex(sock, 0, slave); } /** * Release a link from a bond * @arg sock netlink socket * @arg slave slave link to be released * * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from * its master and sends the request via the specified netlink socket. * * @note The feature of enslaving/releasing via netlink has only been added * recently to the kernel (Feb 2011). Also, the kernel does not signal * if the operation is not supported. Therefore this function will * verify if the master assignment has changed and will return * -NLE_OPNOTSUPP if it did not. * * @see rtnl_link_bond_release_ifindex() * @see rtnl_link_bond_enslave() * * @return 0 on success or a negative error code. */ int rtnl_link_bond_release(struct nl_sock *sock, struct rtnl_link *slave) { return rtnl_link_bond_release_ifindex(sock, rtnl_link_get_ifindex(slave)); } static struct rtnl_link_info_ops bonding_info_ops = { .io_name = "bond", }; static void __init bonding_init(void) { rtnl_link_register_info(&bonding_info_ops); } static void __exit bonding_exit(void) { rtnl_link_unregister_info(&bonding_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/ipvti.c0000644000175000017500000002424313023014600013762 00000000000000/* * lib/route/link/ipvti.c IPVTI Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ /** * @ingroup link * @defgroup ipvti IPVTI * ipvti link module * * @details * \b Link Type Name: "ipvti" * * @route_doc{link_ipvti, IPVTI Documentation} * * @{ */ #include #include #include #include #include #include #include #include #define IPVTI_ATTR_LINK (1 << 0) #define IPVTI_ATTR_IKEY (1 << 1) #define IPVTI_ATTR_OKEY (1 << 2) #define IPVTI_ATTR_LOCAL (1 << 3) #define IPVTI_ATTR_REMOTE (1 << 4) struct ipvti_info { uint32_t link; uint32_t ikey; uint32_t okey; uint32_t local; uint32_t remote; uint32_t ipvti_mask; }; static struct nla_policy ipvti_policy[IFLA_GRE_MAX + 1] = { [IFLA_VTI_LINK] = { .type = NLA_U32 }, [IFLA_VTI_IKEY] = { .type = NLA_U32 }, [IFLA_VTI_OKEY] = { .type = NLA_U32 }, [IFLA_VTI_LOCAL] = { .type = NLA_U32 }, [IFLA_VTI_REMOTE] = { .type = NLA_U32 }, }; static int ipvti_alloc(struct rtnl_link *link) { struct ipvti_info *ipvti; if (link->l_info) memset(link->l_info, 0, sizeof(*ipvti)); else { ipvti = calloc(1, sizeof(*ipvti)); if (!ipvti) return -NLE_NOMEM; link->l_info = ipvti; } return 0; } static int ipvti_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_IPTUN_MAX + 1]; struct ipvti_info *ipvti; int err; NL_DBG(3, "Parsing IPVTI link info\n"); err = nla_parse_nested(tb, IFLA_GRE_MAX, data, ipvti_policy); if (err < 0) goto errout; err = ipvti_alloc(link); if (err < 0) goto errout; ipvti = link->l_info; if (tb[IFLA_VTI_LINK]) { ipvti->link = nla_get_u32(tb[IFLA_VTI_LINK]); ipvti->ipvti_mask |= IPVTI_ATTR_LINK; } if (tb[IFLA_VTI_IKEY]) { ipvti->ikey = nla_get_u32(tb[IFLA_VTI_IKEY]); ipvti->ipvti_mask |= IPVTI_ATTR_IKEY; } if (tb[IFLA_VTI_OKEY]) { ipvti->okey = nla_get_u32(tb[IFLA_VTI_OKEY]); ipvti->ipvti_mask |= IPVTI_ATTR_OKEY; } if (tb[IFLA_VTI_LOCAL]) { ipvti->local = nla_get_u32(tb[IFLA_VTI_LOCAL]); ipvti->ipvti_mask |= IPVTI_ATTR_LOCAL; } if (tb[IFLA_VTI_REMOTE]) { ipvti->remote = nla_get_u32(tb[IFLA_VTI_REMOTE]); ipvti->ipvti_mask |= IPVTI_ATTR_REMOTE; } err = 0; errout: return err; } static int ipvti_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct ipvti_info *ipvti = link->l_info; struct nlattr *data; data = nla_nest_start(msg, IFLA_INFO_DATA); if (!data) return -NLE_MSGSIZE; if (ipvti->ipvti_mask & IPVTI_ATTR_LINK) NLA_PUT_U32(msg, IFLA_VTI_LINK, ipvti->link); if (ipvti->ipvti_mask & IPVTI_ATTR_IKEY) NLA_PUT_U32(msg, IFLA_VTI_IKEY, ipvti->ikey); if (ipvti->ipvti_mask & IFLA_VTI_IKEY) NLA_PUT_U32(msg, IFLA_VTI_OKEY, ipvti->okey); if (ipvti->ipvti_mask & IPVTI_ATTR_LOCAL) NLA_PUT_U32(msg, IFLA_VTI_LOCAL, ipvti->local); if (ipvti->ipvti_mask & IPVTI_ATTR_REMOTE) NLA_PUT_U32(msg, IFLA_VTI_REMOTE, ipvti->remote); nla_nest_end(msg, data); nla_put_failure: return 0; } static void ipvti_free(struct rtnl_link *link) { struct ipvti_info *ipvti = link->l_info; free(ipvti); link->l_info = NULL; } static void ipvti_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { nl_dump(p, "ipvti : %s", link->l_name); } static void ipvti_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct ipvti_info *ipvti = link->l_info; char *name, addr[INET_ADDRSTRLEN]; struct rtnl_link *parent; if (ipvti->ipvti_mask & IPVTI_ATTR_LINK) { nl_dump(p, " link "); name = NULL; parent = link_lookup(link->ce_cache, ipvti->link); if (parent) name = rtnl_link_get_name(parent); if (name) nl_dump_line(p, "%s\n", name); else nl_dump_line(p, "%u\n", ipvti->link); } if (ipvti->ipvti_mask & IPVTI_ATTR_IKEY) { nl_dump(p, " ikey "); nl_dump_line(p, "%x\n",ipvti->ikey); } if (ipvti->ipvti_mask & IPVTI_ATTR_OKEY) { nl_dump(p, " okey "); nl_dump_line(p, "%x\n", ipvti->okey); } if (ipvti->ipvti_mask & IPVTI_ATTR_LOCAL) { nl_dump(p, " local "); if(inet_ntop(AF_INET, &ipvti->local, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(ipvti->local)); } if (ipvti->ipvti_mask & IPVTI_ATTR_REMOTE) { nl_dump(p, " remote "); if(inet_ntop(AF_INET, &ipvti->remote, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(ipvti->remote)); } } static int ipvti_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct ipvti_info *ipvti_dst, *ipvti_src = src->l_info; int err; dst->l_info = NULL; err = rtnl_link_set_type(dst, "vti"); if (err < 0) return err; ipvti_dst = dst->l_info; if (!ipvti_dst || !ipvti_src) BUG(); memcpy(ipvti_dst, ipvti_src, sizeof(struct ipvti_info)); return 0; } static struct rtnl_link_info_ops ipvti_info_ops = { .io_name = "vti", .io_alloc = ipvti_alloc, .io_parse = ipvti_parse, .io_dump = { [NL_DUMP_LINE] = ipvti_dump_line, [NL_DUMP_DETAILS] = ipvti_dump_details, }, .io_clone = ipvti_clone, .io_put_attrs = ipvti_put_attrs, .io_free = ipvti_free, }; #define IS_IPVTI_LINK_ASSERT(link) \ if ((link)->l_info_ops != &ipvti_info_ops) { \ APPBUG("Link is not a ipvti link. set type \vti\" first."); \ return -NLE_OPNOTSUPP; \ } struct rtnl_link *rtnl_link_ipvti_alloc(void) { struct rtnl_link *link; int err; link = rtnl_link_alloc(); if (!link) return NULL; err = rtnl_link_set_type(link, "vti"); if (err < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a IPVTI link * @arg link Link object * * @return True if link is a IPVTI link, otherwise 0 is returned. */ int rtnl_link_is_ipvti(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vti"); } /** * Create a new ipvti tunnel device * @arg sock netlink socket * @arg name name of the tunnel deviceL * * Creates a new ipvti tunnel device in the kernel * @return 0 on success or a negative error code */ int rtnl_link_ipvti_add(struct nl_sock *sk, const char *name) { struct rtnl_link *link; int err; link = rtnl_link_ipvti_alloc(); if (!link) return -NLE_NOMEM; if(name) rtnl_link_set_name(link, name); err = rtnl_link_add(sk, link, NLM_F_CREATE); rtnl_link_put(link); return err; } /** * Set IPVTI tunnel interface index * @arg link Link object * @arg index interface index * * @return 0 on success or a negative error code */ int rtnl_link_ipvti_set_link(struct rtnl_link *link, uint32_t index) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); ipvti->link = index; ipvti->ipvti_mask |= IPVTI_ATTR_LINK; return 0; } /** * Get IPVTI tunnel interface index * @arg link Link object * * @return interface index */ uint32_t rtnl_link_ipvti_get_link(struct rtnl_link *link) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); return ipvti->link; } /** * Set IPVTI tunnel set ikey * @arg link Link object * @arg ikey gre ikey * * @return 0 on success or a negative error code */ int rtnl_link_ipvti_set_ikey(struct rtnl_link *link, uint32_t ikey) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); ipvti->ikey = ikey; ipvti->ipvti_mask |= IPVTI_ATTR_IKEY; return 0; } /** * Get IPVTI tunnel ikey * @arg link Link object * * @return ikey */ uint32_t rtnl_link_ipvti_get_ikey(struct rtnl_link *link) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); return ipvti->ikey; } /** * Set IPVTI tunnel set okey * @arg link Link object * @arg okey gre okey * * @return 0 on success or a negative error code */ int rtnl_link_ipvti_set_okey(struct rtnl_link *link, uint32_t okey) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); ipvti->okey = okey; ipvti->ipvti_mask |= IPVTI_ATTR_OKEY; return 0; } /** * Get IPVTI tunnel okey * @arg link Link object * * @return okey value */ uint32_t rtnl_link_ipvti_get_okey(struct rtnl_link *link) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); return ipvti->okey; } /** * Set IPVTI tunnel local address * @arg link Link object * @arg addr local address * * @return 0 on success or a negative error code */ int rtnl_link_ipvti_set_local(struct rtnl_link *link, uint32_t addr) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); ipvti->local = addr; ipvti->ipvti_mask |= IPVTI_ATTR_LOCAL; return 0; } /** * Get IPVTI tunnel local address * @arg link Link object * * @return local address */ uint32_t rtnl_link_ipvti_get_local(struct rtnl_link *link) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); return ipvti->local; } /** * Set IPVTI tunnel remote address * @arg link Link object * @arg remote remote address * * @return 0 on success or a negative error code */ int rtnl_link_ipvti_set_remote(struct rtnl_link *link, uint32_t remote) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); ipvti->remote = remote; ipvti->ipvti_mask |= IPVTI_ATTR_REMOTE; return 0; } /** * Get IPVTI tunnel remote address * @arg link Link object * * @return remote address on success or a negative error code */ uint32_t rtnl_link_ipvti_get_remote(struct rtnl_link *link) { struct ipvti_info *ipvti = link->l_info; IS_IPVTI_LINK_ASSERT(link); return ipvti->remote; } static void __init ipvti_init(void) { rtnl_link_register_info(&ipvti_info_ops); } static void __exit ipvti_exit(void) { rtnl_link_unregister_info(&ipvti_info_ops); } libnl-3.2.29/lib/route/link/ipgre.c0000644000175000017500000004337713023014600013746 00000000000000/* * lib/route/link/ipgre.c IPGRE Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ /** * @ingroup link * @defgroup ipgre IPGRE * ipgre link module * * @details * \b Link Type Name: "ipgre" * * @route_doc{link_ipgre, IPGRE Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include #define IPGRE_ATTR_LINK (1 << 0) #define IPGRE_ATTR_IFLAGS (1 << 1) #define IPGRE_ATTR_OFLAGS (1 << 2) #define IPGRE_ATTR_IKEY (1 << 3) #define IPGRE_ATTR_OKEY (1 << 4) #define IPGRE_ATTR_LOCAL (1 << 5) #define IPGRE_ATTR_REMOTE (1 << 6) #define IPGRE_ATTR_TTL (1 << 7) #define IPGRE_ATTR_TOS (1 << 8) #define IPGRE_ATTR_PMTUDISC (1 << 9) struct ipgre_info { uint8_t ttl; uint8_t tos; uint8_t pmtudisc; uint16_t iflags; uint16_t oflags; uint32_t ikey; uint32_t okey; uint32_t link; uint32_t local; uint32_t remote; uint32_t ipgre_mask; }; static struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = { [IFLA_GRE_LINK] = { .type = NLA_U32 }, [IFLA_GRE_IFLAGS] = { .type = NLA_U16 }, [IFLA_GRE_OFLAGS] = { .type = NLA_U16 }, [IFLA_GRE_IKEY] = { .type = NLA_U32 }, [IFLA_GRE_OKEY] = { .type = NLA_U32 }, [IFLA_GRE_LOCAL] = { .type = NLA_U32 }, [IFLA_GRE_REMOTE] = { .type = NLA_U32 }, [IFLA_GRE_TTL] = { .type = NLA_U8 }, [IFLA_GRE_TOS] = { .type = NLA_U8 }, [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 }, }; static int ipgre_alloc(struct rtnl_link *link) { struct ipgre_info *ipgre; if (link->l_info) memset(link->l_info, 0, sizeof(*ipgre)); else { ipgre = calloc(1, sizeof(*ipgre)); if (!ipgre) return -NLE_NOMEM; link->l_info = ipgre; } return 0; } static int ipgre_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_IPTUN_MAX + 1]; struct ipgre_info *ipgre; int err; NL_DBG(3, "Parsing IPGRE link info\n"); err = nla_parse_nested(tb, IFLA_GRE_MAX, data, ipgre_policy); if (err < 0) goto errout; err = ipgre_alloc(link); if (err < 0) goto errout; ipgre = link->l_info; if (tb[IFLA_GRE_LINK]) { ipgre->link = nla_get_u32(tb[IFLA_GRE_LINK]); ipgre->ipgre_mask |= IPGRE_ATTR_LINK; } if (tb[IFLA_GRE_IFLAGS]) { ipgre->iflags = nla_get_u16(tb[IFLA_GRE_IFLAGS]); ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS; } if (tb[IFLA_GRE_OFLAGS]) { ipgre->oflags = nla_get_u16(tb[IFLA_GRE_OFLAGS]); ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS; } if (tb[IFLA_GRE_IKEY]) { ipgre->ikey = nla_get_u32(tb[IFLA_GRE_IKEY]); ipgre->ipgre_mask |= IPGRE_ATTR_IKEY; } if (tb[IFLA_GRE_OKEY]) { ipgre->okey = nla_get_u32(tb[IFLA_GRE_OKEY]); ipgre->ipgre_mask |= IPGRE_ATTR_OKEY; } if (tb[IFLA_GRE_LOCAL]) { ipgre->local = nla_get_u32(tb[IFLA_GRE_LOCAL]); ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL; } if (tb[IFLA_GRE_REMOTE]) { ipgre->remote = nla_get_u32(tb[IFLA_GRE_REMOTE]); ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE; } if (tb[IFLA_GRE_TTL]) { ipgre->ttl = nla_get_u8(tb[IFLA_GRE_TTL]); ipgre->ipgre_mask |= IPGRE_ATTR_TTL; } if (tb[IFLA_GRE_TOS]) { ipgre->tos = nla_get_u8(tb[IFLA_GRE_TOS]); ipgre->ipgre_mask |= IPGRE_ATTR_TOS; } if (tb[IFLA_GRE_PMTUDISC]) { ipgre->pmtudisc = nla_get_u8(tb[IFLA_GRE_PMTUDISC]); ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC; } err = 0; errout: return err; } static int ipgre_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; struct nlattr *data; data = nla_nest_start(msg, IFLA_INFO_DATA); if (!data) return -NLE_MSGSIZE; if (ipgre->ipgre_mask & IPGRE_ATTR_LINK) NLA_PUT_U32(msg, IFLA_GRE_LINK, ipgre->link); if (ipgre->ipgre_mask & IFLA_GRE_IFLAGS) NLA_PUT_U16(msg, IFLA_GRE_IFLAGS, ipgre->iflags); if (ipgre->ipgre_mask & IFLA_GRE_OFLAGS) NLA_PUT_U16(msg, IFLA_GRE_OFLAGS, ipgre->oflags); if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY) NLA_PUT_U32(msg, IFLA_GRE_IKEY, ipgre->ikey); if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY) NLA_PUT_U32(msg, IFLA_GRE_OKEY, ipgre->okey); if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL) NLA_PUT_U32(msg, IFLA_GRE_LOCAL, ipgre->local); if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE) NLA_PUT_U32(msg, IFLA_GRE_REMOTE, ipgre->remote); if (ipgre->ipgre_mask & IPGRE_ATTR_TTL) NLA_PUT_U8(msg, IFLA_GRE_TTL, ipgre->ttl); if (ipgre->ipgre_mask & IPGRE_ATTR_TOS) NLA_PUT_U8(msg, IFLA_GRE_TOS, ipgre->tos); if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC) NLA_PUT_U8(msg, IFLA_GRE_PMTUDISC, ipgre->pmtudisc); nla_nest_end(msg, data); nla_put_failure: return 0; } static void ipgre_free(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; free(ipgre); link->l_info = NULL; } static void ipgre_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { nl_dump(p, "ipgre : %s", link->l_name); } static void ipgre_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct ipgre_info *ipgre = link->l_info; char *name, addr[INET_ADDRSTRLEN]; struct rtnl_link *parent; if (ipgre->ipgre_mask & IPGRE_ATTR_LINK) { nl_dump(p, " link "); name = NULL; parent = link_lookup(link->ce_cache, ipgre->link); if (parent) name = rtnl_link_get_name(parent); if (name) nl_dump_line(p, "%s\n", name); else nl_dump_line(p, "%u\n", ipgre->link); } if (ipgre->ipgre_mask & IPGRE_ATTR_IFLAGS) { nl_dump(p, " iflags "); nl_dump_line(p, "%x\n", ipgre->iflags); } if (ipgre->ipgre_mask & IPGRE_ATTR_OFLAGS) { nl_dump(p, " oflags "); nl_dump_line(p, "%x\n", ipgre->oflags); } if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY) { nl_dump(p, " ikey "); nl_dump_line(p, "%x\n",ipgre->ikey); } if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY) { nl_dump(p, " okey "); nl_dump_line(p, "%x\n", ipgre->okey); } if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL) { nl_dump(p, " local "); if(inet_ntop(AF_INET, &ipgre->local, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(ipgre->local)); } if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE) { nl_dump(p, " remote "); if(inet_ntop(AF_INET, &ipgre->remote, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(ipgre->remote)); } if (ipgre->ipgre_mask & IPGRE_ATTR_TTL) { nl_dump(p, " ttl "); nl_dump_line(p, "%u\n", ipgre->ttl); } if (ipgre->ipgre_mask & IPGRE_ATTR_TOS) { nl_dump(p, " tos "); nl_dump_line(p, "%u\n", ipgre->tos); } if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC) { nl_dump(p, " pmtudisc "); nl_dump_line(p, "enabled (%#x)\n", ipgre->pmtudisc); } } static int ipgre_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct ipgre_info *ipgre_dst, *ipgre_src = src->l_info; int err; dst->l_info = NULL; err = rtnl_link_set_type(dst, "gre"); if (err < 0) return err; ipgre_dst = dst->l_info; if (!ipgre_dst || !ipgre_src) BUG(); memcpy(ipgre_dst, ipgre_src, sizeof(struct ipgre_info)); return 0; } static int ipgretap_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct ipgre_info *ipgre_dst, *ipgre_src = src->l_info; int err; dst->l_info = NULL; err = rtnl_link_set_type(dst, "gretap"); if (err < 0) return err; ipgre_dst = dst->l_info; if (!ipgre_dst || !ipgre_src) BUG(); memcpy(ipgre_dst, ipgre_src, sizeof(struct ipgre_info)); return 0; } static struct rtnl_link_info_ops ipgre_info_ops = { .io_name = "gre", .io_alloc = ipgre_alloc, .io_parse = ipgre_parse, .io_dump = { [NL_DUMP_LINE] = ipgre_dump_line, [NL_DUMP_DETAILS] = ipgre_dump_details, }, .io_clone = ipgre_clone, .io_put_attrs = ipgre_put_attrs, .io_free = ipgre_free, }; static struct rtnl_link_info_ops ipgretap_info_ops = { .io_name = "gretap", .io_alloc = ipgre_alloc, .io_parse = ipgre_parse, .io_dump = { [NL_DUMP_LINE] = ipgre_dump_line, [NL_DUMP_DETAILS] = ipgre_dump_details, }, .io_clone = ipgretap_clone, .io_put_attrs = ipgre_put_attrs, .io_free = ipgre_free, }; #define IS_IPGRE_LINK_ASSERT(link) \ if ((link)->l_info_ops != &ipgre_info_ops && \ (link)->l_info_ops != &ipgretap_info_ops) { \ APPBUG("Link is not a ipgre link. set type \"gre/gretap\" first.");\ return -NLE_OPNOTSUPP; \ } struct rtnl_link *rtnl_link_ipgre_alloc(void) { struct rtnl_link *link; int err; link = rtnl_link_alloc(); if (!link) return NULL; err = rtnl_link_set_type(link, "gre"); if (err < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a IPGRE link * @arg link Link object * * @return True if link is a IPGRE link, otherwise 0 is returned. */ int rtnl_link_is_ipgre(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "gre"); } /** * Create a new IPGRE tunnel device * @arg sock netlink socket * @arg name name of the tunnel deviceL * * Creates a new ipip tunnel device in the kernel * @return 0 on success or a negative error code */ int rtnl_link_ipgre_add(struct nl_sock *sk, const char *name) { struct rtnl_link *link; int err; link = rtnl_link_ipgre_alloc(); if (!link) return -NLE_NOMEM; if(name) rtnl_link_set_name(link, name); err = rtnl_link_add(sk, link, NLM_F_CREATE); rtnl_link_put(link); return err; } struct rtnl_link *rtnl_link_ipgretap_alloc(void) { struct rtnl_link *link; int err; link = rtnl_link_alloc(); if (!link) return NULL; err = rtnl_link_set_type(link, "gretap"); if (err < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a IPGRETAP link * @arg link Link object * * @return True if link is a IPGRETAP link, otherwise 0 is returned. */ int rtnl_link_is_ipgretap(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "gretap"); } /** * Create a new IPGRETAP tunnel device * @arg sock netlink socket * @arg name name of the tunnel deviceL * * Creates a new IPGRETAP tunnel device in the kernel * @return 0 on success or a negative error code */ int rtnl_link_ipgretap_add(struct nl_sock *sk, const char *name) { struct rtnl_link *link; int err; link = rtnl_link_ipgretap_alloc(); if (!link) return -NLE_NOMEM; if(name) rtnl_link_set_name(link, name); err = rtnl_link_add(sk, link, NLM_F_CREATE); rtnl_link_put(link); return err; } /** * Set IPGRE tunnel interface index * @arg link Link object * @arg index interface index * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_link(struct rtnl_link *link, uint32_t index) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->link = index; ipgre->ipgre_mask |= IPGRE_ATTR_LINK; return 0; } /** * Get IPGRE tunnel interface index * @arg link Link object * * @return interface index */ uint32_t rtnl_link_ipgre_get_link(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->link; } /** * Set IPGRE tunnel set iflags * @arg link Link object * @arg iflags gre iflags * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_iflags(struct rtnl_link *link, uint16_t iflags) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->iflags = iflags; ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS; return 0; } /** * Get IPGRE tunnel iflags * @arg link Link object * * @return iflags */ uint16_t rtnl_link_ipgre_get_iflags(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->iflags; } /** * Set IPGRE tunnel set oflags * @arg link Link object * @arg iflags gre oflags * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_oflags(struct rtnl_link *link, uint16_t oflags) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->oflags = oflags; ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS; return 0; } /** * Get IPGRE tunnel oflags * @arg link Link object * * @return oflags */ uint16_t rtnl_link_ipgre_get_oflags(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->oflags; } /** * Set IPGRE tunnel set ikey * @arg link Link object * @arg ikey gre ikey * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_ikey(struct rtnl_link *link, uint32_t ikey) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->ikey = ikey; ipgre->ipgre_mask |= IPGRE_ATTR_IKEY; return 0; } /** * Get IPGRE tunnel ikey * @arg link Link object * * @return ikey */ uint32_t rtnl_link_ipgre_get_ikey(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->ikey; } /** * Set IPGRE tunnel set okey * @arg link Link object * @arg okey gre okey * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_okey(struct rtnl_link *link, uint32_t okey) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->okey = okey; ipgre->ipgre_mask |= IPGRE_ATTR_OKEY; return 0; } /** * Get IPGRE tunnel okey * @arg link Link object * * @return okey value */ uint32_t rtnl_link_ipgre_get_okey(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->okey; } /** * Set IPGRE tunnel local address * @arg link Link object * @arg addr local address * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_local(struct rtnl_link *link, uint32_t addr) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->local = addr; ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL; return 0; } /** * Get IPGRE tunnel local address * @arg link Link object * * @return local address */ uint32_t rtnl_link_ipgre_get_local(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->local; } /** * Set IPGRE tunnel remote address * @arg link Link object * @arg remote remote address * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_remote(struct rtnl_link *link, uint32_t remote) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->remote = remote; ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE; return 0; } /** * Get IPGRE tunnel remote address * @arg link Link object * * @return remote address on success or a negative error code */ uint32_t rtnl_link_ipgre_get_remote(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->remote; } /** * Set IPGRE tunnel ttl * @arg link Link object * @arg ttl tunnel ttl * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_ttl(struct rtnl_link *link, uint8_t ttl) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->ttl = ttl; ipgre->ipgre_mask |= IPGRE_ATTR_TTL; return 0; } /** * Set IPGRE tunnel ttl * @arg link Link object * * @return ttl value */ uint8_t rtnl_link_ipgre_get_ttl(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->ttl; } /** * Set IPGRE tunnel tos * @arg link Link object * @arg tos tunnel tos * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_tos(struct rtnl_link *link, uint8_t tos) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->tos = tos; ipgre->ipgre_mask |= IPGRE_ATTR_TOS; return 0; } /** * Get IPGRE tunnel tos * @arg link Link object * * @return tos value */ uint8_t rtnl_link_ipgre_get_tos(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->tos; } /** * Set IPGRE tunnel path MTU discovery * @arg link Link object * @arg pmtudisc path MTU discovery * * @return 0 on success or a negative error code */ int rtnl_link_ipgre_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); ipgre->pmtudisc = pmtudisc; ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC; return 0; } /** * Get IPGRE path MTU discovery * @arg link Link object * * @return pmtudisc value */ uint8_t rtnl_link_ipgre_get_pmtudisc(struct rtnl_link *link) { struct ipgre_info *ipgre = link->l_info; IS_IPGRE_LINK_ASSERT(link); return ipgre->pmtudisc; } uint8_t rtnl_link_get_pmtudisc(struct rtnl_link *link) { /* rtnl_link_ipgre_get_pmtudisc() was wrongly named. Keep this * to preserve ABI. */ return rtnl_link_ipgre_get_pmtudisc (link); } static void __init ipgre_init(void) { rtnl_link_register_info(&ipgre_info_ops); rtnl_link_register_info(&ipgretap_info_ops); } static void __exit ipgre_exit(void) { rtnl_link_unregister_info(&ipgre_info_ops); rtnl_link_unregister_info(&ipgretap_info_ops); } libnl-3.2.29/lib/route/link/bridge.c0000644000175000017500000005621613023014600014070 00000000000000/* * lib/route/link/bridge.c AF_BRIDGE link support * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2013 Thomas Graf */ /** * @ingroup link * @defgroup bridge Bridging * * @details * @{ */ #include #include #include #include #include #include #include #define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ /** @cond SKIP */ #define BRIDGE_ATTR_PORT_STATE (1 << 0) #define BRIDGE_ATTR_PRIORITY (1 << 1) #define BRIDGE_ATTR_COST (1 << 2) #define BRIDGE_ATTR_FLAGS (1 << 3) #define BRIDGE_ATTR_PORT_VLAN (1 << 4) #define BRIDGE_ATTR_HWMODE (1 << 5) #define BRIDGE_ATTR_SELF (1 << 6) #define PRIV_FLAG_NEW_ATTRS (1 << 0) struct bridge_data { uint8_t b_port_state; uint8_t b_priv_flags; /* internal flags */ uint16_t b_hwmode; uint16_t b_priority; uint16_t b_self; /* here for comparison reasons */ uint32_t b_cost; uint32_t b_flags; uint32_t b_flags_mask; uint32_t ce_mask; /* HACK to support attr macros */ struct rtnl_link_bridge_vlan vlan_info; }; static void set_bit(unsigned nr, uint32_t *addr) { if (nr < RTNL_LINK_BRIDGE_VLAN_BITMAP_MAX) addr[nr / 32] |= (((uint32_t) 1) << (nr % 32)); } static int find_next_bit(int i, uint32_t x) { int j; if (i >= 32) return -1; /* find first bit */ if (i < 0) return __builtin_ffs(x); /* mask off prior finds to get next */ j = __builtin_ffs(x >> i); return j ? j + i : 0; } static struct rtnl_link_af_ops bridge_ops; #define IS_BRIDGE_LINK_ASSERT(link) \ if (!rtnl_link_is_bridge(link)) { \ APPBUG("A function was expecting a link object of type bridge."); \ return -NLE_OPNOTSUPP; \ } static inline struct bridge_data *bridge_data(struct rtnl_link *link) { return rtnl_link_af_data(link, &bridge_ops); } static void *bridge_alloc(struct rtnl_link *link) { return calloc(1, sizeof(struct bridge_data)); } static void *bridge_clone(struct rtnl_link *link, void *data) { struct bridge_data *bd; if ((bd = bridge_alloc(link))) memcpy(bd, data, sizeof(*bd)); return bd; } static void bridge_free(struct rtnl_link *link, void *data) { free(data); } static struct nla_policy br_attrs_policy[IFLA_BRPORT_MAX+1] = { [IFLA_BRPORT_STATE] = { .type = NLA_U8 }, [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 }, [IFLA_BRPORT_COST] = { .type = NLA_U32 }, [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, [IFLA_BRPORT_FAST_LEAVE] = { .type = NLA_U8 }, [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, [IFLA_BRPORT_LEARNING_SYNC] = { .type = NLA_U8 }, [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, }; static void check_flag(struct rtnl_link *link, struct nlattr *attrs[], int type, int flag) { if (attrs[type] && nla_get_u8(attrs[type])) rtnl_link_bridge_set_flags(link, flag); } static int bridge_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, void *data) { struct bridge_data *bd = data; struct nlattr *br_attrs[IFLA_BRPORT_MAX+1]; int err; /* Backwards compatibility */ if (!nla_is_nested(attr)) { if (nla_len(attr) < 1) return -NLE_RANGE; bd->b_port_state = nla_get_u8(attr); bd->ce_mask |= BRIDGE_ATTR_PORT_STATE; return 0; } if ((err = nla_parse_nested(br_attrs, IFLA_BRPORT_MAX, attr, br_attrs_policy)) < 0) return err; bd->b_priv_flags |= PRIV_FLAG_NEW_ATTRS; if (br_attrs[IFLA_BRPORT_STATE]) { bd->b_port_state = nla_get_u8(br_attrs[IFLA_BRPORT_STATE]); bd->ce_mask |= BRIDGE_ATTR_PORT_STATE; } if (br_attrs[IFLA_BRPORT_PRIORITY]) { bd->b_priority = nla_get_u16(br_attrs[IFLA_BRPORT_PRIORITY]); bd->ce_mask |= BRIDGE_ATTR_PRIORITY; } if (br_attrs[IFLA_BRPORT_COST]) { bd->b_cost = nla_get_u32(br_attrs[IFLA_BRPORT_COST]); bd->ce_mask |= BRIDGE_ATTR_COST; } check_flag(link, br_attrs, IFLA_BRPORT_MODE, RTNL_BRIDGE_HAIRPIN_MODE); check_flag(link, br_attrs, IFLA_BRPORT_GUARD, RTNL_BRIDGE_BPDU_GUARD); check_flag(link, br_attrs, IFLA_BRPORT_PROTECT, RTNL_BRIDGE_ROOT_BLOCK); check_flag(link, br_attrs, IFLA_BRPORT_FAST_LEAVE, RTNL_BRIDGE_FAST_LEAVE); check_flag(link, br_attrs, IFLA_BRPORT_UNICAST_FLOOD, RTNL_BRIDGE_UNICAST_FLOOD); check_flag(link, br_attrs, IFLA_BRPORT_LEARNING, RTNL_BRIDGE_LEARNING); check_flag(link, br_attrs, IFLA_BRPORT_LEARNING_SYNC, RTNL_BRIDGE_LEARNING_SYNC); return 0; } static int bridge_parse_af_full(struct rtnl_link *link, struct nlattr *attr_full, void *data) { struct bridge_data *bd = data; struct bridge_vlan_info *vinfo = NULL; uint16_t vid_range_start = 0; uint16_t vid_range_flags = -1; struct nlattr *attr; int remaining; nla_for_each_nested(attr, attr_full, remaining) { if (nla_type(attr) == IFLA_BRIDGE_MODE) { bd->b_hwmode = nla_get_u16(attr); bd->ce_mask |= BRIDGE_ATTR_HWMODE; } else if (nla_type(attr) != IFLA_BRIDGE_VLAN_INFO) continue; if (nla_len(attr) != sizeof(struct bridge_vlan_info)) return -EINVAL; vinfo = nla_data(attr); if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK) return -EINVAL; if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) { vid_range_start = vinfo->vid; vid_range_flags = (vinfo->flags ^ BRIDGE_VLAN_INFO_RANGE_BEGIN); continue; } if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) { /* sanity check the range flags */ if (vid_range_flags != (vinfo->flags ^ BRIDGE_VLAN_INFO_RANGE_END)) { NL_DBG(1, "VLAN range flags differ; can not handle it.\n"); return -EINVAL; } } else { vid_range_start = vinfo->vid; } for (; vid_range_start <= vinfo->vid; vid_range_start++) { if (vinfo->flags & BRIDGE_VLAN_INFO_PVID) bd->vlan_info.pvid = vinfo->vid; if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED) set_bit(vid_range_start, bd->vlan_info.untagged_bitmap); set_bit(vid_range_start, bd->vlan_info.vlan_bitmap); bd->ce_mask |= BRIDGE_ATTR_PORT_VLAN; } vid_range_flags = -1; } return 0; } static int bridge_fill_af(struct rtnl_link *link, struct nl_msg *msg, void *data) { struct bridge_data *bd = data; if ((bd->ce_mask & BRIDGE_ATTR_SELF)||(bd->ce_mask & BRIDGE_ATTR_HWMODE)) NLA_PUT_U16(msg, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF); if (bd->ce_mask & BRIDGE_ATTR_HWMODE) NLA_PUT_U16(msg, IFLA_BRIDGE_MODE, bd->b_hwmode); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int bridge_fill_pi(struct rtnl_link *link, struct nl_msg *msg, void *data) { struct bridge_data *bd = data; if (bd->ce_mask & BRIDGE_ATTR_FLAGS) { if (bd->b_flags_mask & RTNL_BRIDGE_BPDU_GUARD) { NLA_PUT_U8(msg, IFLA_BRPORT_GUARD, bd->b_flags & RTNL_BRIDGE_BPDU_GUARD); } if (bd->b_flags_mask & RTNL_BRIDGE_HAIRPIN_MODE) { NLA_PUT_U8(msg, IFLA_BRPORT_MODE, bd->b_flags & RTNL_BRIDGE_HAIRPIN_MODE); } if (bd->b_flags_mask & RTNL_BRIDGE_FAST_LEAVE) { NLA_PUT_U8(msg, IFLA_BRPORT_FAST_LEAVE, bd->b_flags & RTNL_BRIDGE_FAST_LEAVE); } if (bd->b_flags_mask & RTNL_BRIDGE_ROOT_BLOCK) { NLA_PUT_U8(msg, IFLA_BRPORT_PROTECT, bd->b_flags & RTNL_BRIDGE_ROOT_BLOCK); } if (bd->b_flags_mask & RTNL_BRIDGE_UNICAST_FLOOD) { NLA_PUT_U8(msg, IFLA_BRPORT_UNICAST_FLOOD, bd->b_flags & RTNL_BRIDGE_UNICAST_FLOOD); } if (bd->b_flags_mask & RTNL_BRIDGE_LEARNING) { NLA_PUT_U8(msg, IFLA_BRPORT_LEARNING, bd->b_flags & RTNL_BRIDGE_LEARNING); } if (bd->b_flags_mask & RTNL_BRIDGE_LEARNING_SYNC) { NLA_PUT_U8(msg, IFLA_BRPORT_LEARNING_SYNC, bd->b_flags & RTNL_BRIDGE_LEARNING_SYNC); } } if (bd->ce_mask & BRIDGE_ATTR_COST) NLA_PUT_U32(msg, IFLA_BRPORT_COST, bd->b_cost); if (bd->ce_mask & BRIDGE_ATTR_PRIORITY) NLA_PUT_U16(msg, IFLA_BRPORT_PRIORITY, bd->b_priority); if (bd->ce_mask & BRIDGE_ATTR_PORT_STATE) NLA_PUT_U8(msg, IFLA_BRPORT_STATE, bd->b_port_state); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int bridge_get_af(struct nl_msg *msg, uint32_t *ext_filter_mask) { *ext_filter_mask |= RTEXT_FILTER_BRVLAN; return 0; } static void dump_bitmap(struct nl_dump_params *p, const uint32_t *b) { int i = -1, j, k; int start = -1, prev = -1; int done, found = 0; for (k = 0; k < RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN; k++) { int base_bit; uint32_t a = b[k]; base_bit = k * 32; i = -1; done = 0; while (!done) { j = find_next_bit(i, a); if (j > 0) { /* first hit of any bit */ if (start < 0 && prev < 0) { start = prev = j - 1 + base_bit; goto next; } /* this bit is a continuation of prior bits */ if (j - 2 + base_bit == prev) { prev++; goto next; } } else done = 1; if (start >= 0) { found++; if (done && k < RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN - 1) break; nl_dump(p, " %d", start); if (start != prev) nl_dump(p, "-%d", prev); if (done) break; } if (j > 0) start = prev = j - 1 + base_bit; next: i = j; } } if (!found) nl_dump(p, " "); return; } static void rtnl_link_bridge_dump_vlans(struct nl_dump_params *p, struct bridge_data *bd) { nl_dump(p, "pvid %u", bd->vlan_info.pvid); nl_dump(p, " all vlans:"); dump_bitmap(p, bd->vlan_info.vlan_bitmap); nl_dump(p, " untagged vlans:"); dump_bitmap(p, bd->vlan_info.untagged_bitmap); } static void bridge_dump_details(struct rtnl_link *link, struct nl_dump_params *p, void *data) { struct bridge_data *bd = data; nl_dump_line(p, " bridge: "); if (bd->ce_mask & BRIDGE_ATTR_PORT_STATE) nl_dump(p, "port-state %u ", bd->b_port_state); if (bd->ce_mask & BRIDGE_ATTR_PRIORITY) nl_dump(p, "prio %u ", bd->b_priority); if (bd->ce_mask & BRIDGE_ATTR_COST) nl_dump(p, "cost %u ", bd->b_cost); if (bd->ce_mask & BRIDGE_ATTR_HWMODE) { char hbuf[32]; rtnl_link_bridge_hwmode2str(bd->b_hwmode, hbuf, sizeof(hbuf)); nl_dump(p, "hwmode %s", hbuf); } if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN) rtnl_link_bridge_dump_vlans(p, bd); if (bd->ce_mask & BRIDGE_ATTR_FLAGS) { char buf[256]; rtnl_link_bridge_flags2str(bd->b_flags & bd->b_flags_mask, buf, sizeof(buf)); nl_dump(p, "%s", buf); } nl_dump(p, "\n"); } static int bridge_compare(struct rtnl_link *_a, struct rtnl_link *_b, int family, uint32_t attrs, int flags) { struct bridge_data *a = bridge_data(_a); struct bridge_data *b = bridge_data(_b); int diff = 0; #define BRIDGE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, BRIDGE_ATTR_##ATTR, a, b, EXPR) diff |= BRIDGE_DIFF(PORT_STATE, a->b_port_state != b->b_port_state); diff |= BRIDGE_DIFF(PRIORITY, a->b_priority != b->b_priority); diff |= BRIDGE_DIFF(COST, a->b_cost != b->b_cost); diff |= BRIDGE_DIFF(PORT_VLAN, memcmp(&a->vlan_info, &b->vlan_info, sizeof(struct rtnl_link_bridge_vlan))); diff |= BRIDGE_DIFF(HWMODE, a->b_hwmode != b->b_hwmode); diff |= BRIDGE_DIFF(SELF, a->b_self != b->b_self); if (flags & LOOSE_COMPARISON) diff |= BRIDGE_DIFF(FLAGS, (a->b_flags ^ b->b_flags) & b->b_flags_mask); else diff |= BRIDGE_DIFF(FLAGS, a->b_flags != b->b_flags); #undef BRIDGE_DIFF return diff; } /** @endcond */ /** * Allocate link object of type bridge * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_bridge_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "bridge")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Create a new kernel bridge device * @arg sk netlink socket * @arg name name of the bridge device or NULL * * Creates a new bridge device in the kernel. If no name is * provided, the kernel will automatically pick a name of the * form "type%d" (e.g. bridge0, vlan1, etc.) * * @return 0 on success or a negative error code */ int rtnl_link_bridge_add(struct nl_sock *sk, const char *name) { int err; struct rtnl_link *link; if (!(link = rtnl_link_bridge_alloc())) return -NLE_NOMEM; if(name) rtnl_link_set_name(link, name); err = rtnl_link_add(sk, link, NLM_F_CREATE); rtnl_link_put(link); return err; } /** * Check if a link is a bridge * @arg link Link object * * @return 1 if the link is a bridge, 0 otherwise. */ int rtnl_link_is_bridge(struct rtnl_link *link) { return link->l_family == AF_BRIDGE && link->l_af_ops == &bridge_ops; } /** * Check if bridge has extended information * @arg link Link object of type bridge * * Checks if the bridge object has been constructed based on * information that is only available in newer kernels. This * affectes the following functions: * - rtnl_link_bridge_get_cost() * - rtnl_link_bridge_get_priority() * - rtnl_link_bridge_get_flags() * * @return 1 if extended information is available, otherwise 0 is returned. */ int rtnl_link_bridge_has_ext_info(struct rtnl_link *link) { struct bridge_data *bd; if (!rtnl_link_is_bridge(link)) return 0; bd = bridge_data(link); return !!(bd->b_priv_flags & PRIV_FLAG_NEW_ATTRS); } /** * Set Spanning Tree Protocol (STP) port state * @arg link Link object of type bridge * @arg state New STP port state * * The value of state must be one of the following: * - BR_STATE_DISABLED * - BR_STATE_LISTENING * - BR_STATE_LEARNING * - BR_STATE_FORWARDING * - BR_STATE_BLOCKING * * @see rtnl_link_bridge_get_port_state() * * @return 0 on success or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge * @retval -NLE_INVAL Invalid state value (0..BR_STATE_BLOCKING) */ int rtnl_link_bridge_set_port_state(struct rtnl_link *link, uint8_t state) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); if (state > BR_STATE_BLOCKING) return -NLE_INVAL; bd->b_port_state = state; bd->ce_mask |= BRIDGE_ATTR_PORT_STATE; return 0; } /** * Get Spanning Tree Protocol (STP) port state * @arg link Link object of type bridge * * @see rtnl_link_bridge_set_port_state() * * @return The STP port state or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge */ int rtnl_link_bridge_get_port_state(struct rtnl_link *link) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); return bd->b_port_state; } /** * Set priority * @arg link Link object of type bridge * @arg prio Bridge priority * * @see rtnl_link_bridge_get_priority() * * @return 0 on success or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge */ int rtnl_link_bridge_set_priority(struct rtnl_link *link, uint16_t prio) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); bd->b_priority = prio; bd->ce_mask |= BRIDGE_ATTR_PRIORITY; return 0; } /** * Get priority * @arg link Link object of type bridge * * @see rtnl_link_bridge_set_priority() * * @return 0 on success or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge */ int rtnl_link_bridge_get_priority(struct rtnl_link *link) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); return bd->b_priority; } /** * Set Spanning Tree Protocol (STP) path cost * @arg link Link object of type bridge * @arg cost New STP path cost value * * @see rtnl_link_bridge_get_cost() * * @return The bridge priority or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge */ int rtnl_link_bridge_set_cost(struct rtnl_link *link, uint32_t cost) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); bd->b_cost = cost; bd->ce_mask |= BRIDGE_ATTR_COST; return 0; } /** * Get Spanning Tree Protocol (STP) path cost * @arg link Link object of type bridge * @arg cost Pointer to store STP cost value * * @see rtnl_link_bridge_set_cost() * * @return 0 on success or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge * @retval -NLE_INVAL `cost` is not a valid pointer */ int rtnl_link_bridge_get_cost(struct rtnl_link *link, uint32_t *cost) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); if (!cost) return -NLE_INVAL; *cost = bd->b_cost; return 0; } /** * Unset flags * @arg link Link object of type bridge * @arg flags Bridging flags to unset * * @see rtnl_link_bridge_set_flags() * @see rtnl_link_bridge_get_flags() * * @return 0 on success or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge */ int rtnl_link_bridge_unset_flags(struct rtnl_link *link, unsigned int flags) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); bd->b_flags_mask |= flags; bd->b_flags &= ~flags; bd->ce_mask |= BRIDGE_ATTR_FLAGS; return 0; } /** * Set flags * @arg link Link object of type bridge * @arg flags Bridging flags to set * * Valid flags are: * - RTNL_BRIDGE_HAIRPIN_MODE * - RTNL_BRIDGE_BPDU_GUARD * - RTNL_BRIDGE_ROOT_BLOCK * - RTNL_BRIDGE_FAST_LEAVE * - RTNL_BRIDGE_UNICAST_FLOOD * - RTNL_BRIDGE_LEARNING * - RTNL_BRIDGE_LEARNING_SYNC * * @see rtnl_link_bridge_unset_flags() * @see rtnl_link_bridge_get_flags() * * @return 0 on success or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge */ int rtnl_link_bridge_set_flags(struct rtnl_link *link, unsigned int flags) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); bd->b_flags_mask |= flags; bd->b_flags |= flags; bd->ce_mask |= BRIDGE_ATTR_FLAGS; return 0; } /** * Get flags * @arg link Link object of type bridge * * @see rtnl_link_bridge_set_flags() * @see rtnl_link_bridge_unset_flags() * * @return Flags or a negative error code. * @retval -NLE_OPNOTSUPP Link is not a bridge */ int rtnl_link_bridge_get_flags(struct rtnl_link *link) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); return bd->b_flags; } /** * Set link change type to self * @arg link Link Object of type bridge * * This will set the bridge change flag to self, meaning that changes to * be applied with this link object will be applied directly to the physical * device in a bridge instead of the virtual device. * * @return 0 on success or negative error code * @return -NLE_OPNOTSUP Link is not a bridge */ int rtnl_link_bridge_set_self(struct rtnl_link *link) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); bd->b_self |= 1; bd->ce_mask |= BRIDGE_ATTR_SELF; return 0; } /** * Get hardware mode * @arg link Link object of type bridge * @arg hwmode Output argument. * * @see rtnl_link_bridge_set_hwmode() * * @return 0 if hardware mode is present and returned in hwmode * @return -NLE_NOATTR if hardware mode is not present * @return -NLE_OPNOTSUP Link is not a bridge */ int rtnl_link_bridge_get_hwmode(struct rtnl_link *link, uint16_t *hwmode) { struct bridge_data *bd = bridge_data(link); IS_BRIDGE_LINK_ASSERT(link); if (!(bd->ce_mask & BRIDGE_ATTR_HWMODE)) return -NLE_NOATTR; *hwmode = bd->b_hwmode; return 0; } /** * Set hardware mode * @arg link Link object of type bridge * @arg hwmode Hardware mode to set on link * * This will set the hardware mode of a link when it supports hardware * offloads for bridging. * @see rtnl_link_bridge_get_hwmode() * * Valid modes are: * - RTNL_BRIDGE_HWMODE_VEB * - RTNL_BRIDGE_HWMODE_VEPA * * When setting hardware mode, the change type will be set to self. * @see rtnl_link_bridge_set_self() * * @return 0 on success or negative error code * @return -NLE_OPNOTSUP Link is not a bridge * @return -NLE_INVAL when specified hwmode is unsupported. */ int rtnl_link_bridge_set_hwmode(struct rtnl_link *link, uint16_t hwmode) { int err; struct bridge_data *bd = bridge_data(link); if (hwmode > RTNL_BRIDGE_HWMODE_MAX) return -NLE_INVAL; if ((err = rtnl_link_bridge_set_self(link)) < 0) return err; bd->b_hwmode = hwmode; bd->ce_mask |= BRIDGE_ATTR_HWMODE; return 0; } static const struct trans_tbl bridge_flags[] = { __ADD(RTNL_BRIDGE_HAIRPIN_MODE, hairpin_mode), __ADD(RTNL_BRIDGE_BPDU_GUARD, bpdu_guard), __ADD(RTNL_BRIDGE_ROOT_BLOCK, root_block), __ADD(RTNL_BRIDGE_FAST_LEAVE, fast_leave), __ADD(RTNL_BRIDGE_UNICAST_FLOOD, flood), __ADD(RTNL_BRIDGE_LEARNING, learning), __ADD(RTNL_BRIDGE_LEARNING_SYNC, learning_sync), }; /** * @name Flag Translation * @{ */ char *rtnl_link_bridge_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, bridge_flags, ARRAY_SIZE(bridge_flags)); } int rtnl_link_bridge_str2flags(const char *name) { return __str2flags(name, bridge_flags, ARRAY_SIZE(bridge_flags)); } /** @} */ static const struct trans_tbl port_states[] = { __ADD(BR_STATE_DISABLED, disabled), __ADD(BR_STATE_LISTENING, listening), __ADD(BR_STATE_LEARNING, learning), __ADD(BR_STATE_FORWARDING, forwarding), __ADD(BR_STATE_BLOCKING, blocking), }; /** * @name Port State Translation * @{ */ char *rtnl_link_bridge_portstate2str(int st, char *buf, size_t len) { return __type2str(st, buf, len, port_states, ARRAY_SIZE(port_states)); } int rtnl_link_bridge_str2portstate(const char *name) { return __str2type(name, port_states, ARRAY_SIZE(port_states)); } /** @} */ static const struct trans_tbl hw_modes[] = { __ADD(RTNL_BRIDGE_HWMODE_VEB, veb), __ADD(RTNL_BRIDGE_HWMODE_VEPA, vepa), __ADD(RTNL_BRIDGE_HWMODE_UNDEF, undef), }; /** * @name Hardware Mode Translation * @{ */ char *rtnl_link_bridge_hwmode2str(uint16_t st, char *buf, size_t len) { return __type2str(st, buf, len, hw_modes, ARRAY_SIZE(hw_modes)); } uint16_t rtnl_link_bridge_str2hwmode(const char *name) { return __str2type(name, hw_modes, ARRAY_SIZE(hw_modes)); } /** @} */ int rtnl_link_bridge_pvid(struct rtnl_link *link) { struct bridge_data *bd; IS_BRIDGE_LINK_ASSERT(link); bd = link->l_af_data[AF_BRIDGE]; if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN) return (int) bd->vlan_info.pvid; return -EINVAL; } int rtnl_link_bridge_has_vlan(struct rtnl_link *link) { struct bridge_data *bd; int i; IS_BRIDGE_LINK_ASSERT(link); bd = link->l_af_data[AF_BRIDGE]; if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN) { if (bd->vlan_info.pvid) return 1; for (i = 0; i < RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN; ++i) { if (bd->vlan_info.vlan_bitmap[i] || bd->vlan_info.untagged_bitmap[i]) return 1; } } return 0; } struct rtnl_link_bridge_vlan *rtnl_link_bridge_get_port_vlan(struct rtnl_link *link) { struct bridge_data *data; if (!rtnl_link_is_bridge(link)) return NULL; data = link->l_af_data[AF_BRIDGE]; if (data && (data->ce_mask & BRIDGE_ATTR_PORT_VLAN)) return &data->vlan_info; return NULL; } static struct rtnl_link_af_ops bridge_ops = { .ao_family = AF_BRIDGE, .ao_alloc = &bridge_alloc, .ao_clone = &bridge_clone, .ao_free = &bridge_free, .ao_parse_protinfo = &bridge_parse_protinfo, .ao_dump[NL_DUMP_DETAILS] = &bridge_dump_details, .ao_compare = &bridge_compare, .ao_parse_af_full = &bridge_parse_af_full, .ao_get_af = &bridge_get_af, .ao_fill_af = &bridge_fill_af, .ao_fill_pi = &bridge_fill_pi, .ao_fill_pi_flags = NLA_F_NESTED, .ao_override_rtm = 1, .ao_fill_af_no_nest = 1, }; static void __init bridge_init(void) { rtnl_link_af_register(&bridge_ops); } static void __exit bridge_exit(void) { rtnl_link_af_unregister(&bridge_ops); } /** @} */ libnl-3.2.29/lib/route/link/sit.c0000644000175000017500000004504013023014600013424 00000000000000/* * lib/route/link/sit.c SIT Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ /** * @ingroup link * @defgroup sit SIT * sit link module * * @details * \b Link Type Name: "sit" * * @route_doc{link_sit, SIT Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include #define SIT_ATTR_LINK (1 << 0) #define SIT_ATTR_LOCAL (1 << 1) #define SIT_ATTR_REMOTE (1 << 2) #define SIT_ATTR_TTL (1 << 3) #define SIT_ATTR_TOS (1 << 4) #define SIT_ATTR_PMTUDISC (1 << 5) #define SIT_ATTR_FLAGS (1 << 6) #define SIT_ATTR_PROTO (1 << 7) #define SIT_ATTR_6RD_PREFIX (1 << 8) #define SIT_ATTR_6RD_RELAY_PREFIX (1 << 9) #define SIT_ATTR_6RD_PREFIXLEN (1 << 10) #define SIT_ATTR_6RD_RELAY_PREFIXLEN (1 << 11) struct sit_info { uint8_t ttl; uint8_t tos; uint8_t pmtudisc; uint8_t proto; uint16_t flags; uint32_t link; uint32_t local; uint32_t remote; struct in6_addr ip6rd_prefix; uint32_t ip6rd_relay_prefix; uint16_t ip6rd_prefixlen; uint16_t ip6rd_relay_prefixlen; uint32_t sit_mask; }; static struct nla_policy sit_policy[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 }, [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 }, [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, [IFLA_IPTUN_6RD_PREFIX] = { .minlen = sizeof(struct in6_addr) }, [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 }, [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 }, [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 }, }; static int sit_alloc(struct rtnl_link *link) { struct sit_info *sit; if (link->l_info) memset(link->l_info, 0, sizeof(*sit)); else { sit = calloc(1, sizeof(*sit)); if (!sit) return -NLE_NOMEM; link->l_info = sit; } return 0; } static int sit_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_IPTUN_MAX + 1]; struct sit_info *sit; int err; NL_DBG(3, "Parsing SIT link info\n"); err = nla_parse_nested(tb, IFLA_IPTUN_MAX, data, sit_policy); if (err < 0) goto errout; err = sit_alloc(link); if (err < 0) goto errout; sit = link->l_info; if (tb[IFLA_IPTUN_LINK]) { sit->link = nla_get_u32(tb[IFLA_IPTUN_LINK]); sit->sit_mask |= SIT_ATTR_LINK; } if (tb[IFLA_IPTUN_LOCAL]) { sit->local = nla_get_u32(tb[IFLA_IPTUN_LOCAL]); sit->sit_mask |= SIT_ATTR_LOCAL; } if (tb[IFLA_IPTUN_REMOTE]) { sit->remote = nla_get_u32(tb[IFLA_IPTUN_REMOTE]); sit->sit_mask |= SIT_ATTR_REMOTE; } if (tb[IFLA_IPTUN_TTL]) { sit->ttl = nla_get_u8(tb[IFLA_IPTUN_TTL]); sit->sit_mask |= SIT_ATTR_TTL; } if (tb[IFLA_IPTUN_TOS]) { sit->tos = nla_get_u8(tb[IFLA_IPTUN_TOS]); sit->sit_mask |= SIT_ATTR_TOS; } if (tb[IFLA_IPTUN_PMTUDISC]) { sit->pmtudisc = nla_get_u8(tb[IFLA_IPTUN_PMTUDISC]); sit->sit_mask |= SIT_ATTR_PMTUDISC; } if (tb[IFLA_IPTUN_FLAGS]) { sit->flags = nla_get_u16(tb[IFLA_IPTUN_FLAGS]); sit->sit_mask |= SIT_ATTR_FLAGS; } if (tb[IFLA_IPTUN_PROTO]) { sit->proto = nla_get_u8(tb[IFLA_IPTUN_PROTO]); sit->sit_mask |= SIT_ATTR_PROTO; } if (tb[IFLA_IPTUN_6RD_PREFIX]) { nla_memcpy(&sit->ip6rd_prefix, tb[IFLA_IPTUN_6RD_PREFIX], sizeof(struct in6_addr)); sit->sit_mask |= SIT_ATTR_6RD_PREFIX; } if (tb[IFLA_IPTUN_6RD_RELAY_PREFIX]) { sit->ip6rd_relay_prefix = nla_get_u32(tb[IFLA_IPTUN_6RD_RELAY_PREFIX]); sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIX; } if (tb[IFLA_IPTUN_6RD_PREFIXLEN]) { sit->ip6rd_prefixlen = nla_get_u16(tb[IFLA_IPTUN_6RD_PREFIXLEN]); sit->sit_mask |= SIT_ATTR_6RD_PREFIXLEN; } if (tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]) { sit->ip6rd_relay_prefixlen = nla_get_u16(tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]); sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIXLEN; } err = 0; errout: return err; } static int sit_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct sit_info *sit = link->l_info; struct nlattr *data; data = nla_nest_start(msg, IFLA_INFO_DATA); if (!data) return -NLE_MSGSIZE; if (sit->sit_mask & SIT_ATTR_LINK) NLA_PUT_U32(msg, IFLA_IPTUN_LINK, sit->link); if (sit->sit_mask & SIT_ATTR_LOCAL) NLA_PUT_U32(msg, IFLA_IPTUN_LOCAL, sit->local); if (sit->sit_mask & SIT_ATTR_REMOTE) NLA_PUT_U32(msg, IFLA_IPTUN_REMOTE, sit->remote); if (sit->sit_mask & SIT_ATTR_TTL) NLA_PUT_U8(msg, IFLA_IPTUN_TTL, sit->ttl); if (sit->sit_mask & SIT_ATTR_TOS) NLA_PUT_U8(msg, IFLA_IPTUN_TOS, sit->tos); if (sit->sit_mask & SIT_ATTR_PMTUDISC) NLA_PUT_U8(msg, IFLA_IPTUN_PMTUDISC, sit->pmtudisc); if (sit->sit_mask & SIT_ATTR_FLAGS) NLA_PUT_U16(msg, IFLA_IPTUN_FLAGS, sit->flags); if (sit->sit_mask & SIT_ATTR_PROTO) NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, sit->proto); if (sit->sit_mask & SIT_ATTR_6RD_PREFIX) NLA_PUT(msg, IFLA_IPTUN_6RD_PREFIX, sizeof(struct in6_addr), &sit->ip6rd_prefix); if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX) NLA_PUT_U32(msg, IFLA_IPTUN_6RD_RELAY_PREFIX, sit->ip6rd_relay_prefix); if (sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN) NLA_PUT_U16(msg, IFLA_IPTUN_6RD_PREFIXLEN, sit->ip6rd_prefixlen); if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIXLEN) NLA_PUT_U16(msg, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, sit->ip6rd_relay_prefixlen); nla_nest_end(msg, data); nla_put_failure: return 0; } static void sit_free(struct rtnl_link *link) { struct sit_info *sit = link->l_info; free(sit); link->l_info = NULL; } static void sit_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { nl_dump(p, "sit : %s", link->l_name); } static void sit_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct sit_info *sit = link->l_info; char *name, addr[INET_ADDRSTRLEN], addr6[INET6_ADDRSTRLEN]; struct rtnl_link *parent; if (sit->sit_mask & SIT_ATTR_LINK) { nl_dump(p, " link "); name = NULL; parent = link_lookup(link->ce_cache, sit->link); if (parent) name = rtnl_link_get_name(parent); if (name) nl_dump_line(p, "%s\n", name); else nl_dump_line(p, "%u\n", sit->link); } if (sit->sit_mask & SIT_ATTR_LOCAL) { nl_dump(p, " local "); if(inet_ntop(AF_INET, &sit->local, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(sit->local)); } if (sit->sit_mask & SIT_ATTR_REMOTE) { nl_dump(p, " remote "); if(inet_ntop(AF_INET, &sit->remote, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(sit->remote)); } if (sit->sit_mask & SIT_ATTR_TTL) { nl_dump(p, " ttl "); nl_dump_line(p, "%u\n", sit->ttl); } if (sit->sit_mask & SIT_ATTR_TOS) { nl_dump(p, " tos "); nl_dump_line(p, "%u\n", sit->tos); } if (sit->sit_mask & SIT_ATTR_FLAGS) { nl_dump(p, " flags "); nl_dump_line(p, " (%x)\n", sit->flags); } if (sit->sit_mask & SIT_ATTR_PROTO) { nl_dump(p, " proto "); nl_dump_line(p, " (%x)\n", sit->proto); } if (sit->sit_mask & SIT_ATTR_6RD_PREFIX) { nl_dump(p, " 6rd_prefix "); if(inet_ntop(AF_INET6, &sit->ip6rd_prefix, addr6, INET6_ADDRSTRLEN)) nl_dump_line(p, "%s\n", addr6); else nl_dump_line(p, "[unknown]\n"); } if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX) { nl_dump(p, " 6rd_relay_prefix "); if(inet_ntop(AF_INET, &sit->ip6rd_relay_prefix, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "[unknown]\n"); } if (sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN) { nl_dump(p, " 6rd_prefixlen "); nl_dump_line(p, "%d\n", sit->ip6rd_prefixlen); } if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIXLEN) { nl_dump(p, " 6rd_relay_prefixlen "); nl_dump_line(p, "%d\n", sit->ip6rd_relay_prefixlen); } } static int sit_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct sit_info *sit_dst, *sit_src = src->l_info; int err; dst->l_info = NULL; err = rtnl_link_set_type(dst, "sit"); if (err < 0) return err; sit_dst = dst->l_info; if (!sit_dst || !sit_src) return -NLE_NOMEM; memcpy(sit_dst, sit_src, sizeof(struct sit_info)); return 0; } static struct rtnl_link_info_ops sit_info_ops = { .io_name = "sit", .io_alloc = sit_alloc, .io_parse = sit_parse, .io_dump = { [NL_DUMP_LINE] = sit_dump_line, [NL_DUMP_DETAILS] = sit_dump_details, }, .io_clone = sit_clone, .io_put_attrs = sit_put_attrs, .io_free = sit_free, }; #define IS_SIT_LINK_ASSERT(link, sit) \ struct sit_info *sit; \ do { \ const struct rtnl_link *_link = (link); \ if (!_link || _link->l_info_ops != &sit_info_ops) { \ APPBUG("Link is not a sit link. set type \"sit\" first."); \ return -NLE_OPNOTSUPP; \ } \ (sit) = _link->l_info; \ } while (0) struct rtnl_link *rtnl_link_sit_alloc(void) { struct rtnl_link *link; int err; link = rtnl_link_alloc(); if (!link) return NULL; err = rtnl_link_set_type(link, "sit"); if (err < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a SIT link * @arg link Link object * * @return True if link is a SIT link, otherwise false is returned. */ int rtnl_link_is_sit(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "sit"); } /** * Create a new sit tunnel device * @arg sock netlink socket * @arg name name of the tunnel device * * Creates a new sit tunnel device in the kernel * @return 0 on success or a negative error code */ int rtnl_link_sit_add(struct nl_sock *sk, const char *name) { struct rtnl_link *link; int err; link = rtnl_link_sit_alloc(); if (!link) return -NLE_NOMEM; if(name) rtnl_link_set_name(link, name); err = rtnl_link_add(sk, link, NLM_F_CREATE); rtnl_link_put(link); return err; } /** * Set SIT tunnel interface index * @arg link Link object * @arg index interface index * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_link(struct rtnl_link *link, uint32_t index) { IS_SIT_LINK_ASSERT(link, sit); sit->link = index; sit->sit_mask |= SIT_ATTR_LINK; return 0; } /** * Get SIT tunnel interface index * @arg link Link object * * @return interface index value */ uint32_t rtnl_link_sit_get_link(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->link; } /** * Set SIT tunnel local address * @arg link Link object * @arg addr local address * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_local(struct rtnl_link *link, uint32_t addr) { IS_SIT_LINK_ASSERT(link, sit); sit->local = addr; sit->sit_mask |= SIT_ATTR_LOCAL; return 0; } /** * Get SIT tunnel local address * @arg link Link object * * @return local address value */ uint32_t rtnl_link_sit_get_local(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->local; } /** * Set SIT tunnel remote address * @arg link Link object * @arg remote remote address * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_remote(struct rtnl_link *link, uint32_t addr) { IS_SIT_LINK_ASSERT(link, sit); sit->remote = addr; sit->sit_mask |= SIT_ATTR_REMOTE; return 0; } /** * Get SIT tunnel remote address * @arg link Link object * * @return remote address */ uint32_t rtnl_link_sit_get_remote(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->remote; } /** * Set SIT tunnel ttl * @arg link Link object * @arg ttl tunnel ttl * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_ttl(struct rtnl_link *link, uint8_t ttl) { IS_SIT_LINK_ASSERT(link, sit); sit->ttl = ttl; sit->sit_mask |= SIT_ATTR_TTL; return 0; } /** * Get SIT tunnel ttl * @arg link Link object * * @return ttl value */ uint8_t rtnl_link_sit_get_ttl(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->ttl; } /** * Set SIT tunnel tos * @arg link Link object * @arg tos tunnel tos * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_tos(struct rtnl_link *link, uint8_t tos) { IS_SIT_LINK_ASSERT(link, sit); sit->tos = tos; sit->sit_mask |= SIT_ATTR_TOS; return 0; } /** * Get SIT tunnel tos * @arg link Link object * * @return tos value */ uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->tos; } /** * Set SIT tunnel path MTU discovery * @arg link Link object * @arg pmtudisc path MTU discovery * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc) { IS_SIT_LINK_ASSERT(link, sit); sit->pmtudisc = pmtudisc; sit->sit_mask |= SIT_ATTR_PMTUDISC; return 0; } /** * Get SIT path MTU discovery * @arg link Link object * * @return pmtudisc value */ uint8_t rtnl_link_sit_get_pmtudisc(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->pmtudisc; } /** * Set SIT tunnel flags * @arg link Link object * @arg flags tunnel flags * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_flags(struct rtnl_link *link, uint16_t flags) { IS_SIT_LINK_ASSERT(link, sit); sit->flags = flags; sit->sit_mask |= SIT_ATTR_FLAGS; return 0; } /** * Get SIT path flags * @arg link Link object * * @return flags value */ uint16_t rtnl_link_sit_get_flags(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->flags; } /** * Set SIT tunnel proto * @arg link Link object * @arg proto tunnel proto * * @return 0 on success or a negative error code */ int rtnl_link_sit_set_proto(struct rtnl_link *link, uint8_t proto) { IS_SIT_LINK_ASSERT(link, sit); sit->proto = proto; sit->sit_mask |= SIT_ATTR_PROTO; return 0; } /** * Get SIT proto * @arg link Link object * * @return proto value */ uint8_t rtnl_link_sit_get_proto(struct rtnl_link *link) { IS_SIT_LINK_ASSERT(link, sit); return sit->proto; } /** * Set ip6rd prefix * @arg link Link object * @arg prefix The IPv6 prefix * * @return 0 on success or an error code. */ int rtnl_link_sit_set_ip6rd_prefix(struct rtnl_link *link, const struct in6_addr *prefix) { IS_SIT_LINK_ASSERT(link, sit); sit->ip6rd_prefix = *prefix; sit->sit_mask |= SIT_ATTR_6RD_PREFIX; return 0; } /** * Get ip6rd prefix * @arg link Link object * @arg prefix The output IPv6 prefix * * @return 0 on success or an error code. If the property is unset, * this call fails too. */ int rtnl_link_sit_get_ip6rd_prefix(const struct rtnl_link *link, struct in6_addr *prefix) { IS_SIT_LINK_ASSERT(link, sit); if (!(sit->sit_mask & SIT_ATTR_6RD_PREFIX)) return -NLE_NOATTR; if (prefix) *prefix = sit->ip6rd_prefix; return 0; } /** * Set ip6rd prefix length * @arg link Link object * @arg prefixlen The IPv6 prefix length * * @return 0 on success or an error code. */ int rtnl_link_sit_set_ip6rd_prefixlen(struct rtnl_link *link, uint16_t prefixlen) { IS_SIT_LINK_ASSERT(link, sit); sit->sit_mask |= SIT_ATTR_6RD_PREFIXLEN; sit->ip6rd_prefixlen = prefixlen; return 0; } /** * Get ip6rd prefix length * @arg link Link object * @arg prefixlen Output pointer for the prefix length * * @return 0 on success or an error code. If the property is unset, * this call fails. */ int rtnl_link_sit_get_ip6rd_prefixlen(struct rtnl_link *link, uint16_t *prefixlen) { IS_SIT_LINK_ASSERT(link, sit); if (!(sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN)) return -NLE_NOATTR; if (prefixlen) *prefixlen = sit->ip6rd_prefixlen; return 0; } /** * Set ip6rd relay prefix * @arg link Link object * @arg prefix The IPv6 prefix length * * @return 0 on success or an error code. */ int rtnl_link_sit_set_ip6rd_relay_prefix(struct rtnl_link *link, uint32_t prefix) { IS_SIT_LINK_ASSERT(link, sit); sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIX; sit->ip6rd_relay_prefix = prefix; return 0; } /** * Get ip6rd prefix length * @arg link Link object * @arg prefixlen Output pointer for the prefix length * * @return 0 on success or an error code. If the property is unset, * this call fails. */ int rtnl_link_sit_get_ip6rd_relay_prefix(const struct rtnl_link *link, uint32_t *prefix) { IS_SIT_LINK_ASSERT(link, sit); if (!(sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX)) return -NLE_NOATTR; if (prefix) *prefix = sit->ip6rd_relay_prefix; return 0; } /** * Set ip6rd relay prefix length * @arg link Link object * @arg prefixlen The IPv6 prefix length * * @return 0 on success or an error code. */ int rtnl_link_sit_set_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t prefixlen) { IS_SIT_LINK_ASSERT(link, sit); sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIXLEN; sit->ip6rd_relay_prefixlen = prefixlen; return 0; } /** * Get ip6rd relay prefix length * @arg link Link object * @arg prefixlen Output pointer for the prefix length * * @return 0 on success or an error code. If the property is unset, * this call fails. */ int rtnl_link_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *prefixlen) { IS_SIT_LINK_ASSERT(link, sit); if (!(sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX)) return -NLE_NOATTR; if (prefixlen) *prefixlen = sit->ip6rd_relay_prefixlen; return 0; } static void __init sit_init(void) { rtnl_link_register_info(&sit_info_ops); } static void __exit sit_exit(void) { rtnl_link_unregister_info(&sit_info_ops); } libnl-3.2.29/lib/route/link/ipip.c0000644000175000017500000002621313023014600013567 00000000000000/* * lib/route/link/ipip.c IPIP Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ /** * @ingroup link * @defgroup ipip IPIP * ipip link module * * @details * \b Link Type Name: "ipip" * * @route_doc{link_ipip, IPIP Documentation} * * @{ */ #include #include #include #include #include #include #include #include #define IPIP_ATTR_LINK (1 << 0) #define IPIP_ATTR_LOCAL (1 << 1) #define IPIP_ATTR_REMOTE (1 << 2) #define IPIP_ATTR_TTL (1 << 3) #define IPIP_ATTR_TOS (1 << 4) #define IPIP_ATTR_PMTUDISC (1 << 5) struct ipip_info { uint8_t ttl; uint8_t tos; uint8_t pmtudisc; uint32_t link; uint32_t local; uint32_t remote; uint32_t ipip_mask; }; static struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 }, [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, }; static int ipip_alloc(struct rtnl_link *link) { struct ipip_info *ipip; if (link->l_info) memset(link->l_info, 0, sizeof(*ipip)); else { ipip = calloc(1, sizeof(*ipip)); if (!ipip) return -NLE_NOMEM; link->l_info = ipip; } return 0; } static int ipip_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_IPTUN_MAX + 1]; struct ipip_info *ipip; int err; NL_DBG(3, "Parsing IPIP link info\n"); err = nla_parse_nested(tb, IFLA_IPTUN_MAX, data, ipip_policy); if (err < 0) goto errout; err = ipip_alloc(link); if (err < 0) goto errout; ipip = link->l_info; if (tb[IFLA_IPTUN_LINK]) { ipip->link = nla_get_u32(tb[IFLA_IPTUN_LINK]); ipip->ipip_mask |= IPIP_ATTR_LINK; } if (tb[IFLA_IPTUN_LOCAL]) { ipip->local = nla_get_u32(tb[IFLA_IPTUN_LOCAL]); ipip->ipip_mask |= IPIP_ATTR_LOCAL; } if (tb[IFLA_IPTUN_REMOTE]) { ipip->remote = nla_get_u32(tb[IFLA_IPTUN_REMOTE]); ipip->ipip_mask |= IPIP_ATTR_REMOTE; } if (tb[IFLA_IPTUN_TTL]) { ipip->ttl = nla_get_u8(tb[IFLA_IPTUN_TTL]); ipip->ipip_mask |= IPIP_ATTR_TTL; } if (tb[IFLA_IPTUN_TOS]) { ipip->tos = nla_get_u8(tb[IFLA_IPTUN_TOS]); ipip->ipip_mask |= IPIP_ATTR_TOS; } if (tb[IFLA_IPTUN_PMTUDISC]) { ipip->pmtudisc = nla_get_u8(tb[IFLA_IPTUN_PMTUDISC]); ipip->ipip_mask |= IPIP_ATTR_PMTUDISC; } err = 0; errout: return err; } static int ipip_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; struct nlattr *data; data = nla_nest_start(msg, IFLA_INFO_DATA); if (!data) return -NLE_MSGSIZE; if (ipip->ipip_mask & IPIP_ATTR_LINK) NLA_PUT_U32(msg, IFLA_IPTUN_LINK, ipip->link); if (ipip->ipip_mask & IPIP_ATTR_LOCAL) NLA_PUT_U32(msg, IFLA_IPTUN_LOCAL, ipip->local); if (ipip->ipip_mask & IPIP_ATTR_REMOTE) NLA_PUT_U32(msg, IFLA_IPTUN_REMOTE, ipip->remote); if (ipip->ipip_mask & IPIP_ATTR_TTL) NLA_PUT_U8(msg, IFLA_IPTUN_TTL, ipip->ttl); if (ipip->ipip_mask & IPIP_ATTR_TOS) NLA_PUT_U8(msg, IFLA_IPTUN_TOS, ipip->tos); if (ipip->ipip_mask & IPIP_ATTR_PMTUDISC) NLA_PUT_U8(msg, IFLA_IPTUN_PMTUDISC, ipip->pmtudisc); nla_nest_end(msg, data); nla_put_failure: return 0; } static void ipip_free(struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; free(ipip); link->l_info = NULL; } static void ipip_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { nl_dump(p, "ipip : %s", link->l_name); } static void ipip_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct ipip_info *ipip = link->l_info; char *name, addr[INET_ADDRSTRLEN]; struct rtnl_link *parent; if (ipip->ipip_mask & IPIP_ATTR_LINK) { nl_dump(p, " link "); name = NULL; parent = link_lookup(link->ce_cache, ipip->link); if (parent) name = rtnl_link_get_name(parent); if (name) nl_dump_line(p, "%s\n", name); else nl_dump_line(p, "%u\n", ipip->link); } if (ipip->ipip_mask & IPIP_ATTR_LOCAL) { nl_dump(p, " local "); if(inet_ntop(AF_INET, &ipip->local, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(ipip->local)); } if (ipip->ipip_mask & IPIP_ATTR_REMOTE) { nl_dump(p, " remote "); if(inet_ntop(AF_INET, &ipip->remote, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(ipip->remote)); } if (ipip->ipip_mask & IPIP_ATTR_TTL) { nl_dump(p, " ttl "); nl_dump_line(p, "%u\n", ipip->ttl); } if (ipip->ipip_mask & IPIP_ATTR_TOS) { nl_dump(p, " tos "); nl_dump_line(p, "%u\n", ipip->tos); } if (ipip->ipip_mask & IPIP_ATTR_PMTUDISC) { nl_dump(p, " pmtudisc "); nl_dump_line(p, "enabled (%#x)\n", ipip->pmtudisc); } } static int ipip_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct ipip_info *ipip_dst, *ipip_src = src->l_info; int err; dst->l_info = NULL; err = rtnl_link_set_type(dst, "ipip"); if (err < 0) return err; ipip_dst = dst->l_info; if (!ipip_dst || !ipip_src) BUG(); memcpy(ipip_dst, ipip_src, sizeof(struct ipip_info)); return 0; } static struct rtnl_link_info_ops ipip_info_ops = { .io_name = "ipip", .io_alloc = ipip_alloc, .io_parse = ipip_parse, .io_dump = { [NL_DUMP_LINE] = ipip_dump_line, [NL_DUMP_DETAILS] = ipip_dump_details, }, .io_clone = ipip_clone, .io_put_attrs = ipip_put_attrs, .io_free = ipip_free, }; #define IS_IPIP_LINK_ASSERT(link) \ if ((link)->l_info_ops != &ipip_info_ops) { \ APPBUG("Link is not a ipip link. set type \"ipip\" first."); \ return -NLE_OPNOTSUPP; \ } struct rtnl_link *rtnl_link_ipip_alloc(void) { struct rtnl_link *link; int err; link = rtnl_link_alloc(); if (!link) return NULL; err = rtnl_link_set_type(link, "ipip"); if (err < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a IPIP link * @arg link Link object * * @return True if link is a IPIP link, otherwise false is returned. */ int rtnl_link_is_ipip(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ipip"); } /** * Create a new ipip tunnel device * @arg sock netlink socket * @arg name name of the tunnel deviceL * * Creates a new ipip tunnel device in the kernel * @return 0 on success or a negative error code */ int rtnl_link_ipip_add(struct nl_sock *sk, const char *name) { struct rtnl_link *link; int err; link = rtnl_link_ipip_alloc(); if (!link) return -NLE_NOMEM; if(name) rtnl_link_set_name(link, name); err = rtnl_link_add(sk, link, NLM_F_CREATE); rtnl_link_put(link); return err; } /** * Set IPIP tunnel interface index * @arg link Link object * @arg index interface index * * @return 0 on success or a negative error code */ int rtnl_link_ipip_set_link(struct rtnl_link *link, uint32_t index) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); ipip->link = index; ipip->ipip_mask |= IPIP_ATTR_LINK; return 0; } /** * Get IPIP tunnel interface index * @arg link Link object * * @return interface index value */ uint32_t rtnl_link_ipip_get_link(struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); return ipip->link; } /** * Set IPIP tunnel local address * @arg link Link object * @arg addr local address * * @return 0 on success or a negative error code */ int rtnl_link_ipip_set_local(struct rtnl_link *link, uint32_t addr) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); ipip->local = addr; ipip->ipip_mask |= IPIP_ATTR_LOCAL; return 0; } /** * Get IPIP tunnel local address * @arg link Link object * * @return local address value */ uint32_t rtnl_link_ipip_get_local(struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); return ipip->local; } /** * Set IPIP tunnel remote address * @arg link Link object * @arg remote remote address * * @return 0 on success or a negative error code */ int rtnl_link_ipip_set_remote(struct rtnl_link *link, uint32_t addr) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); ipip->remote = addr; ipip->ipip_mask |= IPIP_ATTR_REMOTE; return 0; } /** * Get IPIP tunnel remote address * @arg link Link object * * @return remote address */ uint32_t rtnl_link_ipip_get_remote(struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); return ipip->remote; } /** * Set IPIP tunnel ttl * @arg link Link object * @arg ttl tunnel ttl * * @return 0 on success or a negative error code */ int rtnl_link_ipip_set_ttl(struct rtnl_link *link, uint8_t ttl) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); ipip->ttl = ttl; ipip->ipip_mask |= IPIP_ATTR_TTL; return 0; } /** * Get IPIP tunnel ttl * @arg link Link object * * @return ttl value */ uint8_t rtnl_link_ipip_get_ttl(struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); return ipip->ttl; } /** * Set IPIP tunnel tos * @arg link Link object * @arg tos tunnel tos * * @return 0 on success or a negative error code */ int rtnl_link_ipip_set_tos(struct rtnl_link *link, uint8_t tos) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); ipip->tos = tos; ipip->ipip_mask |= IPIP_ATTR_TOS; return 0; } /** * Get IPIP tunnel tos * @arg link Link object * * @return tos value */ uint8_t rtnl_link_ipip_get_tos(struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); return ipip->tos; } /** * Set IPIP tunnel path MTU discovery * @arg link Link object * @arg pmtudisc path MTU discovery * * @return 0 on success or a negative error code */ int rtnl_link_ipip_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); ipip->pmtudisc = pmtudisc; ipip->ipip_mask |= IPIP_ATTR_PMTUDISC; return 0; } /** * Get IPIP path MTU discovery * @arg link Link object * * @return pmtudisc value */ uint8_t rtnl_link_ipip_get_pmtudisc(struct rtnl_link *link) { struct ipip_info *ipip = link->l_info; IS_IPIP_LINK_ASSERT(link); return ipip->pmtudisc; } static void __init ipip_init(void) { rtnl_link_register_info(&ipip_info_ops); } static void __exit ipip_exit(void) { rtnl_link_unregister_info(&ipip_info_ops); } libnl-3.2.29/lib/route/link/vlan.c0000644000175000017500000003376113023014600013574 00000000000000/* * lib/route/link/vlan.c VLAN Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ /** * @ingroup link * @defgroup vlan VLAN * Virtual LAN link module * * @details * \b Link Type Name: "vlan" * * @route_doc{link_vlan, VLAN Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define VLAN_HAS_ID (1<<0) #define VLAN_HAS_FLAGS (1<<1) #define VLAN_HAS_INGRESS_QOS (1<<2) #define VLAN_HAS_EGRESS_QOS (1<<3) #define VLAN_HAS_PROTOCOL (1<<4) struct vlan_info { uint16_t vi_vlan_id; uint16_t vi_protocol; unsigned int vi_ingress_qos_mask:(VLAN_PRIO_MAX+1); uint32_t vi_flags; uint32_t vi_flags_mask; uint32_t vi_ingress_qos[VLAN_PRIO_MAX+1]; uint32_t vi_negress; uint32_t vi_egress_size; struct vlan_map * vi_egress_qos; uint32_t vi_mask; }; /** @endcond */ static struct nla_policy vlan_policy[IFLA_VLAN_MAX+1] = { [IFLA_VLAN_ID] = { .type = NLA_U16 }, [IFLA_VLAN_FLAGS] = { .minlen = sizeof(struct ifla_vlan_flags) }, [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED }, [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED }, [IFLA_VLAN_PROTOCOL] = { .type = NLA_U16 }, }; static int vlan_alloc(struct rtnl_link *link) { struct vlan_info *vi; if (link->l_info) { vi = link->l_info; free(vi->vi_egress_qos); memset(link->l_info, 0, sizeof(*vi)); } else { if ((vi = calloc(1, sizeof(*vi))) == NULL) return -NLE_NOMEM; link->l_info = vi; } return 0; } static int vlan_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_VLAN_MAX+1]; struct vlan_info *vi; int err; NL_DBG(3, "Parsing VLAN link info\n"); if ((err = nla_parse_nested(tb, IFLA_VLAN_MAX, data, vlan_policy)) < 0) goto errout; if ((err = vlan_alloc(link)) < 0) goto errout; vi = link->l_info; if (tb[IFLA_VLAN_ID]) { vi->vi_vlan_id = nla_get_u16(tb[IFLA_VLAN_ID]); vi->vi_mask |= VLAN_HAS_ID; } if (tb[IFLA_VLAN_PROTOCOL]) { vi->vi_protocol = nla_get_u16(tb[IFLA_VLAN_PROTOCOL]); vi->vi_mask |= VLAN_HAS_PROTOCOL; } if (tb[IFLA_VLAN_FLAGS]) { struct ifla_vlan_flags flags; nla_memcpy(&flags, tb[IFLA_VLAN_FLAGS], sizeof(flags)); vi->vi_flags = flags.flags; vi->vi_mask |= VLAN_HAS_FLAGS; } if (tb[IFLA_VLAN_INGRESS_QOS]) { struct ifla_vlan_qos_mapping *map; struct nlattr *nla; int remaining; vi->vi_ingress_qos_mask = 0; memset(vi->vi_ingress_qos, 0, sizeof(vi->vi_ingress_qos)); nla_for_each_nested(nla, tb[IFLA_VLAN_INGRESS_QOS], remaining) { if (nla_len(nla) < sizeof(*map)) return -NLE_INVAL; map = nla_data(nla); if (map->from > VLAN_PRIO_MAX) { return -NLE_INVAL; } /* Kernel will not explicitly serialize mappings with "to" zero * (although they are implicitly set). * * Thus we only mark those as "set" which are explicitly sent. * That is similar to what we do with the egress map and it preserves * previous behavior before NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR. * * It matters only when a received object is send back to kernel to modify * the link. */ vi->vi_ingress_qos_mask |= (1 << map->from); vi->vi_ingress_qos[map->from] = map->to; } vi->vi_mask |= VLAN_HAS_INGRESS_QOS; } if (tb[IFLA_VLAN_EGRESS_QOS]) { struct ifla_vlan_qos_mapping *map; struct nlattr *nla; int remaining, i = 0; nla_for_each_nested(nla, tb[IFLA_VLAN_EGRESS_QOS], remaining) { if (nla_len(nla) < sizeof(*map)) return -NLE_INVAL; i++; } /* align to have a little reserve */ vi->vi_egress_size = (i + 32) & ~31; vi->vi_egress_qos = calloc(vi->vi_egress_size, sizeof(*vi->vi_egress_qos)); if (vi->vi_egress_qos == NULL) return -NLE_NOMEM; i = 0; nla_for_each_nested(nla, tb[IFLA_VLAN_EGRESS_QOS], remaining) { map = nla_data(nla); NL_DBG(4, "Assigning egress qos mapping %d\n", i); vi->vi_egress_qos[i].vm_from = map->from; vi->vi_egress_qos[i++].vm_to = map->to; } vi->vi_negress = i; vi->vi_mask |= VLAN_HAS_EGRESS_QOS; } err = 0; errout: return err; } static void vlan_free(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; if (vi) { free(vi->vi_egress_qos); vi->vi_egress_qos = NULL; } free(vi); link->l_info = NULL; } static void vlan_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { struct vlan_info *vi = link->l_info; nl_dump(p, "vlan-id %d", vi->vi_vlan_id); } static void vlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct vlan_info *vi = link->l_info; int printed; uint32_t i; char buf[64]; rtnl_link_vlan_flags2str(vi->vi_flags, buf, sizeof(buf)); nl_dump_line(p, " vlan-info id %d <%s>", vi->vi_vlan_id, buf); if (vi->vi_mask & VLAN_HAS_PROTOCOL) nl_dump_line(p, " vlan protocol <%d>", ntohs(vi->vi_protocol)); nl_dump(p, "\n"); if (vi->vi_mask & VLAN_HAS_INGRESS_QOS) { nl_dump_line(p, " ingress vlan prio -> qos/socket prio mapping:\n"); for (i = 0, printed = 0; i <= VLAN_PRIO_MAX; i++) { if (vi->vi_ingress_qos_mask & (1 << i)) { if (printed == 0) nl_dump_line(p, " "); nl_dump(p, "%x -> %#08x, ", i, vi->vi_ingress_qos[i]); if (printed++ == 3) { nl_dump(p, "\n"); printed = 0; } } } if (printed > 0 && printed != 4) nl_dump(p, "\n"); } if (vi->vi_mask & VLAN_HAS_EGRESS_QOS) { nl_dump_line(p, " egress qos/socket prio -> vlan prio mapping:\n"); for (i = 0, printed = 0; i < vi->vi_negress; i++) { if (printed == 0) nl_dump_line(p, " "); nl_dump(p, "%#08x -> %x, ", vi->vi_egress_qos[i].vm_from, vi->vi_egress_qos[i].vm_to); if (printed++ == 3) { nl_dump(p, "\n"); printed = 0; } } if (printed > 0 && printed != 4) nl_dump(p, "\n"); } } static int vlan_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct vlan_info *vdst, *vsrc = src->l_info; int err; dst->l_info = NULL; if ((err = rtnl_link_set_type(dst, "vlan")) < 0) return err; vdst = dst->l_info; vdst->vi_egress_qos = calloc(vsrc->vi_egress_size, sizeof(struct vlan_map)); if (!vdst->vi_egress_qos) return -NLE_NOMEM; memcpy(vdst->vi_egress_qos, vsrc->vi_egress_qos, vsrc->vi_egress_size * sizeof(struct vlan_map)); return 0; } static int vlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct vlan_info *vi = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; if (vi->vi_mask & VLAN_HAS_ID) NLA_PUT_U16(msg, IFLA_VLAN_ID, vi->vi_vlan_id); if (vi->vi_mask & VLAN_HAS_PROTOCOL) NLA_PUT_U16(msg, IFLA_VLAN_PROTOCOL, vi->vi_protocol); if (vi->vi_mask & VLAN_HAS_FLAGS) { struct ifla_vlan_flags flags = { .flags = vi->vi_flags, .mask = vi->vi_flags_mask, }; NLA_PUT(msg, IFLA_VLAN_FLAGS, sizeof(flags), &flags); } if (vi->vi_mask & VLAN_HAS_INGRESS_QOS) { struct ifla_vlan_qos_mapping map; struct nlattr *qos; int i; if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS))) goto nla_put_failure; for (i = 0; i <= VLAN_PRIO_MAX; i++) { if (vi->vi_ingress_qos_mask & (1 << i)) { map.from = i; map.to = vi->vi_ingress_qos[i]; NLA_PUT(msg, i, sizeof(map), &map); } } nla_nest_end(msg, qos); } if (vi->vi_mask & VLAN_HAS_EGRESS_QOS) { struct ifla_vlan_qos_mapping map; struct nlattr *qos; uint32_t i; if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS))) goto nla_put_failure; for (i = 0; i < vi->vi_negress; i++) { map.from = vi->vi_egress_qos[i].vm_from; map.to = vi->vi_egress_qos[i].vm_to; NLA_PUT(msg, i, sizeof(map), &map); } nla_nest_end(msg, qos); } nla_nest_end(msg, data); nla_put_failure: return 0; } static struct rtnl_link_info_ops vlan_info_ops = { .io_name = "vlan", .io_alloc = vlan_alloc, .io_parse = vlan_parse, .io_dump = { [NL_DUMP_LINE] = vlan_dump_line, [NL_DUMP_DETAILS] = vlan_dump_details, }, .io_clone = vlan_clone, .io_put_attrs = vlan_put_attrs, .io_free = vlan_free, }; /** @cond SKIP */ #define IS_VLAN_LINK_ASSERT(link) \ if ((link)->l_info_ops != &vlan_info_ops) { \ APPBUG("Link is not a vlan link. set type \"vlan\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ /** * @name VLAN Object * @{ */ /** * Allocate link object of type VLAN * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_vlan_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "vlan")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a VLAN link * @arg link Link object * * @return True if link is a VLAN link, otherwise false is returned. */ int rtnl_link_is_vlan(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vlan"); } /** * Set VLAN ID * @arg link Link object * @arg id VLAN identifier * * @return 0 on success or a negative error code */ int rtnl_link_vlan_set_id(struct rtnl_link *link, uint16_t id) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); vi->vi_vlan_id = id; vi->vi_mask |= VLAN_HAS_ID; return 0; } /** * Get VLAN Id * @arg link Link object * * @return VLAN id, 0 if not set or a negative error code. */ int rtnl_link_vlan_get_id(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); if (vi->vi_mask & VLAN_HAS_ID) return vi->vi_vlan_id; else return 0; } /** * Set VLAN protocol * @arg link Link object * @arg protocol VLAN protocol in network byte order. * Probably you want to set it to something like htons(ETH_P_8021Q). * * @return 0 on success or a negative error code */ int rtnl_link_vlan_set_protocol(struct rtnl_link *link, uint16_t protocol) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); vi->vi_protocol = protocol; vi->vi_mask |= VLAN_HAS_PROTOCOL; return 0; } /** * Get VLAN protocol * @arg link Link object * * @return VLAN protocol in network byte order like htons(ETH_P_8021Q), * 0 if not set or a negative error code. */ int rtnl_link_vlan_get_protocol(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); if (vi->vi_mask & VLAN_HAS_PROTOCOL) return vi->vi_protocol; else return 0; } /** * Set VLAN flags * @arg link Link object * @arg flags VLAN flags * * @return 0 on success or a negative error code. */ int rtnl_link_vlan_set_flags(struct rtnl_link *link, unsigned int flags) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); vi->vi_flags_mask |= flags; vi->vi_flags |= flags; vi->vi_mask |= VLAN_HAS_FLAGS; return 0; } /** * Unset VLAN flags * @arg link Link object * @arg flags VLAN flags * * @return 0 on success or a negative error code. */ int rtnl_link_vlan_unset_flags(struct rtnl_link *link, unsigned int flags) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); vi->vi_flags_mask |= flags; vi->vi_flags &= ~flags; vi->vi_mask |= VLAN_HAS_FLAGS; return 0; } /** * Get VLAN flags * @arg link Link object * * @return VLAN flags, 0 if none set, or a negative error code. */ int rtnl_link_vlan_get_flags(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); return vi->vi_flags; } /** @} */ /** * @name Quality of Service * @{ */ int rtnl_link_vlan_set_ingress_map(struct rtnl_link *link, int from, uint32_t to) { struct vlan_info *vi = link->l_info; IS_VLAN_LINK_ASSERT(link); if (from < 0 || from > VLAN_PRIO_MAX) return -NLE_INVAL; vi->vi_ingress_qos_mask |= (1 << from); vi->vi_ingress_qos[from] = to; vi->vi_mask |= VLAN_HAS_INGRESS_QOS; return 0; } uint32_t *rtnl_link_vlan_get_ingress_map(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return NULL; if (vi->vi_mask & VLAN_HAS_INGRESS_QOS) return vi->vi_ingress_qos; else return NULL; } int rtnl_link_vlan_set_egress_map(struct rtnl_link *link, uint32_t from, int to) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return -NLE_OPNOTSUPP; if (to < 0 || to > VLAN_PRIO_MAX) return -NLE_INVAL; if (vi->vi_negress >= vi->vi_egress_size) { int new_size = vi->vi_egress_size + 32; void *ptr; ptr = realloc(vi->vi_egress_qos, new_size); if (!ptr) return -NLE_NOMEM; vi->vi_egress_qos = ptr; vi->vi_egress_size = new_size; } vi->vi_egress_qos[vi->vi_negress].vm_from = from; vi->vi_egress_qos[vi->vi_negress].vm_to = to; vi->vi_negress++; vi->vi_mask |= VLAN_HAS_EGRESS_QOS; return 0; } struct vlan_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *link, int *negress) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return NULL; if (negress == NULL) return NULL; if (vi->vi_mask & VLAN_HAS_EGRESS_QOS) { *negress = vi->vi_negress; return vi->vi_egress_qos; } else { *negress = 0; return NULL; } } /** @} */ static const struct trans_tbl vlan_flags[] = { __ADD(VLAN_FLAG_REORDER_HDR, reorder_hdr), __ADD(VLAN_FLAG_GVRP, gvrp), __ADD(VLAN_FLAG_LOOSE_BINDING, loose_binding), __ADD(VLAN_FLAG_MVRP, mvrp), }; /** * @name Flag Translation * @{ */ char *rtnl_link_vlan_flags2str(int flags, char *buf, size_t len) { return __flags2str(flags, buf, len, vlan_flags, ARRAY_SIZE(vlan_flags)); } int rtnl_link_vlan_str2flags(const char *name) { return __str2flags(name, vlan_flags, ARRAY_SIZE(vlan_flags)); } /** @} */ static void __init vlan_init(void) { rtnl_link_register_info(&vlan_info_ops); } static void __exit vlan_exit(void) { rtnl_link_unregister_info(&vlan_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/ip6tnl.c0000644000175000017500000003744413023014600014052 00000000000000/* * lib/route/link/ip6tnl.c IP6TNL Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Susant Sahani */ /** * @ingroup link * @defgroup ip6tnl IP6TNL * ip6tnl link module * * @details * \b Link Type Name: "ip6tnl" * * @route_doc{link_ip6tnl, IP6TNL Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include #include #define IP6_TNL_ATTR_LINK (1 << 0) #define IP6_TNL_ATTR_LOCAL (1 << 1) #define IP6_TNL_ATTR_REMOTE (1 << 2) #define IP6_TNL_ATTR_TTL (1 << 3) #define IP6_TNL_ATTR_TOS (1 << 4) #define IP6_TNL_ATTR_ENCAPLIMIT (1 << 5) #define IP6_TNL_ATTR_FLAGS (1 << 6) #define IP6_TNL_ATTR_PROTO (1 << 7) #define IP6_TNL_ATTR_FLOWINFO (1 << 8) struct ip6_tnl_info { uint8_t ttl; uint8_t tos; uint8_t encap_limit; uint8_t proto; uint32_t flags; uint32_t link; uint32_t flowinfo; struct in6_addr local; struct in6_addr remote; uint32_t ip6_tnl_mask; }; static struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, [IFLA_IPTUN_LOCAL] = { .minlen = sizeof(struct in6_addr) }, [IFLA_IPTUN_REMOTE] = { .minlen = sizeof(struct in6_addr) }, [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 }, [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 }, [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 }, [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, }; static int ip6_tnl_alloc(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl; if (link->l_info) memset(link->l_info, 0, sizeof(*ip6_tnl)); else { ip6_tnl = calloc(1, sizeof(*ip6_tnl)); if (!ip6_tnl) return -NLE_NOMEM; link->l_info = ip6_tnl; } return 0; } static int ip6_tnl_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_IPTUN_MAX + 1]; struct ip6_tnl_info *ip6_tnl; int err; NL_DBG(3, "Parsing IP6_TNL link info\n"); err = nla_parse_nested(tb, IFLA_IPTUN_MAX, data, ip6_tnl_policy); if (err < 0) goto errout; err = ip6_tnl_alloc(link); if (err < 0) goto errout; ip6_tnl = link->l_info; if (tb[IFLA_IPTUN_LINK]) { ip6_tnl->link = nla_get_u32(tb[IFLA_IPTUN_LINK]); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LINK; } if (tb[IFLA_IPTUN_LOCAL]) { nla_memcpy(&ip6_tnl->local, tb[IFLA_IPTUN_LOCAL], sizeof(struct in6_addr)); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LOCAL; } if (tb[IFLA_IPTUN_REMOTE]) { nla_memcpy(&ip6_tnl->remote, tb[IFLA_IPTUN_REMOTE], sizeof(struct in6_addr)); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_REMOTE; } if (tb[IFLA_IPTUN_TTL]) { ip6_tnl->ttl = nla_get_u8(tb[IFLA_IPTUN_TTL]); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TTL; } if (tb[IFLA_IPTUN_TOS]) { ip6_tnl->tos = nla_get_u8(tb[IFLA_IPTUN_TOS]); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TOS; } if (tb[IFLA_IPTUN_ENCAP_LIMIT]) { ip6_tnl->encap_limit = nla_get_u8(tb[IFLA_IPTUN_ENCAP_LIMIT]); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_ENCAPLIMIT; } if (tb[IFLA_IPTUN_FLAGS]) { ip6_tnl->flags = nla_get_u32(tb[IFLA_IPTUN_FLAGS]); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLAGS; } if (tb[IFLA_IPTUN_FLOWINFO]) { ip6_tnl->flowinfo = nla_get_u32(tb[IFLA_IPTUN_FLOWINFO]); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLOWINFO; } if (tb[IFLA_IPTUN_PROTO]) { ip6_tnl->proto = nla_get_u8(tb[IFLA_IPTUN_PROTO]); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_PROTO; } err = 0; errout: return err; } static int ip6_tnl_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; struct nlattr *data; data = nla_nest_start(msg, IFLA_INFO_DATA); if (!data) return -NLE_MSGSIZE; if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LINK) NLA_PUT_U32(msg, IFLA_IPTUN_LINK, ip6_tnl->link); if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LOCAL) NLA_PUT(msg, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), &ip6_tnl->local); if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_REMOTE) NLA_PUT(msg, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), &ip6_tnl->remote); if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TTL) NLA_PUT_U8(msg, IFLA_IPTUN_TTL, ip6_tnl->ttl); if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TOS) NLA_PUT_U8(msg, IFLA_IPTUN_TOS, ip6_tnl->tos); if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_ENCAPLIMIT) NLA_PUT_U8(msg, IFLA_IPTUN_ENCAP_LIMIT, ip6_tnl->encap_limit); if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLAGS) NLA_PUT_U32(msg, IFLA_IPTUN_FLAGS, ip6_tnl->flags); if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLOWINFO) NLA_PUT_U32(msg, IFLA_IPTUN_FLOWINFO, ip6_tnl->flowinfo); /* kernel crashes if this attribure is missing temporary fix */ if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_PROTO) NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, ip6_tnl->proto); else NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, 0); nla_nest_end(msg, data); nla_put_failure: return 0; } static void ip6_tnl_free(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; free(ip6_tnl); link->l_info = NULL; } static void ip6_tnl_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { nl_dump(p, "ip6_tnl : %s", link->l_name); } static void ip6_tnl_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct ip6_tnl_info *ip6_tnl = link->l_info; char *name, addr[INET6_ADDRSTRLEN]; struct rtnl_link *parent; if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LINK) { nl_dump(p, " link "); name = NULL; parent = link_lookup(link->ce_cache, ip6_tnl->link); if (parent) name = rtnl_link_get_name(parent); if (name) nl_dump_line(p, "%s\n", name); else nl_dump_line(p, "%u\n", ip6_tnl->link); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LOCAL) { nl_dump(p, " local "); if(inet_ntop(AF_INET6, &ip6_tnl->local, addr, INET6_ADDRSTRLEN)) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ip6_tnl->local); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_REMOTE) { nl_dump(p, " remote "); if(inet_ntop(AF_INET6, &ip6_tnl->remote, addr, INET6_ADDRSTRLEN)) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ip6_tnl->remote); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TTL) { nl_dump(p, " ttl "); nl_dump_line(p, "%d\n", ip6_tnl->ttl); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TOS) { nl_dump(p, " tos "); nl_dump_line(p, "%d\n", ip6_tnl->tos); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_ENCAPLIMIT) { nl_dump(p, " encaplimit "); nl_dump_line(p, "%d\n", ip6_tnl->encap_limit); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLAGS) { nl_dump(p, " flags "); nl_dump_line(p, " (%x)\n", ip6_tnl->flags); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FLOWINFO) { nl_dump(p, " flowinfo "); nl_dump_line(p, " (%x)\n", ip6_tnl->flowinfo); } if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_PROTO) { nl_dump(p, " proto "); nl_dump_line(p, " (%x)\n", ip6_tnl->proto); } } static int ip6_tnl_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct ip6_tnl_info *ip6_tnl_dst, *ip6_tnl_src = src->l_info; int err; dst->l_info = NULL; err = rtnl_link_set_type(dst, "ip6tnl"); if (err < 0) return err; ip6_tnl_dst = dst->l_info; if (!ip6_tnl_dst || !ip6_tnl_src) BUG(); memcpy(ip6_tnl_dst, ip6_tnl_src, sizeof(struct ip6_tnl_info)); return 0; } static struct rtnl_link_info_ops ip6_tnl_info_ops = { .io_name = "ip6tnl", .io_alloc = ip6_tnl_alloc, .io_parse = ip6_tnl_parse, .io_dump = { [NL_DUMP_LINE] = ip6_tnl_dump_line, [NL_DUMP_DETAILS] = ip6_tnl_dump_details, }, .io_clone = ip6_tnl_clone, .io_put_attrs = ip6_tnl_put_attrs, .io_free = ip6_tnl_free, }; #define IS_IP6_TNL_LINK_ASSERT(link)\ if ((link)->l_info_ops != &ip6_tnl_info_ops) {\ APPBUG("Link is not a ip6_tnl link. set type \"ip6tnl\" first.");\ return -NLE_OPNOTSUPP;\ } struct rtnl_link *rtnl_link_ip6_tnl_alloc(void) { struct rtnl_link *link; int err; link = rtnl_link_alloc(); if (!link) return NULL; err = rtnl_link_set_type(link, "ip6tnl"); if (err < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a IP6_TNL link * @arg link Link object * * @return True if link is a IP6_TNL link, otherwise false is returned. */ int rtnl_link_is_ip6_tnl(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ip6tnl"); } /** * Create a new ip6_tnl tunnel device * @arg sock netlink socket * @arg name name of the tunnel device * * Creates a new ip6_tnl tunnel device in the kernel * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_add(struct nl_sock *sk, const char *name) { struct rtnl_link *link; int err; link = rtnl_link_ip6_tnl_alloc(); if (!link) return -NLE_NOMEM; if(name) rtnl_link_set_name(link, name); err = rtnl_link_add(sk, link, NLM_F_CREATE); rtnl_link_put(link); return err; } /** * Set IP6_TNL tunnel interface index * @arg link Link object * @arg index interface index * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_link(struct rtnl_link *link, uint32_t index) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); ip6_tnl->link = index; ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LINK; return 0; } /** * Get IP6_TNL tunnel interface index * @arg link Link object * * @return interface index value */ uint32_t rtnl_link_ip6_tnl_get_link(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); return ip6_tnl->link; } /** * Set IP6_TNL tunnel local address * @arg link Link object * @arg addr local address * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_local(struct rtnl_link *link, struct in6_addr *addr) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); memcpy(&ip6_tnl->local, addr, sizeof(struct in6_addr)); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_LOCAL; return 0; } /** * Get IP6_TNL tunnel local address * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_get_local(struct rtnl_link *link, struct in6_addr *addr) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); memcpy(addr, &ip6_tnl->local, sizeof(struct in6_addr)); return 0; } /** * Set IP6_TNL tunnel remote address * @arg link Link object * @arg remote remote address * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_remote(struct rtnl_link *link, struct in6_addr *addr) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); memcpy(&ip6_tnl->remote, addr, sizeof(struct in6_addr)); ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_REMOTE; return 0; } /** * Get IP6_TNL tunnel remote address * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_get_remote(struct rtnl_link *link, struct in6_addr *addr) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); memcpy(addr, &ip6_tnl->remote, sizeof(struct in6_addr)); return 0; } /** * Set IP6_TNL tunnel ttl * @arg link Link object * @arg ttl tunnel ttl * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_ttl(struct rtnl_link *link, uint8_t ttl) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); ip6_tnl->ttl = ttl; ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TTL; return 0; } /** * Get IP6_TNL tunnel ttl * @arg link Link object * * @return ttl value */ uint8_t rtnl_link_ip6_tnl_get_ttl(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); return ip6_tnl->ttl; } /** * Set IP6_TNL tunnel tos * @arg link Link object * @arg tos tunnel tos * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_tos(struct rtnl_link *link, uint8_t tos) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); ip6_tnl->tos = tos; ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_TOS; return 0; } /** * Get IP6_TNL tunnel tos * @arg link Link object * * @return tos value */ uint8_t rtnl_link_ip6_tnl_get_tos(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); return ip6_tnl->tos; } /** * Set IP6_TNL tunnel encap limit * @arg link Link object * @arg encap_limit encaplimit value * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_encaplimit(struct rtnl_link *link, uint8_t encap_limit) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); ip6_tnl->encap_limit = encap_limit; ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_ENCAPLIMIT; return 0; } /** * Get IP6_TNL encaplimit * @arg link Link object * * @return encaplimit value */ uint8_t rtnl_link_ip6_tnl_get_encaplimit(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); return ip6_tnl->encap_limit; } /** * Set IP6_TNL tunnel flowinfo * @arg link Link object * @arg flowinfo flowinfo value * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); ip6_tnl->flowinfo = flowinfo; ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLOWINFO; return 0; } /** * Get IP6_TNL flowinfo * @arg link Link object * * @return flowinfo value */ uint32_t rtnl_link_ip6_tnl_get_flowinfo(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); return ip6_tnl->flowinfo; } /** * Set IP6_TNL tunnel flags * @arg link Link object * @arg flags tunnel flags * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_flags(struct rtnl_link *link, uint32_t flags) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); ip6_tnl->flags = flags; ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FLAGS; return 0; } /** * Get IP6_TNL path flags * @arg link Link object * * @return flags value */ uint32_t rtnl_link_ip6_tnl_get_flags(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); return ip6_tnl->flags; } /** * Set IP6_TNL tunnel proto * @arg link Link object * @arg proto tunnel proto * * @return 0 on success or a negative error code */ int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); ip6_tnl->proto = proto; ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_PROTO; return 0; } /** * Get IP6_TNL proto * @arg link Link object * * @return proto value */ uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link) { struct ip6_tnl_info *ip6_tnl = link->l_info; IS_IP6_TNL_LINK_ASSERT(link); return ip6_tnl->proto; } static void __init ip6_tnl_init(void) { rtnl_link_register_info(&ip6_tnl_info_ops); } static void __exit ip6_tnl_exit(void) { rtnl_link_unregister_info(&ip6_tnl_info_ops); } libnl-3.2.29/lib/route/link/vxlan.c0000644000175000017500000012442613023014600013763 00000000000000/* * lib/route/link/vxlan.c VXLAN Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Yasunobu Chiba */ /** * @ingroup link * @defgroup vxlan VXLAN * Virtual eXtensible Local Area Network link module * * @details * \b Link Type Name: "vxlan" * * @route_doc{link_vxlan, VXLAN Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define VXLAN_ATTR_ID (1<<0) #define VXLAN_ATTR_GROUP (1<<1) #define VXLAN_ATTR_LINK (1<<2) #define VXLAN_ATTR_LOCAL (1<<3) #define VXLAN_ATTR_TTL (1<<4) #define VXLAN_ATTR_TOS (1<<5) #define VXLAN_ATTR_LEARNING (1<<6) #define VXLAN_ATTR_AGEING (1<<7) #define VXLAN_ATTR_LIMIT (1<<8) #define VXLAN_ATTR_PORT_RANGE (1<<9) #define VXLAN_ATTR_PROXY (1<<10) #define VXLAN_ATTR_RSC (1<<11) #define VXLAN_ATTR_L2MISS (1<<12) #define VXLAN_ATTR_L3MISS (1<<13) #define VXLAN_ATTR_GROUP6 (1<<14) #define VXLAN_ATTR_LOCAL6 (1<<15) #define VXLAN_ATTR_PORT (1<<16) #define VXLAN_ATTR_UDP_CSUM (1<<17) #define VXLAN_ATTR_UDP_ZERO_CSUM6_TX (1<<18) #define VXLAN_ATTR_UDP_ZERO_CSUM6_RX (1<<19) #define VXLAN_ATTR_REMCSUM_TX (1<<20) #define VXLAN_ATTR_REMCSUM_RX (1<<21) #define VXLAN_ATTR_COLLECT_METADATA (1<<22) #define VXLAN_ATTR_LABEL (1<<23) #define VXLAN_ATTR_FLAGS (1<<24) struct vxlan_info { uint32_t vxi_id; uint32_t vxi_group; struct in6_addr vxi_group6; uint32_t vxi_link; uint32_t vxi_local; struct in6_addr vxi_local6; uint8_t vxi_ttl; uint8_t vxi_tos; uint8_t vxi_learning; uint8_t vxi_flags; uint32_t vxi_ageing; uint32_t vxi_limit; struct ifla_vxlan_port_range vxi_port_range; uint8_t vxi_proxy; uint8_t vxi_rsc; uint8_t vxi_l2miss; uint8_t vxi_l3miss; uint16_t vxi_port; uint8_t vxi_udp_csum; uint8_t vxi_udp_zero_csum6_tx; uint8_t vxi_udp_zero_csum6_rx; uint8_t vxi_remcsum_tx; uint8_t vxi_remcsum_rx; uint8_t vxi_collect_metadata; uint32_t vxi_label; uint32_t ce_mask; }; /** @endcond */ static struct nla_policy vxlan_policy[IFLA_VXLAN_MAX+1] = { [IFLA_VXLAN_ID] = { .type = NLA_U32 }, [IFLA_VXLAN_GROUP] = { .minlen = sizeof(uint32_t) }, [IFLA_VXLAN_GROUP6] = { .minlen = sizeof(struct in6_addr) }, [IFLA_VXLAN_LINK] = { .type = NLA_U32 }, [IFLA_VXLAN_LOCAL] = { .minlen = sizeof(uint32_t) }, [IFLA_VXLAN_LOCAL6] = { .minlen = sizeof(struct in6_addr) }, [IFLA_VXLAN_TTL] = { .type = NLA_U8 }, [IFLA_VXLAN_TOS] = { .type = NLA_U8 }, [IFLA_VXLAN_LABEL] = { .type = NLA_U32 }, [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 }, [IFLA_VXLAN_AGEING] = { .type = NLA_U32 }, [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 }, [IFLA_VXLAN_PORT_RANGE] = { .minlen = sizeof(struct ifla_vxlan_port_range) }, [IFLA_VXLAN_PROXY] = { .type = NLA_U8 }, [IFLA_VXLAN_RSC] = { .type = NLA_U8 }, [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 }, [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 }, [IFLA_VXLAN_COLLECT_METADATA] = { .type = NLA_U8 }, [IFLA_VXLAN_PORT] = { .type = NLA_U16 }, [IFLA_VXLAN_UDP_CSUM] = { .type = NLA_U8 }, [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 }, [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 }, [IFLA_VXLAN_REMCSUM_TX] = { .type = NLA_U8 }, [IFLA_VXLAN_REMCSUM_RX] = { .type = NLA_U8 }, [IFLA_VXLAN_GBP] = { .type = NLA_FLAG, }, [IFLA_VXLAN_GPE] = { .type = NLA_FLAG, }, [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG }, }; static int vxlan_alloc(struct rtnl_link *link) { struct vxlan_info *vxi; if (link->l_info) memset(link->l_info, 0, sizeof(*vxi)); else { if ((vxi = calloc(1, sizeof(*vxi))) == NULL) return -NLE_NOMEM; link->l_info = vxi; } return 0; } static int vxlan_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_VXLAN_MAX+1]; struct vxlan_info *vxi; int err; NL_DBG(3, "Parsing VXLAN link info\n"); if ((err = nla_parse_nested(tb, IFLA_VXLAN_MAX, data, vxlan_policy)) < 0) goto errout; if ((err = vxlan_alloc(link)) < 0) goto errout; vxi = link->l_info; if (tb[IFLA_VXLAN_ID]) { vxi->vxi_id = nla_get_u32(tb[IFLA_VXLAN_ID]); vxi->ce_mask |= VXLAN_ATTR_ID; } if (tb[IFLA_VXLAN_GROUP6]) { nla_memcpy(&vxi->vxi_group6, tb[IFLA_VXLAN_GROUP6], sizeof(vxi->vxi_group6)); vxi->ce_mask |= VXLAN_ATTR_GROUP6; } if (tb[IFLA_VXLAN_GROUP]) { nla_memcpy(&vxi->vxi_group, tb[IFLA_VXLAN_GROUP], sizeof(vxi->vxi_group)); vxi->ce_mask |= VXLAN_ATTR_GROUP; vxi->ce_mask &= ~VXLAN_ATTR_GROUP6; } if (tb[IFLA_VXLAN_LINK]) { vxi->vxi_link = nla_get_u32(tb[IFLA_VXLAN_LINK]); vxi->ce_mask |= VXLAN_ATTR_LINK; } if (tb[IFLA_VXLAN_LOCAL6]) { nla_memcpy(&vxi->vxi_local6, tb[IFLA_VXLAN_LOCAL6], sizeof(vxi->vxi_local6)); vxi->ce_mask |= VXLAN_ATTR_LOCAL6; } if (tb[IFLA_VXLAN_LOCAL]) { nla_memcpy(&vxi->vxi_local, tb[IFLA_VXLAN_LOCAL], sizeof(vxi->vxi_local)); vxi->ce_mask |= VXLAN_ATTR_LOCAL; vxi->ce_mask &= ~VXLAN_ATTR_LOCAL6; } if (tb[IFLA_VXLAN_TTL]) { vxi->vxi_ttl = nla_get_u8(tb[IFLA_VXLAN_TTL]); vxi->ce_mask |= VXLAN_ATTR_TTL; } if (tb[IFLA_VXLAN_TOS]) { vxi->vxi_tos = nla_get_u8(tb[IFLA_VXLAN_TOS]); vxi->ce_mask |= VXLAN_ATTR_TOS; } if (tb[IFLA_VXLAN_LEARNING]) { vxi->vxi_learning = nla_get_u8(tb[IFLA_VXLAN_LEARNING]); vxi->ce_mask |= VXLAN_ATTR_LEARNING; } if (tb[IFLA_VXLAN_AGEING]) { vxi->vxi_ageing = nla_get_u32(tb[IFLA_VXLAN_AGEING]); vxi->ce_mask |= VXLAN_ATTR_AGEING; } if (tb[IFLA_VXLAN_LIMIT]) { vxi->vxi_limit = nla_get_u32(tb[IFLA_VXLAN_LIMIT]); vxi->ce_mask |= VXLAN_ATTR_LIMIT; } if (tb[IFLA_VXLAN_PORT_RANGE]) { nla_memcpy(&vxi->vxi_port_range, tb[IFLA_VXLAN_PORT_RANGE], sizeof(vxi->vxi_port_range)); vxi->ce_mask |= VXLAN_ATTR_PORT_RANGE; } if (tb[IFLA_VXLAN_PROXY]) { vxi->vxi_proxy = nla_get_u8(tb[IFLA_VXLAN_PROXY]); vxi->ce_mask |= VXLAN_ATTR_PROXY; } if (tb[IFLA_VXLAN_RSC]) { vxi->vxi_rsc = nla_get_u8(tb[IFLA_VXLAN_RSC]); vxi->ce_mask |= VXLAN_ATTR_RSC; } if (tb[IFLA_VXLAN_L2MISS]) { vxi->vxi_l2miss = nla_get_u8(tb[IFLA_VXLAN_L2MISS]); vxi->ce_mask |= VXLAN_ATTR_L2MISS; } if (tb[IFLA_VXLAN_L3MISS]) { vxi->vxi_l3miss = nla_get_u8(tb[IFLA_VXLAN_L3MISS]); vxi->ce_mask |= VXLAN_ATTR_L3MISS; } if (tb[IFLA_VXLAN_PORT]) { vxi->vxi_port = nla_get_u16(tb[IFLA_VXLAN_PORT]); vxi->ce_mask |= VXLAN_ATTR_PORT; } if (tb[IFLA_VXLAN_UDP_CSUM]) { vxi->vxi_udp_csum = nla_get_u8(tb[IFLA_VXLAN_UDP_CSUM]); vxi->ce_mask |= VXLAN_ATTR_UDP_CSUM; } if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]) { vxi->vxi_udp_zero_csum6_tx = nla_get_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]); vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_TX; } if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]) { vxi->vxi_udp_zero_csum6_rx = nla_get_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]); vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_RX; } if (tb[IFLA_VXLAN_REMCSUM_TX]) { vxi->vxi_remcsum_tx = nla_get_u8(tb[IFLA_VXLAN_REMCSUM_TX]); vxi->ce_mask |= VXLAN_ATTR_REMCSUM_TX; } if (tb[IFLA_VXLAN_REMCSUM_RX]) { vxi->vxi_remcsum_rx = nla_get_u8(tb[IFLA_VXLAN_REMCSUM_RX]); vxi->ce_mask |= VXLAN_ATTR_REMCSUM_RX; } if (tb[IFLA_VXLAN_GBP]) vxi->vxi_flags |= RTNL_LINK_VXLAN_F_GBP; if (tb[IFLA_VXLAN_REMCSUM_NOPARTIAL]) vxi->vxi_flags |= RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL; if (tb[IFLA_VXLAN_COLLECT_METADATA]) { vxi->vxi_collect_metadata = nla_get_u8(tb[IFLA_VXLAN_COLLECT_METADATA]); vxi->ce_mask |= VXLAN_ATTR_COLLECT_METADATA; } if (tb[IFLA_VXLAN_LABEL]) { vxi->vxi_label = nla_get_u32(tb[IFLA_VXLAN_LABEL]); vxi->ce_mask |= VXLAN_ATTR_LABEL; } if (tb[IFLA_VXLAN_GPE]) vxi->vxi_flags |= RTNL_LINK_VXLAN_F_GPE; err = 0; errout: return err; } static void vxlan_free(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; free(vxi); link->l_info = NULL; } static void vxlan_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { struct vxlan_info *vxi = link->l_info; nl_dump(p, "vxlan-id %u", vxi->vxi_id); } static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct vxlan_info *vxi = link->l_info; char *name, addr[INET6_ADDRSTRLEN]; struct rtnl_link *parent; nl_dump_line(p, " vxlan-id %u\n", vxi->vxi_id); if (vxi->ce_mask & VXLAN_ATTR_GROUP) { nl_dump(p, " group "); if (inet_ntop(AF_INET, &vxi->vxi_group, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_group)); } else if (vxi->ce_mask & VXLAN_ATTR_GROUP6) { nl_dump(p, " group "); if (inet_ntop(AF_INET6, &vxi->vxi_group6, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", vxi->vxi_group6); } if (vxi->ce_mask & VXLAN_ATTR_LINK) { nl_dump(p, " link "); name = NULL; parent = link_lookup(link->ce_cache, vxi->vxi_link); if (parent) name = rtnl_link_get_name(parent); if (name) nl_dump_line(p, "%s\n", name); else nl_dump_line(p, "%u\n", vxi->vxi_link); } if (vxi->ce_mask & VXLAN_ATTR_LOCAL) { nl_dump(p, " local "); if (inet_ntop(AF_INET, &vxi->vxi_local, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_local)); } else if (vxi->ce_mask & VXLAN_ATTR_LOCAL6) { nl_dump(p, " local "); if (inet_ntop(AF_INET6, &vxi->vxi_local6, addr, sizeof(addr))) nl_dump_line(p, "%s\n", addr); else nl_dump_line(p, "%#x\n", vxi->vxi_local6); } if (vxi->ce_mask & VXLAN_ATTR_TTL) { nl_dump(p, " ttl "); if(vxi->vxi_ttl) nl_dump_line(p, "%u\n", vxi->vxi_ttl); else nl_dump_line(p, "inherit\n"); } if (vxi->ce_mask & VXLAN_ATTR_TOS) { nl_dump(p, " tos "); if (vxi->vxi_tos == 1) nl_dump_line(p, "inherit\n", vxi->vxi_tos); else nl_dump_line(p, "%#x\n", vxi->vxi_tos); } if (vxi->ce_mask & VXLAN_ATTR_LEARNING) { nl_dump(p, " learning "); if (vxi->vxi_learning) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_learning); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_AGEING) { nl_dump(p, " ageing "); if (vxi->vxi_ageing) nl_dump_line(p, "%u seconds\n", vxi->vxi_ageing); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_LIMIT) { nl_dump(p, " limit "); if (vxi->vxi_limit) nl_dump_line(p, "%u\n", vxi->vxi_limit); else nl_dump_line(p, "unlimited\n"); } if (vxi->ce_mask & VXLAN_ATTR_PORT_RANGE) nl_dump_line(p, " port range %u - %u\n", ntohs(vxi->vxi_port_range.low), ntohs(vxi->vxi_port_range.high)); if (vxi->ce_mask & VXLAN_ATTR_PROXY) { nl_dump(p, " proxy "); if (vxi->vxi_proxy) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_proxy); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_RSC) { nl_dump(p, " rsc "); if (vxi->vxi_rsc) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_rsc); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_L2MISS) { nl_dump(p, " l2miss "); if (vxi->vxi_l2miss) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_l2miss); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_L3MISS) { nl_dump(p, " l3miss "); if (vxi->vxi_l3miss) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_l3miss); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_PORT) { nl_dump(p, " port "); nl_dump_line(p, "%u\n", ntohs(vxi->vxi_port)); } if (vxi->ce_mask & VXLAN_ATTR_UDP_CSUM) { nl_dump(p, " UDP checksums "); if (vxi->vxi_udp_csum) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_csum); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX) { nl_dump(p, " udp-zero-csum6-tx "); if (vxi->vxi_udp_zero_csum6_tx) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_zero_csum6_tx); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX) { nl_dump(p, " udp-zero-csum6-rx "); if (vxi->vxi_udp_zero_csum6_rx) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_zero_csum6_rx); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX) { nl_dump(p, " remcsum-tx "); if (vxi->vxi_remcsum_tx) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_remcsum_tx); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX) { nl_dump(p, " remcsum-rx "); if (vxi->vxi_remcsum_rx) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_remcsum_rx); else nl_dump_line(p, "disabled\n"); } if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GBP) nl_dump(p, " gbp\n"); if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL) nl_dump(p, " rncsum-nopartial\n"); if (vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA) { nl_dump(p, " remcsum-rx "); if (vxi->vxi_collect_metadata) nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_collect_metadata); else nl_dump_line(p, "disabled\n"); } if (vxi->ce_mask & VXLAN_ATTR_LABEL) { nl_dump(p, " label "); nl_dump_line(p, "%u\n", ntohl(vxi->vxi_label)); } if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GPE) nl_dump(p, " gpe\n"); } static int vxlan_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct vxlan_info *vdst, *vsrc = src->l_info; int err; dst->l_info = NULL; if ((err = rtnl_link_set_type(dst, "vxlan")) < 0) return err; vdst = dst->l_info; if (!vdst || !vsrc) return -NLE_NOMEM; memcpy(vdst, vsrc, sizeof(struct vxlan_info)); return 0; } static int vxlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; if (vxi->ce_mask & VXLAN_ATTR_ID) NLA_PUT_U32(msg, IFLA_VXLAN_ID, vxi->vxi_id); if (vxi->ce_mask & VXLAN_ATTR_GROUP) NLA_PUT(msg, IFLA_VXLAN_GROUP, sizeof(vxi->vxi_group), &vxi->vxi_group); if (vxi->ce_mask & VXLAN_ATTR_GROUP6) NLA_PUT(msg, IFLA_VXLAN_GROUP6, sizeof(vxi->vxi_group6), &vxi->vxi_group6); if (vxi->ce_mask & VXLAN_ATTR_LINK) NLA_PUT_U32(msg, IFLA_VXLAN_LINK, vxi->vxi_link); if (vxi->ce_mask & VXLAN_ATTR_LOCAL) NLA_PUT(msg, IFLA_VXLAN_LOCAL, sizeof(vxi->vxi_local), &vxi->vxi_local); if (vxi->ce_mask & VXLAN_ATTR_LOCAL6) NLA_PUT(msg, IFLA_VXLAN_LOCAL6, sizeof(vxi->vxi_local6), &vxi->vxi_local6); if (vxi->ce_mask & VXLAN_ATTR_TTL) NLA_PUT_U8(msg, IFLA_VXLAN_TTL, vxi->vxi_ttl); if (vxi->ce_mask & VXLAN_ATTR_TOS) NLA_PUT_U8(msg, IFLA_VXLAN_TOS, vxi->vxi_tos); if (vxi->ce_mask & VXLAN_ATTR_LEARNING) NLA_PUT_U8(msg, IFLA_VXLAN_LEARNING, vxi->vxi_learning); if (vxi->ce_mask & VXLAN_ATTR_AGEING) NLA_PUT_U32(msg, IFLA_VXLAN_AGEING, vxi->vxi_ageing); if (vxi->ce_mask & VXLAN_ATTR_LIMIT) NLA_PUT_U32(msg, IFLA_VXLAN_LIMIT, vxi->vxi_limit); if (vxi->ce_mask & VXLAN_ATTR_PORT_RANGE) NLA_PUT(msg, IFLA_VXLAN_PORT_RANGE, sizeof(vxi->vxi_port_range), &vxi->vxi_port_range); if (vxi->ce_mask & VXLAN_ATTR_PROXY) NLA_PUT_U8(msg, IFLA_VXLAN_PROXY, vxi->vxi_proxy); if (vxi->ce_mask & VXLAN_ATTR_RSC) NLA_PUT_U8(msg, IFLA_VXLAN_RSC, vxi->vxi_rsc); if (vxi->ce_mask & VXLAN_ATTR_L2MISS) NLA_PUT_U8(msg, IFLA_VXLAN_L2MISS, vxi->vxi_l2miss); if (vxi->ce_mask & VXLAN_ATTR_L3MISS) NLA_PUT_U8(msg, IFLA_VXLAN_L3MISS, vxi->vxi_l3miss); if (vxi->ce_mask & VXLAN_ATTR_PORT) NLA_PUT_U32(msg, IFLA_VXLAN_PORT, vxi->vxi_port); if (vxi->ce_mask & VXLAN_ATTR_UDP_CSUM) NLA_PUT_U8(msg, IFLA_VXLAN_UDP_CSUM, vxi->vxi_udp_csum); if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX) NLA_PUT_U8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, vxi->vxi_udp_zero_csum6_tx); if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX) NLA_PUT_U8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, vxi->vxi_udp_zero_csum6_rx); if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX) NLA_PUT_U8(msg, IFLA_VXLAN_REMCSUM_TX, vxi->vxi_remcsum_tx); if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX) NLA_PUT_U8(msg, IFLA_VXLAN_REMCSUM_RX, vxi->vxi_remcsum_rx); if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GBP) NLA_PUT_FLAG(msg, IFLA_VXLAN_GBP); if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL) NLA_PUT_FLAG(msg, IFLA_VXLAN_REMCSUM_NOPARTIAL); if (vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA) NLA_PUT_U8(msg, IFLA_VXLAN_COLLECT_METADATA, vxi->vxi_collect_metadata); if (vxi->ce_mask & VXLAN_ATTR_LABEL) NLA_PUT_U32(msg, IFLA_VXLAN_LABEL, vxi->vxi_label); if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GPE) NLA_PUT_FLAG(msg, IFLA_VXLAN_GPE); nla_nest_end(msg, data); nla_put_failure: return 0; } static int vxlan_compare(struct rtnl_link *link_a, struct rtnl_link *link_b, int flags) { struct vxlan_info *a = link_a->l_info; struct vxlan_info *b = link_b->l_info; int diff = 0; uint32_t attrs = flags & LOOSE_COMPARISON ? b->ce_mask : ~0; #define VXLAN_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, VXLAN_ATTR_##ATTR, a, b, EXPR) diff |= VXLAN_DIFF(ID, a->vxi_id != b->vxi_id); diff |= VXLAN_DIFF(GROUP, a->vxi_group != b->vxi_group); diff |= VXLAN_DIFF(LINK, a->vxi_link != b->vxi_link); diff |= VXLAN_DIFF(LOCAL, a->vxi_local != b->vxi_local); diff |= VXLAN_DIFF(TOS, a->vxi_tos != b->vxi_tos); diff |= VXLAN_DIFF(TTL, a->vxi_ttl != b->vxi_ttl); diff |= VXLAN_DIFF(LEARNING, a->vxi_learning != b->vxi_learning); diff |= VXLAN_DIFF(AGEING, a->vxi_ageing != b->vxi_ageing); diff |= VXLAN_DIFF(LIMIT, a->vxi_limit != b->vxi_limit); diff |= VXLAN_DIFF(PORT_RANGE, a->vxi_port_range.low != b->vxi_port_range.low); diff |= VXLAN_DIFF(PORT_RANGE, a->vxi_port_range.high != b->vxi_port_range.high); diff |= VXLAN_DIFF(PROXY, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(RSC, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(L2MISS, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(L3MISS, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(PORT, a->vxi_port != b->vxi_port); diff |= VXLAN_DIFF(GROUP6, memcmp(&a->vxi_group6, &b->vxi_group6, sizeof(a->vxi_group6)) != 0); diff |= VXLAN_DIFF(LOCAL6, memcmp(&a->vxi_local6, &b->vxi_local6, sizeof(a->vxi_local6)) != 0); diff |= VXLAN_DIFF(UDP_CSUM, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(UDP_ZERO_CSUM6_TX, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(UDP_ZERO_CSUM6_RX, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(REMCSUM_TX, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(REMCSUM_RX, a->vxi_proxy != b->vxi_proxy); diff |= VXLAN_DIFF(COLLECT_METADATA, a->vxi_collect_metadata != b->vxi_collect_metadata); diff |= VXLAN_DIFF(LABEL, a->vxi_label != b->vxi_label); diff |= VXLAN_DIFF(FLAGS, a->vxi_flags != b->vxi_flags); #undef VXLAN_DIFF return diff; } static struct rtnl_link_info_ops vxlan_info_ops = { .io_name = "vxlan", .io_alloc = vxlan_alloc, .io_parse = vxlan_parse, .io_dump = { [NL_DUMP_LINE] = vxlan_dump_line, [NL_DUMP_DETAILS] = vxlan_dump_details, }, .io_clone = vxlan_clone, .io_put_attrs = vxlan_put_attrs, .io_free = vxlan_free, .io_compare = vxlan_compare, }; /** @cond SKIP */ #define IS_VXLAN_LINK_ASSERT(link) \ if ((link)->l_info_ops != &vxlan_info_ops) { \ APPBUG("Link is not a vxlan link. set type \"vxlan\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ /** * @name VXLAN Object * @{ */ /** * Allocate link object of type VXLAN * * @return Allocated link object or NULL. */ struct rtnl_link *rtnl_link_vxlan_alloc(void) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return NULL; if ((err = rtnl_link_set_type(link, "vxlan")) < 0) { rtnl_link_put(link); return NULL; } return link; } /** * Check if link is a VXLAN link * @arg link Link object * * @return True if link is a VXLAN link, otherwise false is returned. */ int rtnl_link_is_vxlan(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vxlan"); } /** * Set VXLAN Network Identifier * @arg link Link object * @arg id VXLAN network identifier (or VXLAN segment identifier) * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_id(struct rtnl_link *link, uint32_t id) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (id > VXLAN_ID_MAX) return -NLE_INVAL; vxi->vxi_id = id; vxi->ce_mask |= VXLAN_ATTR_ID; return 0; } /** * Get VXLAN Network Identifier * @arg link Link object * @arg id Pointer to store network identifier * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_id(struct rtnl_link *link, uint32_t *id) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if(!id) return -NLE_INVAL; if (vxi->ce_mask & VXLAN_ATTR_ID) *id = vxi->vxi_id; else return -NLE_AGAIN; return 0; } /** * Set VXLAN multicast IP address * @arg link Link object * @arg addr Multicast IP address to join * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_group(struct rtnl_link *link, struct nl_addr *addr) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if ((nl_addr_get_family(addr) == AF_INET) && (nl_addr_get_len(addr) == sizeof(vxi->vxi_group))) { memcpy(&vxi->vxi_group, nl_addr_get_binary_addr(addr), sizeof(vxi->vxi_group)); vxi->ce_mask |= VXLAN_ATTR_GROUP; vxi->ce_mask &= ~VXLAN_ATTR_GROUP6; } else if ((nl_addr_get_family(addr) == AF_INET6) && (nl_addr_get_len(addr) == sizeof(vxi->vxi_group6))) { memcpy(&vxi->vxi_group6, nl_addr_get_binary_addr(addr), sizeof(vxi->vxi_group6)); vxi->ce_mask |= VXLAN_ATTR_GROUP6; vxi->ce_mask &= ~VXLAN_ATTR_GROUP; } else return -NLE_INVAL; return 0; } /** * Get VXLAN multicast IP address * @arg link Link object * @arg addr Pointer to store multicast IP address * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_group(struct rtnl_link *link, struct nl_addr **addr) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!addr) return -NLE_INVAL; if (vxi->ce_mask & VXLAN_ATTR_GROUP) *addr = nl_addr_build(AF_INET, &vxi->vxi_group, sizeof(vxi->vxi_group)); else if (vxi->ce_mask & VXLAN_ATTR_GROUP6) *addr = nl_addr_build(AF_INET6, &vxi->vxi_group6, sizeof(vxi->vxi_group6)); else return -NLE_AGAIN; return 0; } /** * Set physical device to use for VXLAN * @arg link Link object * @arg index Interface index * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_link(struct rtnl_link *link, uint32_t index) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_link = index; vxi->ce_mask |= VXLAN_ATTR_LINK; return 0; } /** * Get physical device to use for VXLAN * @arg link Link object * @arg index Pointer to store interface index * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_link(struct rtnl_link *link, uint32_t *index) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!index) return -NLE_INVAL; if (!(vxi->ce_mask & VXLAN_ATTR_LINK)) return -NLE_AGAIN; *index = vxi->vxi_link; return 0; } /** * Set source address to use for VXLAN * @arg link Link object * @arg addr Local address * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_local(struct rtnl_link *link, struct nl_addr *addr) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if ((nl_addr_get_family(addr) == AF_INET) && (nl_addr_get_len(addr) == sizeof(vxi->vxi_local))) { memcpy(&vxi->vxi_local, nl_addr_get_binary_addr(addr), sizeof(vxi->vxi_local)); vxi->ce_mask |= VXLAN_ATTR_LOCAL; vxi->ce_mask &= VXLAN_ATTR_LOCAL6; } else if ((nl_addr_get_family(addr) == AF_INET6) && (nl_addr_get_len(addr) == sizeof(vxi->vxi_local6))) { memcpy(&vxi->vxi_local6, nl_addr_get_binary_addr(addr), sizeof(vxi->vxi_local6)); vxi->ce_mask |= VXLAN_ATTR_LOCAL6; vxi->ce_mask &= ~VXLAN_ATTR_LOCAL; } else return -NLE_INVAL; return 0; } /** * Get source address to use for VXLAN * @arg link Link object * @arg addr Pointer to store local address * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_local(struct rtnl_link *link, struct nl_addr **addr) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!addr) return -NLE_INVAL; if (vxi->ce_mask & VXLAN_ATTR_LOCAL) *addr = nl_addr_build(AF_INET, &vxi->vxi_local, sizeof(vxi->vxi_local)); else if (vxi->ce_mask & VXLAN_ATTR_LOCAL6) *addr = nl_addr_build(AF_INET6, &vxi->vxi_local6, sizeof(vxi->vxi_local6)); else return -NLE_AGAIN; return 0; } /** * Set IP TTL value to use for VXLAN * @arg link Link object * @arg ttl TTL value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_ttl(struct rtnl_link *link, uint8_t ttl) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_ttl = ttl; vxi->ce_mask |= VXLAN_ATTR_TTL; return 0; } /** * Get IP TTL value to use for VXLAN * @arg link Link object * * @return TTL value on success or a negative error code */ int rtnl_link_vxlan_get_ttl(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_TTL)) return -NLE_AGAIN; return vxi->vxi_ttl; } /** * Set IP ToS value to use for VXLAN * @arg link Link object * @arg tos ToS value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_tos(struct rtnl_link *link, uint8_t tos) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_tos = tos; vxi->ce_mask |= VXLAN_ATTR_TOS; return 0; } /** * Get IP ToS value to use for VXLAN * @arg link Link object * * @return ToS value on success or a negative error code */ int rtnl_link_vxlan_get_tos(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_TOS)) return -NLE_AGAIN; return vxi->vxi_tos; } /** * Set VXLAN learning status * @arg link Link object * @arg learning Learning status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_learning(struct rtnl_link *link, uint8_t learning) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_learning = learning; vxi->ce_mask |= VXLAN_ATTR_LEARNING; return 0; } /** * Get VXLAN learning status * @arg link Link object * * @return Learning status value on success or a negative error code */ int rtnl_link_vxlan_get_learning(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_LEARNING)) return -NLE_AGAIN; return vxi->vxi_learning; } /** * Enable VXLAN address learning * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_enable_learning(struct rtnl_link *link) { return rtnl_link_vxlan_set_learning(link, 1); } /** * Disable VXLAN address learning * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_disable_learning(struct rtnl_link *link) { return rtnl_link_vxlan_set_learning(link, 0); } /** * Set expiration timer value to use for VXLAN * @arg link Link object * @arg expiry Expiration timer value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_ageing(struct rtnl_link *link, uint32_t expiry) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_ageing = expiry; vxi->ce_mask |= VXLAN_ATTR_AGEING; return 0; } /** * Get expiration timer value to use for VXLAN * @arg link Link object * @arg expiry Pointer to store expiration timer value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_ageing(struct rtnl_link *link, uint32_t *expiry) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!expiry) return -NLE_INVAL; if (vxi->ce_mask & VXLAN_ATTR_AGEING) *expiry = vxi->vxi_ageing; else return -NLE_AGAIN; return 0; } /** * Set maximum number of forwarding database entries to use for VXLAN * @arg link Link object * @arg limit Maximum number * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_limit(struct rtnl_link *link, uint32_t limit) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_limit = limit; vxi->ce_mask |= VXLAN_ATTR_LIMIT; return 0; } /** * Get maximum number of forwarding database entries to use for VXLAN * @arg link Link object * @arg limit Pointer to store maximum number * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_limit(struct rtnl_link *link, uint32_t *limit) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!limit) return -NLE_INVAL; if (vxi->ce_mask & VXLAN_ATTR_LIMIT) *limit = vxi->vxi_limit; else return -NLE_AGAIN; return 0; } /** * Set range of UDP port numbers to use for VXLAN * @arg link Link object * @arg range Port number range * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_port_range(struct rtnl_link *link, struct ifla_vxlan_port_range *range) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!range) return -NLE_INVAL; memcpy(&vxi->vxi_port_range, range, sizeof(vxi->vxi_port_range)); vxi->ce_mask |= VXLAN_ATTR_PORT_RANGE; return 0; } /** * Get range of UDP port numbers to use for VXLAN * @arg link Link object * @arg range Pointer to store port range * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_port_range(struct rtnl_link *link, struct ifla_vxlan_port_range *range) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!range) return -NLE_INVAL; if (vxi->ce_mask & VXLAN_ATTR_PORT_RANGE) memcpy(range, &vxi->vxi_port_range, sizeof(*range)); else return -NLE_AGAIN; return 0; } /** * Set ARP proxy status to use for VXLAN * @arg link Link object * @arg proxy Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_proxy(struct rtnl_link *link, uint8_t proxy) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_proxy = proxy; vxi->ce_mask |= VXLAN_ATTR_PROXY; return 0; } /** * Get ARP proxy status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_proxy(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_PROXY)) return -NLE_AGAIN; return vxi->vxi_proxy; } /** * Enable ARP proxy * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_enable_proxy(struct rtnl_link *link) { return rtnl_link_vxlan_set_proxy(link, 1); } /** * Disable ARP proxy * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_disable_proxy(struct rtnl_link *link) { return rtnl_link_vxlan_set_proxy(link, 0); } /** * Set Route Short Circuit status to use for VXLAN * @arg link Link object * @arg rsc Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_rsc(struct rtnl_link *link, uint8_t rsc) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_rsc = rsc; vxi->ce_mask |= VXLAN_ATTR_RSC; return 0; } /** * Get Route Short Circuit status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_rsc(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_RSC)) return -NLE_AGAIN; return vxi->vxi_rsc; } /** * Enable Route Short Circuit * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_enable_rsc(struct rtnl_link *link) { return rtnl_link_vxlan_set_rsc(link, 1); } /** * Disable Route Short Circuit * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_disable_rsc(struct rtnl_link *link) { return rtnl_link_vxlan_set_rsc(link, 0); } /** * Set netlink LLADDR miss notification status to use for VXLAN * @arg link Link object * @arg miss Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_l2miss(struct rtnl_link *link, uint8_t miss) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_l2miss = miss; vxi->ce_mask |= VXLAN_ATTR_L2MISS; return 0; } /** * Get netlink LLADDR miss notification status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_l2miss(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_L2MISS)) return -NLE_AGAIN; return vxi->vxi_l2miss; } /** * Enable netlink LLADDR miss notifications * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_enable_l2miss(struct rtnl_link *link) { return rtnl_link_vxlan_set_l2miss(link, 1); } /** * Disable netlink LLADDR miss notifications * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_disable_l2miss(struct rtnl_link *link) { return rtnl_link_vxlan_set_l2miss(link, 0); } /** * Set netlink IP ADDR miss notification status to use for VXLAN * @arg link Link object * @arg miss Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_l3miss(struct rtnl_link *link, uint8_t miss) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_l3miss = miss; vxi->ce_mask |= VXLAN_ATTR_L3MISS; return 0; } /** * Get netlink IP ADDR miss notification status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_l3miss(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_L3MISS)) return -NLE_AGAIN; return vxi->vxi_l3miss; } /** * Enable netlink IP ADDR miss notifications * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_enable_l3miss(struct rtnl_link *link) { return rtnl_link_vxlan_set_l3miss(link, 1); } /** * Disable netlink IP ADDR miss notifications * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_disable_l3miss(struct rtnl_link *link) { return rtnl_link_vxlan_set_l3miss(link, 0); } /** * Set UDP destination port to use for VXLAN * @arg link Link object * @arg port Destination port * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_port(struct rtnl_link *link, uint32_t port) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_port = htons(port); vxi->ce_mask |= VXLAN_ATTR_PORT; return 0; } /** * Get UDP destination port to use for VXLAN * @arg link Link object * @arg port Pointer to store destination port * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_port(struct rtnl_link *link, uint32_t *port) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!port) return -NLE_INVAL; if (!(vxi->ce_mask & VXLAN_ATTR_PORT)) return -NLE_NOATTR; *port = ntohs(vxi->vxi_port); return 0; } /** * Set UDP checksum status to use for VXLAN * @arg link Link object * @arg csum Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_udp_csum(struct rtnl_link *link, uint8_t csum) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_udp_csum = csum; vxi->ce_mask |= VXLAN_ATTR_UDP_CSUM; return 0; } /** * Get UDP checksum status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_udp_csum(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_UDP_CSUM)) return -NLE_NOATTR; return vxi->vxi_udp_csum; } /** * Set skip UDP checksum transmitted over IPv6 status to use for VXLAN * @arg link Link object * @arg csum Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_udp_zero_csum6_tx(struct rtnl_link *link, uint8_t csum) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_udp_zero_csum6_tx = csum; vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_TX; return 0; } /** * Get skip UDP checksum transmitted over IPv6 status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_udp_zero_csum6_tx(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX)) return -NLE_NOATTR; return vxi->vxi_udp_zero_csum6_tx; } /** * Set skip UDP checksum received over IPv6 status to use for VXLAN * @arg link Link object * @arg csum Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_udp_zero_csum6_rx(struct rtnl_link *link, uint8_t csum) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_udp_zero_csum6_rx = csum; vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_RX; return 0; } /** * Get skip UDP checksum received over IPv6 status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_udp_zero_csum6_rx(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX)) return -NLE_NOATTR; return vxi->vxi_udp_zero_csum6_rx; } /** * Set remote offload transmit checksum status to use for VXLAN * @arg link Link object * @arg csum Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_remcsum_tx(struct rtnl_link *link, uint8_t csum) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_remcsum_tx = csum; vxi->ce_mask |= VXLAN_ATTR_REMCSUM_TX; return 0; } /** * Get remote offload transmit checksum status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_remcsum_tx(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX)) return -NLE_NOATTR; return vxi->vxi_remcsum_tx; } /** * Set remote offload receive checksum status to use for VXLAN * @arg link Link object * @arg csum Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_remcsum_rx(struct rtnl_link *link, uint8_t csum) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_remcsum_rx = csum; vxi->ce_mask |= VXLAN_ATTR_REMCSUM_RX; return 0; } /** * Get remote offload receive checksum status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_remcsum_rx(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX)) return -NLE_NOATTR; return vxi->vxi_remcsum_rx; } /** * Set collect metadata status to use for VXLAN * @arg link Link object * @arg collect Status value * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_collect_metadata(struct rtnl_link *link, uint8_t collect) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_collect_metadata = collect; vxi->ce_mask |= VXLAN_ATTR_COLLECT_METADATA; return 0; } /** * Get collect metadata status to use for VXLAN * @arg link Link object * * @return Status value on success or a negative error code */ int rtnl_link_vxlan_get_collect_metadata(struct rtnl_link *link) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!(vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA)) return -NLE_NOATTR; return vxi->vxi_collect_metadata; } /** * Set flow label to use for VXLAN * @arg link Link object * @arg label Destination label * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_label(struct rtnl_link *link, uint32_t label) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); vxi->vxi_label = htonl(label); vxi->ce_mask |= VXLAN_ATTR_LABEL; return 0; } /** * Get flow label to use for VXLAN * @arg link Link object * @arg label Pointer to store destination label * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_get_label(struct rtnl_link *link, uint32_t *label) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (!label) return -NLE_INVAL; if (!(vxi->ce_mask & VXLAN_ATTR_LABEL)) return -NLE_NOATTR; *label = ntohl(vxi->vxi_label); return 0; } /** * Set VXLAN flags RTNL_LINK_VXLAN_F_* * @arg link Link object * @flags Which flags to set * @arg enable Boolean enabling or disabling flag * * @return 0 on success or a negative error code */ int rtnl_link_vxlan_set_flags(struct rtnl_link *link, uint32_t flags, int enable) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); if (flags & ~(RTNL_LINK_VXLAN_F_GBP | RTNL_LINK_VXLAN_F_GPE | RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL)) return -NLE_INVAL; if (enable) vxi->vxi_flags |= flags; else vxi->vxi_flags &= ~flags; return 0; } /** * Get VXLAN flags RTNL_LINK_VXLAN_F_* * @arg link Link object * @arg out_flags Output value for flags. Must be present. * * @return Zero on success or a negative error code */ int rtnl_link_vxlan_get_flags(struct rtnl_link *link, uint32_t *out_flags) { struct vxlan_info *vxi = link->l_info; IS_VXLAN_LINK_ASSERT(link); *out_flags = vxi->vxi_flags; return 0; } /** @} */ static void __init vxlan_init(void) { rtnl_link_register_info(&vxlan_info_ops); } static void __exit vxlan_exit(void) { rtnl_link_unregister_info(&vxlan_info_ops); } /** @} */ libnl-3.2.29/lib/route/link/sriov.c0000644000175000017500000011214213023014600013765 00000000000000/* * lib/route/link/sriov.c SRIOV VF Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Intel Corp. All rights reserved. * Copyright (c) 2016 Jef Oliver */ /** * @ingroup link * @defgroup sriov SRIOV * SR-IOV VF link module * * @details * SR-IOV (Single Root Input/Output Virtualization) is a network interface * that allows for the isolation of the PCI Express resources. In a virtual * environment, SR-IOV allows multiple virtual machines can share a single * PCI Express hardware interface. This is done via VFs (Virtual Functions), * virtual hardware devices with their own PCI address. * * @{ */ #include #include #include #include #include #include #include #include /** @cond SKIP */ #define SRIOVON "on" #define SRIOVOFF "off" #define SET_VF_STAT(link, vf_num, stb, stat, attr) \ vf_data->vf_stats[stat] = nla_get_u64(stb[attr]) /* SRIOV-VF Attributes */ #define SRIOV_ATTR_INDEX (1 << 0) #define SRIOV_ATTR_ADDR (1 << 1) #define SRIOV_ATTR_VLAN (1 << 2) #define SRIOV_ATTR_TX_RATE (1 << 3) #define SRIOV_ATTR_SPOOFCHK (1 << 4) #define SRIOV_ATTR_RATE_MAX (1 << 5) #define SRIOV_ATTR_RATE_MIN (1 << 6) #define SRIOV_ATTR_LINK_STATE (1 << 7) #define SRIOV_ATTR_RSS_QUERY_EN (1 << 8) #define SRIOV_ATTR_STATS (1 << 9) #define SRIOV_ATTR_TRUST (1 << 10) #define SRIOV_ATTR_IB_NODE_GUID (1 << 11) #define SRIOV_ATTR_IB_PORT_GUID (1 << 12) static struct nla_policy sriov_info_policy[IFLA_VF_MAX+1] = { [IFLA_VF_MAC] = { .minlen = sizeof(struct ifla_vf_mac) }, [IFLA_VF_VLAN] = { .minlen = sizeof(struct ifla_vf_vlan) }, [IFLA_VF_VLAN_LIST] = { .type = NLA_NESTED }, [IFLA_VF_TX_RATE] = { .minlen = sizeof(struct ifla_vf_tx_rate) }, [IFLA_VF_SPOOFCHK] = { .minlen = sizeof(struct ifla_vf_spoofchk) }, [IFLA_VF_RATE] = { .minlen = sizeof(struct ifla_vf_rate) }, [IFLA_VF_LINK_STATE] = { .minlen = sizeof(struct ifla_vf_link_state) }, [IFLA_VF_RSS_QUERY_EN] = { .minlen = sizeof(struct ifla_vf_rss_query_en) }, [IFLA_VF_STATS] = { .type = NLA_NESTED }, [IFLA_VF_TRUST] = { .minlen = sizeof(struct ifla_vf_trust) }, [IFLA_VF_IB_NODE_GUID] = { .minlen = sizeof(struct ifla_vf_guid) }, [IFLA_VF_IB_PORT_GUID] = { .minlen = sizeof(struct ifla_vf_guid) }, }; static struct nla_policy sriov_stats_policy[IFLA_VF_STATS_MAX+1] = { [IFLA_VF_STATS_RX_PACKETS] = { .type = NLA_U64 }, [IFLA_VF_STATS_TX_PACKETS] = { .type = NLA_U64 }, [IFLA_VF_STATS_RX_BYTES] = { .type = NLA_U64 }, [IFLA_VF_STATS_TX_BYTES] = { .type = NLA_U64 }, [IFLA_VF_STATS_BROADCAST] = { .type = NLA_U64 }, [IFLA_VF_STATS_MULTICAST] = { .type = NLA_U64 }, }; /** @endcond */ /* Clone SRIOV VF list in link object */ int rtnl_link_sriov_clone(struct rtnl_link *dst, struct rtnl_link *src) { int err = 0; struct nl_addr *vf_addr; struct rtnl_link_vf *s_list, *d_vf, *s_vf, *next, *dest_h = NULL; nl_vf_vlans_t *src_vlans = NULL, *dst_vlans = NULL; nl_vf_vlan_info_t *src_vlan_info = NULL, *dst_vlan_info = NULL; if (!(err = rtnl_link_has_vf_list(src))) return 0; dst->l_vf_list = rtnl_link_vf_alloc(); if (!dst->l_vf_list) return -NLE_NOMEM; dest_h = dst->l_vf_list; s_list = src->l_vf_list; nl_list_for_each_entry_safe(s_vf, next, &s_list->vf_list, vf_list) { if (!(d_vf = rtnl_link_vf_alloc())) return -NLE_NOMEM; memcpy(d_vf, s_vf, sizeof(*s_vf)); if (s_vf->ce_mask & SRIOV_ATTR_ADDR) { vf_addr = nl_addr_clone(s_vf->vf_lladdr); if (!vf_addr) return -NLE_NOMEM; d_vf->vf_lladdr = vf_addr; } if (s_vf->ce_mask & SRIOV_ATTR_VLAN) { src_vlans = s_vf->vf_vlans; src_vlan_info = src_vlans->vlans; err = rtnl_link_vf_vlan_alloc(&dst_vlans, src_vlans->size); if (err < 0) return err; dst_vlan_info = dst_vlans->vlans; memcpy(dst_vlans, src_vlans, sizeof(nl_vf_vlans_t)); memcpy(dst_vlan_info, src_vlan_info, dst_vlans->size * sizeof(dst_vlan_info)); d_vf->vf_vlans = dst_vlans; } nl_list_add_head(&d_vf->vf_list, &dest_h->vf_list); dest_h = d_vf; } return 0; } /* Dump VLAN details for each SRIOV VF */ static void dump_sriov_vlans(nl_vf_vlans_t *vlans, struct nl_dump_params *p) { char buf[64]; int cur = 0; nl_vf_vlan_info_t *vlan_data; uint16_t prot; vlan_data = vlans->vlans; nl_dump(p, "\t VLANS:\n"); while (cur < vlans->size) { nl_dump(p, "\t vlan %u", vlan_data[cur].vf_vlan); if (vlan_data[cur].vf_vlan_qos) nl_dump(p, " qos %u", vlan_data[cur].vf_vlan_qos); if (vlan_data[cur].vf_vlan_proto) { prot = vlan_data[cur].vf_vlan_proto; nl_dump(p, " proto %s", rtnl_link_vf_vlanproto2str(prot, buf, sizeof(buf))); } nl_dump(p, "\n"); cur++; } return; } /* Dump details for each SRIOV VF */ static void dump_vf_details(struct rtnl_link_vf *vf_data, struct nl_dump_params *p) { char buf[64]; int err = 0; struct nl_vf_rate vf_rate; uint32_t v = 0; nl_dump(p, "\tvf %u: ", vf_data->vf_index); if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) { v = vf_data->vf_linkstate; nl_dump(p, "state %s ", rtnl_link_vf_linkstate2str(v, buf, sizeof(buf))); } if (vf_data->ce_mask & SRIOV_ATTR_ADDR) { nl_dump(p, "addr %s ", nl_addr2str(vf_data->vf_lladdr, buf, sizeof(buf))); } nl_dump(p, "\n"); v = vf_data->vf_spoofchk; nl_dump(p, "\t spoofchk %s ", v ? SRIOVON : SRIOVOFF); v = vf_data->vf_trust; nl_dump(p, "trust %s ", v ? SRIOVON : SRIOVOFF); v = vf_data->vf_rss_query_en; nl_dump(p, "rss_query %s\n", v ? SRIOVON : SRIOVOFF); err = rtnl_link_vf_get_rate(vf_data, &vf_rate); if (!err) { if (vf_rate.api == RTNL_LINK_VF_RATE_API_OLD) nl_dump(p, "\t rate_api old rate %u\n", vf_rate.rate); else if (vf_rate.api == RTNL_LINK_VF_RATE_API_NEW) nl_dump(p, "\t rate_api new min_rate %u " "max_rate %u\n", vf_rate.min_tx_rate, vf_rate.max_tx_rate); } if (vf_data->ce_mask & SRIOV_ATTR_VLAN) dump_sriov_vlans(vf_data->vf_vlans, p); return; } /* Loop through SRIOV VF list dump details */ void rtnl_link_sriov_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { int err; struct rtnl_link_vf *vf_data, *list, *next; if (!(err = rtnl_link_has_vf_list(link))) BUG(); nl_dump(p, " SRIOV VF List\n"); list = link->l_vf_list; nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) { if (vf_data->ce_mask & SRIOV_ATTR_INDEX) dump_vf_details(vf_data, p); } return; } /* Dump stats for each SRIOV VF */ static void dump_vf_stats(struct rtnl_link_vf *vf_data, struct nl_dump_params *p) { char *unit; float res; nl_dump(p, " VF %" PRIu64 " Stats:\n", vf_data->vf_index); nl_dump_line(p, "\tRX: %-14s %-10s %-10s %-10s\n", "bytes", "packets", "multicast", "broadcast"); res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_BYTES], &unit); nl_dump_line(p, "\t%10.2f %3s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", res, unit, vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_PACKETS], vf_data->vf_stats[RTNL_LINK_VF_STATS_MULTICAST], vf_data->vf_stats[RTNL_LINK_VF_STATS_BROADCAST]); nl_dump_line(p, "\tTX: %-14s %-10s\n", "bytes", "packets"); res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_BYTES], &unit); nl_dump_line(p, "\t%10.2f %3s %10" PRIu64 "\n", res, unit, vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_PACKETS]); return; } /* Loop through SRIOV VF list dump stats */ void rtnl_link_sriov_dump_stats(struct rtnl_link *link, struct nl_dump_params *p) { struct rtnl_link_vf *vf_data, *list, *next; list = link->l_vf_list; nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) { if (vf_data->ce_mask & SRIOV_ATTR_INDEX) dump_vf_stats(vf_data, p); } nl_dump(p, "\n"); return; } /* Free stored SRIOV VF data */ void rtnl_link_sriov_free_data(struct rtnl_link *link) { int err = 0; struct rtnl_link_vf *list, *vf, *next; if (!(err = rtnl_link_has_vf_list(link))) return; list = link->l_vf_list; nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) { nl_list_del(&vf->vf_list); rtnl_link_vf_put(vf); } rtnl_link_vf_put(link->l_vf_list); return; } /* Fill VLAN info array */ static int rtnl_link_vf_vlan_info(int len, struct ifla_vf_vlan_info **vi, nl_vf_vlans_t **nvi) { int cur = 0, err; nl_vf_vlans_t *vlans; if (len <= 0) return 0; if ((err = rtnl_link_vf_vlan_alloc(&vlans, len)) < 0) return err; cur = 0; while (cur < len) { vlans->vlans[cur].vf_vlan = vi[cur]->vlan ? vi[cur]->vlan : 0; vlans->vlans[cur].vf_vlan_qos = vi[cur]->qos ? vi[cur]->qos : 0; if (vi[cur]->vlan_proto) { vlans->vlans[cur].vf_vlan_proto = ntohs(vi[cur]->vlan_proto); } else { vlans->vlans[cur].vf_vlan_proto = ETH_P_8021Q; } cur++; } *nvi = vlans; return 0; } /* Fill the IFLA_VF_VLAN attribute */ static void sriov_fill_vf_vlan(struct nl_msg *msg, nl_vf_vlan_info_t *vinfo, uint32_t index) { struct ifla_vf_vlan vlan; vlan.vf = index; vlan.vlan = vinfo[0].vf_vlan; vlan.qos = vinfo[0].vf_vlan_qos; NLA_PUT(msg, IFLA_VF_VLAN, sizeof(vlan), &vlan); nla_put_failure: return; } /* Fill the IFLA_VF_VLAN_LIST attribute */ static int sriov_fill_vf_vlan_list(struct nl_msg *msg, nl_vf_vlans_t *vlans, uint32_t index) { int cur = 0; nl_vf_vlan_info_t *vlan_info = vlans->vlans; struct ifla_vf_vlan_info vlan; struct nlattr *list; if (!(list = nla_nest_start(msg, IFLA_VF_VLAN_LIST))) return -NLE_MSGSIZE; vlan.vf = index; while (cur < vlans->size) { vlan.vlan = vlan_info[cur].vf_vlan; vlan.qos = vlan_info[cur].vf_vlan_qos; vlan.vlan_proto = vlan_info[cur].vf_vlan_proto; NLA_PUT(msg, IFLA_VF_VLAN_INFO, sizeof(vlan), &vlan); cur++; } nla_put_failure: nla_nest_end(msg, list); return 0; } /* Fill individual IFLA_VF_INFO attributes */ static int sriov_fill_vfinfo(struct nl_msg *msg, struct rtnl_link_vf *vf_data) { int err = 0, new_rate = 0; nl_vf_vlans_t *vlan_list; nl_vf_vlan_info_t *vlan_info; struct ifla_vf_guid vf_node_guid; struct ifla_vf_guid vf_port_guid; struct ifla_vf_link_state vf_link_state; struct ifla_vf_mac vf_mac; struct ifla_vf_rate new_vf_rate; struct ifla_vf_rss_query_en vf_rss_query_en; struct ifla_vf_spoofchk vf_spoofchk; struct ifla_vf_trust vf_trust; struct ifla_vf_tx_rate vf_rate; struct nlattr *list; uint16_t proto; if (!(vf_data->ce_mask & SRIOV_ATTR_INDEX)) return -NLE_MISSING_ATTR; if (!(list = nla_nest_start(msg, IFLA_VF_INFO))) return -NLE_MSGSIZE; /* IFLA_VF_MAC */ if (vf_data->ce_mask & SRIOV_ATTR_ADDR) { vf_mac.vf = vf_data->vf_index; memset(vf_mac.mac, 0, sizeof(vf_mac.mac)); memcpy(vf_mac.mac, nl_addr_get_binary_addr(vf_data->vf_lladdr), nl_addr_get_len(vf_data->vf_lladdr)); NLA_PUT(msg, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac); } /* IFLA_VF_VLAN IFLA_VF_VLAN_LIST */ if (vf_data->ce_mask & SRIOV_ATTR_VLAN) { vlan_list = vf_data->vf_vlans; vlan_info = vlan_list->vlans; proto = vlan_info[0].vf_vlan_proto; if (!proto) proto = ETH_P_8021Q; if ((vlan_list->size == 1) && (proto == ETH_P_8021Q)) sriov_fill_vf_vlan(msg, vlan_info, vf_data->vf_index); else err = sriov_fill_vf_vlan_list(msg, vlan_list, vf_data->vf_index); } /* IFLA_VF_TX_RATE */ if (vf_data->ce_mask & SRIOV_ATTR_TX_RATE) { vf_rate.vf = vf_data->vf_index; vf_rate.rate = vf_data->vf_rate; NLA_PUT(msg, IFLA_VF_TX_RATE, sizeof(vf_rate), &vf_rate); } /* IFLA_VF_RATE */ new_vf_rate.min_tx_rate = 0; new_vf_rate.max_tx_rate = 0; new_vf_rate.vf = vf_data->vf_index; if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) { new_vf_rate.min_tx_rate = vf_data->vf_min_tx_rate; new_rate = 1; } if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) { new_vf_rate.max_tx_rate = vf_data->vf_max_tx_rate; new_rate = 1; } if (new_rate) NLA_PUT(msg, IFLA_VF_RATE, sizeof(new_vf_rate), &new_vf_rate); /* IFLA_VF_SPOOFCHK */ if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK) { vf_spoofchk.vf = vf_data->vf_index; vf_spoofchk.setting = vf_data->vf_spoofchk; NLA_PUT(msg, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), &vf_spoofchk); } /* IFLA_VF_LINK_STATE */ if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) { vf_link_state.vf = vf_data->vf_index; vf_link_state.link_state = vf_data->vf_linkstate; NLA_PUT(msg, IFLA_VF_LINK_STATE, sizeof(vf_link_state), &vf_link_state); } /* IFLA_VF_RSS_QUERY_EN */ if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN) { vf_rss_query_en.vf = vf_data->vf_index; vf_rss_query_en.setting = vf_data->vf_rss_query_en; NLA_PUT(msg, IFLA_VF_RSS_QUERY_EN, sizeof(vf_rss_query_en), &vf_rss_query_en); } /* IFLA_VF_TRUST */ if (vf_data->ce_mask & SRIOV_ATTR_TRUST) { vf_trust.vf = vf_data->vf_index; vf_trust.setting = vf_data->vf_trust; NLA_PUT(msg, IFLA_VF_TRUST, sizeof(vf_trust), &vf_trust); } /* IFLA_VF_IB_NODE_GUID */ if (vf_data->ce_mask & SRIOV_ATTR_IB_NODE_GUID) { vf_node_guid.vf = vf_data->vf_index; vf_node_guid.guid = vf_data->vf_guid_node; NLA_PUT(msg, IFLA_VF_IB_NODE_GUID, sizeof(vf_node_guid), &vf_node_guid); } /* IFLA_VF_IB_PORT_GUID */ if (vf_data->ce_mask & SRIOV_ATTR_IB_PORT_GUID) { vf_port_guid.vf = vf_data->vf_index; vf_port_guid.guid = vf_data->vf_guid_port; NLA_PUT(msg, IFLA_VF_IB_PORT_GUID, sizeof(vf_port_guid), &vf_port_guid); } nla_put_failure: nla_nest_end(msg, list); return err; } /* Fill the IFLA_VFINFO_LIST attribute */ int rtnl_link_sriov_fill_vflist(struct nl_msg *msg, struct rtnl_link *link) { int err = 0; struct nlattr *data; struct rtnl_link_vf *list, *vf, *next; if (!(err = rtnl_link_has_vf_list(link))) return 0; if (!(data = nla_nest_start(msg, IFLA_VFINFO_LIST))) return -NLE_MSGSIZE; list = link->l_vf_list; nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) { if (vf->ce_mask & SRIOV_ATTR_INDEX) { if ((err = sriov_fill_vfinfo(msg, vf)) < 0) goto nla_nest_list_failure; } } nla_nest_list_failure: nla_nest_end(msg, data); return err; } /* Parse IFLA_VFINFO_LIST and IFLA_VF_INFO attributes */ int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) { int err, len, list_len, list_rem; struct ifla_vf_mac *vf_lladdr; struct ifla_vf_vlan *vf_vlan; struct ifla_vf_vlan_info *vf_vlan_info[MAX_VLAN_LIST_LEN]; struct ifla_vf_tx_rate *vf_tx_rate; struct ifla_vf_spoofchk *vf_spoofchk; struct ifla_vf_link_state *vf_linkstate; struct ifla_vf_rate *vf_rate; struct ifla_vf_rss_query_en *vf_rss_query; struct ifla_vf_trust *vf_trust; struct nlattr *nla, *nla_list, *t[IFLA_VF_MAX+1], *stb[RTNL_LINK_VF_STATS_MAX+1]; nl_vf_vlans_t *vf_vlans = NULL; struct rtnl_link_vf *vf_data, *vf_head = NULL; len = nla_len(tb[IFLA_VFINFO_LIST]); link->l_vf_list = rtnl_link_vf_alloc(); if (!link->l_vf_list) return -NLE_NOMEM; vf_head = link->l_vf_list; for (nla = nla_data(tb[IFLA_VFINFO_LIST]); nla_ok(nla, len); nla = nla_next(nla, &len)) { err = nla_parse(t, IFLA_VF_MAX, nla_data(nla), nla_len(nla), sriov_info_policy); if (err < 0) return err; vf_data = rtnl_link_vf_alloc(); if (!vf_data) return -NLE_NOMEM; if (t[IFLA_VF_MAC]) { vf_lladdr = nla_data(t[IFLA_VF_MAC]); vf_data->vf_index = vf_lladdr->vf; vf_data->ce_mask |= SRIOV_ATTR_INDEX; vf_data->vf_lladdr = nl_addr_build(AF_LLC, vf_lladdr->mac, 6); if (vf_data->vf_lladdr == NULL) return -NLE_NOMEM; nl_addr_set_family(vf_data->vf_lladdr, AF_LLC); vf_data->ce_mask |= SRIOV_ATTR_ADDR; } if (t[IFLA_VF_VLAN_LIST]) { list_len = 0; nla_for_each_nested(nla_list, t[IFLA_VF_VLAN_LIST], list_rem) { vf_vlan_info[len] = nla_data(nla_list); list_len++; } err = rtnl_link_vf_vlan_info(list_len, vf_vlan_info, &vf_vlans); if (err < 0) return err; vf_data->vf_vlans = vf_vlans; vf_data->ce_mask |= SRIOV_ATTR_VLAN; } else if (t[IFLA_VF_VLAN]) { vf_vlan = nla_data(t[IFLA_VF_VLAN]); if (vf_vlan->vlan) { err = rtnl_link_vf_vlan_alloc(&vf_vlans, 1); if (err < 0) return err; vf_vlans->vlans[0].vf_vlan = vf_vlan->vlan; vf_vlans->vlans[0].vf_vlan_qos = vf_vlan->qos; vf_vlans->vlans[0].vf_vlan_proto = ETH_P_8021Q; vf_data->vf_vlans = vf_vlans; vf_data->ce_mask |= SRIOV_ATTR_VLAN; } } if (t[IFLA_VF_TX_RATE]) { vf_tx_rate = nla_data(t[IFLA_VF_TX_RATE]); if (vf_tx_rate->rate) { vf_data->vf_rate = vf_tx_rate->rate; vf_data->ce_mask |= SRIOV_ATTR_TX_RATE; } } if (t[IFLA_VF_SPOOFCHK]) { vf_spoofchk = nla_data(t[IFLA_VF_SPOOFCHK]); if (vf_spoofchk->setting != -1) { vf_data->vf_spoofchk = vf_spoofchk->setting ? 1 : 0; vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK; } } if (t[IFLA_VF_LINK_STATE]) { vf_linkstate = nla_data(t[IFLA_VF_LINK_STATE]); vf_data->vf_linkstate = vf_linkstate->link_state; vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE; } if (t[IFLA_VF_RATE]) { vf_rate = nla_data(t[IFLA_VF_RATE]); if (vf_rate->max_tx_rate) { vf_data->vf_max_tx_rate = vf_rate->max_tx_rate; vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX; } if (vf_rate->min_tx_rate) { vf_data->vf_min_tx_rate = vf_rate->min_tx_rate; vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN; } } if (t[IFLA_VF_RSS_QUERY_EN]) { vf_rss_query = nla_data(t[IFLA_VF_RSS_QUERY_EN]); if (vf_rss_query->setting != -1) { vf_data->vf_rss_query_en = vf_rss_query->setting ? 1 : 0; vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN; } } if (t[IFLA_VF_STATS]) { err = nla_parse_nested(stb, IFLA_VF_STATS_MAX, t[IFLA_VF_STATS], sriov_stats_policy); if (err < 0) return err; SET_VF_STAT(link, cur, stb, RTNL_LINK_VF_STATS_RX_PACKETS, IFLA_VF_STATS_RX_PACKETS); SET_VF_STAT(link, cur, stb, RTNL_LINK_VF_STATS_TX_PACKETS, IFLA_VF_STATS_TX_PACKETS); SET_VF_STAT(link, cur, stb, RTNL_LINK_VF_STATS_RX_BYTES, IFLA_VF_STATS_RX_BYTES); SET_VF_STAT(link, cur, stb, RTNL_LINK_VF_STATS_TX_BYTES, IFLA_VF_STATS_TX_BYTES); SET_VF_STAT(link, cur, stb, RTNL_LINK_VF_STATS_BROADCAST, IFLA_VF_STATS_BROADCAST); SET_VF_STAT(link, cur, stb, RTNL_LINK_VF_STATS_MULTICAST, IFLA_VF_STATS_MULTICAST); vf_data->ce_mask |= IFLA_VF_STATS; } if (t[IFLA_VF_TRUST]) { vf_trust = nla_data(t[IFLA_VF_TRUST]); if (vf_trust->setting != -1) { vf_data->vf_trust = vf_trust->setting ? 1 : 0; vf_data->ce_mask |= SRIOV_ATTR_TRUST; } } nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list); vf_head = vf_data; } return 0; } /** * @name SR-IOV Sub-Object * @{ */ /** * Add a SRIOV VF object to a link object * @param link Link object to add to * @param vf_data SRIOV VF object to add * * @return 0 if SRIOV VF object added successfully * @return -NLE_OBJ_NOTFOUND if \p link or \p vf_data not provided * @return -NLE_NOMEM if out of memory */ int rtnl_link_vf_add(struct rtnl_link *link, struct rtnl_link_vf *vf_data) { struct rtnl_link_vf *vf_head = NULL; if (!link||!vf_data) return -NLE_OBJ_NOTFOUND; if (!link->l_vf_list) { link->l_vf_list = rtnl_link_vf_alloc(); if (!link->l_vf_list) return -NLE_NOMEM; } vf_head = vf_data; vf_head->ce_refcnt++; vf_head = link->l_vf_list; nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list); link->l_vf_list = vf_head; rtnl_link_set_vf_list(link); return 0; } /** * Allocate a new SRIOV VF object * * @return NULL if out of memory * @return New VF Object * * @see rtnl_link_vf_put() * * The SRIOV VF object must be returned to the link object with * rtnl_link_vf_put() when operations are done to prevent memory leaks. */ struct rtnl_link_vf *rtnl_link_vf_alloc(void) { struct rtnl_link_vf *vf; if (!(vf = calloc(1, sizeof(*vf)))) return NULL; NL_INIT_LIST_HEAD(&vf->vf_list); vf->ce_refcnt = 1; NL_DBG(4, "Allocated new SRIOV VF object %p\n", vf); return vf; } /** * Free SRIOV VF object. * @arg vf_data SRIOV VF data object */ void rtnl_link_vf_free(struct rtnl_link_vf *vf_data) { if (!vf_data) return; if (vf_data->ce_refcnt > 0) NL_DBG(1, "Warning: Freeing SRIOV VF object in use...\n"); if (vf_data->ce_mask & SRIOV_ATTR_ADDR) nl_addr_put(vf_data->vf_lladdr); if (vf_data->ce_mask & SRIOV_ATTR_VLAN) rtnl_link_vf_vlan_put(vf_data->vf_vlans); NL_DBG(4, "Freed SRIOV VF object %p\n", vf_data); free(vf_data); return; } /** * Lookup SRIOV VF in link object by VF index. * * @return NULL if VF not found * @return VF Object * * @see rtnl_link_vf_put() * * The SRIOV VF object must be returned to the link object with * rtnl_link_vf_put() when operations are done to prevent memory leaks. */ struct rtnl_link_vf *rtnl_link_vf_get(struct rtnl_link *link, uint32_t vf_num) { struct rtnl_link_vf *list, *vf, *next, *ret = NULL; list = link->l_vf_list; nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) { if (vf->vf_index == vf_num) { ret = vf; break; } } if (ret) { ret->ce_refcnt++; NL_DBG(4, "New reference to SRIOV VF object %p, total %i\n", ret, ret->ce_refcnt); } return ret; } /** * Return SRIOV VF object to the owning link object. * @arg vf_data SRIOV VF data object * * @see rtnl_link_vf_alloc() * @see rtnl_link_vf_get() */ void rtnl_link_vf_put(struct rtnl_link_vf *vf_data) { if (!vf_data) return; vf_data->ce_refcnt--; NL_DBG(4, "Returned SRIOV VF object reference %p, %i remaining\n", vf_data, vf_data->ce_refcnt); if (vf_data->ce_refcnt < 0) BUG(); if (vf_data->ce_refcnt <= 0) rtnl_link_vf_free(vf_data); return; } /** * Get link layer address of SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg addr Pointer to store Link Layer address * * @see rtnl_link_get_num_vf() * @see rtnl_link_vf_set_addr() * * @copydoc pointer_lifetime_warning * @return 0 if addr is present and addr is set to pointer containing address * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the link layer address is not set */ int rtnl_link_vf_get_addr(struct rtnl_link_vf *vf_data, struct nl_addr **addr) { if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_ADDR) *addr = vf_data->vf_lladdr; else return -NLE_NOATTR; return 0; } /** * Set link layer address of SRIOV Virtual Function object * @param vf_data SRIOV VF object * @param addr New link layer address * * This function increments the reference counter of the address object * and overwrites any existing link layer address previously assigned. * * @see rtnl_link_vf_get_addr() */ void rtnl_link_vf_set_addr(struct rtnl_link_vf *vf_data, struct nl_addr *addr) { if (vf_data->vf_lladdr) nl_addr_put(vf_data->vf_lladdr); nl_addr_get(addr); vf_data->vf_lladdr = addr; vf_data->ce_mask |= SRIOV_ATTR_ADDR; return; } /** * Set the Infiniband node GUID for the SRIOV Virtual Function object * @param vf_data SRIOV VF object * @param guid node GUID */ void rtnl_link_vf_set_ib_node_guid(struct rtnl_link_vf *vf_data, uint64_t guid) { vf_data->vf_guid_node = guid; vf_data->ce_mask |= SRIOV_ATTR_IB_NODE_GUID; return; } /** * Set the Infiniband port GUID for the SRIOV Virtual Function object * @param vf_data SRIOV VF object * @param guid port GUID */ void rtnl_link_vf_set_ib_port_guid(struct rtnl_link_vf *vf_data, uint64_t guid) { vf_data->vf_guid_port = guid; vf_data->ce_mask |= SRIOV_ATTR_IB_PORT_GUID; return; } /** * Get index of SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg vf_index Pointer to store VF index * * @see rtnl_link_get_num_vf() * * @return 0 if index is present and vf_index is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF index is not set */ int rtnl_link_vf_get_index(struct rtnl_link_vf *vf_data, uint32_t *vf_index) { if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_INDEX) *vf_index = vf_data->vf_index; else return -NLE_NOATTR; return 0; } /** * Set index of SRIOV Virtual Function object * @param vf_data SRIOV VF object * @param vf_index Index value * * @see rtnl_link_vf_get_index() */ void rtnl_link_vf_set_index(struct rtnl_link_vf *vf_data, uint32_t vf_index) { vf_data->vf_index = vf_index; vf_data->ce_mask |= SRIOV_ATTR_INDEX; return; } /** * Get link state of SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg vf_linkstate Pointer to store VF link state * * @see rtnl_link_get_num_vf() * @see rtnl_link_set_linkstate() * * @return 0 if link state is present and vf_linkstate is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF link state is not set */ int rtnl_link_vf_get_linkstate(struct rtnl_link_vf *vf_data, uint32_t *vf_linkstate) { if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) *vf_linkstate = vf_data->vf_linkstate; else return -NLE_NOATTR; return 0; } /** * Set link state of SRIOV Virtual Function object * @param vf_data SRIOV VF object * @param vf_linkstate Link state value * * @see rtnl_link_get_linkstate() * * Not all hardware supports setting link state. If the feature is unsupported, * the link change request will fail with -NLE_OPNOTSUPP */ void rtnl_link_vf_set_linkstate(struct rtnl_link_vf *vf_data, uint32_t vf_linkstate) { vf_data->vf_linkstate = vf_linkstate; vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE; return; } /** * Get TX Rate Limit of SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg vf_rate Pointer to store VF rate limiting data * * @see rtnl_link_get_num_vf() * @see rtnl_link_set_rate() * * When the older rate API has been implemented, the rate member of the struct * will be set, and the api member will be set to RTNL_LINK_VF_API_OLD. * When the newer rate API has been implemented, the max_tx_rate * and/or the minx_tx_rate will be set, and the api member will be set to * RTNL_LINK_VF_API_NEW. * * Old rate API supports only a maximum TX rate. * ip link set dev vf 0 rate * New rate API supports minumum and maximum TX rates. * ip link set dev vf 0 min_tx_rate * ip link set dev vf 0 max_tx_rate * * @return 0 if rate is present and vf_rate is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF rate is not set */ int rtnl_link_vf_get_rate(struct rtnl_link_vf *vf_data, struct nl_vf_rate *vf_rate) { int set = 0; if (!vf_data) return -NLE_OBJ_NOTFOUND; vf_rate->api = RTNL_LINK_VF_RATE_API_UNSPEC; vf_rate->rate = 0; vf_rate->max_tx_rate = 0; vf_rate->min_tx_rate = 0; if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) { if (vf_data->vf_max_tx_rate) { vf_rate->api = RTNL_LINK_VF_RATE_API_NEW; vf_rate->max_tx_rate = vf_data->vf_max_tx_rate; set = 1; } } if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) { if (vf_data->vf_min_tx_rate) { vf_rate->api = RTNL_LINK_VF_RATE_API_NEW; vf_rate->min_tx_rate = vf_data->vf_min_tx_rate; set = 1; } } if ((!set) && (vf_data->ce_mask & SRIOV_ATTR_TX_RATE)) { if (vf_data->vf_rate) { vf_rate->api = RTNL_LINK_VF_RATE_API_OLD; vf_rate->rate = vf_data->vf_rate; set = 1; } } if (!set) return -NLE_NOATTR; return 0; } /** * Set TX Rate Limit of SRIOV Virtual Function object * @param vf_data SRIOV VF object * @param vf_rate Rate limiting structure * * @see rtnl_link_vf_get_rate() * * When setting the rate, the API level must be specificed. * Valid API levels: * RTNL_LINK_VF_RATE_API_NEW * RTNL_LINK_VF_RATE_API_OLD * * When using the new API, if either the min_tx_rate or * max_tx_rate has been set, and the other is being changed, * you must specify the currently set values to preserve * them. If this is not done, that setting will be disabled. * * Old rate API supports only a maximum TX rate. * ip link set dev vf 0 rate * New rate API supports minumum and maximum TX rates. * ip link set dev vf 0 min_tx_rate * ip link set dev vf 0 max_tx_rate * * Not all hardware supports min_tx_rate. */ void rtnl_link_vf_set_rate(struct rtnl_link_vf *vf_data, struct nl_vf_rate *vf_rate) { if (vf_rate->api == RTNL_LINK_VF_RATE_API_OLD) { vf_data->vf_rate = vf_rate->rate; vf_data->ce_mask |= SRIOV_ATTR_TX_RATE; } else if (vf_rate->api == RTNL_LINK_VF_RATE_API_NEW) { vf_data->vf_max_tx_rate = vf_rate->max_tx_rate; vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX; vf_data->vf_min_tx_rate = vf_rate->min_tx_rate; vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN; } return; } /** * Get RSS Query EN value of SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg vf_rss_query_en Pointer to store VF RSS Query value * * @see rtnl_link_get_num_vf() * @see rtnl_link_vf_set_rss_query_en() * * @return 0 if rss_query_en is present and vf_rss_query_en is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF RSS Query EN value is not set */ int rtnl_link_vf_get_rss_query_en(struct rtnl_link_vf *vf_data, uint32_t *vf_rss_query_en) { if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN) *vf_rss_query_en = vf_data->vf_rss_query_en; else return -NLE_NOATTR; return 0; } /** * Set RSS configuration querying of SRIOV Virtual Function Object * @arg vf_data SRIOV VF object * @arg vf_rss_query_en RSS Query value * * @see rtnl_link_vf_get_rss_query_en() */ void rtnl_link_vf_set_rss_query_en(struct rtnl_link_vf *vf_data, uint32_t vf_rss_query_en) { vf_data->vf_rss_query_en = vf_rss_query_en; vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN; return; } /** * Get spoof checking value of SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg vf_spoofchk Pointer to store VF spoofchk value * * @see rtnl_link_get_num_vf() * @see rtnl_link_set_spoofchk() * * @return 0 if spoofchk is present and vf_spoofchk is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF spoofcheck is not set */ int rtnl_link_vf_get_spoofchk(struct rtnl_link_vf *vf_data, uint32_t *vf_spoofchk) { if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK) *vf_spoofchk = vf_data->vf_spoofchk; else return -NLE_NOATTR; return 0; } /** * Set spoof checking value of SRIOV Virtual Function Object * @param vf_data * @param vf_spoofchk * * @see rtnl_link_vf_get_spoofchk() */ void rtnl_link_vf_set_spoofchk(struct rtnl_link_vf *vf_data, uint32_t vf_spoofchk) { vf_data->vf_spoofchk = vf_spoofchk; vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK; return; } /** * Get value of stat counter for SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg stat Identifier of statistical counter * @arg vf_stat Pointer to store VF stat value in * * @see rtnl_link_get_num_vf() * * @return 0 if stat is present and vf_stat is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF stat is not set */ int rtnl_link_vf_get_stat(struct rtnl_link_vf *vf_data, rtnl_link_vf_stats_t stat, uint64_t *vf_stat) { if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_STATS) *vf_stat = vf_data->vf_stats[stat]; else return -NLE_NOATTR; return 0; } /** * Get trust setting of SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg vf_trust Pointer to store VF trust value * * @see rtnl_link_get_num_vf() * @see rtnl_link_set_trust() * * @return 0 if trust is present and vf_trust is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF trust setting is not set */ int rtnl_link_vf_get_trust(struct rtnl_link_vf *vf_data, uint32_t *vf_trust) { if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_TRUST) *vf_trust = vf_data->vf_trust; else return -NLE_NOATTR; return 0; } /** * Set user trust setting on SRIOV Virtual Function Object * @param vf_data * @param vf_trust * * @see rtnl_link_vf_get_trust() */ void rtnl_link_vf_set_trust(struct rtnl_link_vf *vf_data, uint32_t vf_trust) { vf_data->vf_trust = vf_trust; vf_data->ce_mask |= SRIOV_ATTR_TRUST; return; } /** * Get an array of VLANS on SRIOV Virtual Function * @arg vf_data SRIOV VF object * @arg vf_vlans Pointer to nl_vf_vlans_t struct to store vlan info. * * @see rtnl_link_get_num_vf() * * The SRIOV VF VLANs object must be returned to the SRIOV VF object with * rtnl_link_vf_vlans_put() when operations are done to prevent memory leaks. * * @copydoc pointer_lifetime_warning * @return 0 if VLAN info is present and vf_vlans is set * @return -NLE_OBJ_NOTFOUND if information for VF info is not found * @return -NLE_NOATTR if the VF vlans is not set */ int rtnl_link_vf_get_vlans(struct rtnl_link_vf *vf_data, nl_vf_vlans_t **vf_vlans) { nl_vf_vlans_t *vf; if (!vf_data) return -NLE_OBJ_NOTFOUND; if (vf_data->ce_mask & SRIOV_ATTR_VLAN) { vf = vf_data->vf_vlans; vf->ce_refcnt++; *vf_vlans = vf; } else return -NLE_NOATTR; return 0; } /** * Add a SRIOV VF VLANs object to the SRIOV Virtual Function Object * @param vf_data SRIOV VF object * @param vf_vlans SRIOV VF VLANs object * * @see rtnl_link_vf_get_vlans() * @see rtnl_link_vf_vlan_alloc() * * This function assigns ownership of the SRIOV VF object \p vf_vlans * to the SRIOV Virtual Function object \p vf_data. Do not use * rtnl_link_vf_vlan_put() on \p vf_vlans after this. */ void rtnl_link_vf_set_vlans(struct rtnl_link_vf *vf_data, nl_vf_vlans_t *vf_vlans) { if (!vf_data||!vf_vlans) return; vf_data->vf_vlans = vf_vlans; vf_data->vf_vlans->ce_refcnt++; vf_data->ce_mask |= SRIOV_ATTR_VLAN; return; } /** * Allocate a SRIOV VF VLAN object * @param vf_vlans Pointer to store VLAN object at * @param vlan_count Number of VLANs that will be stored in VLAN object * * The SRIOV VF VLANs object must be returned to the sRIOV VF object with * rtnl_link_vf_vlan_put() when operations are done to prevent memory leaks. * * @return 0 if VLAN object is created and vf_vlans is set. * @return -NLE_NOMEM if object could not be allocated. * @return -NLE_INVAL if vlan_count is more than supported by SRIOV VF */ int rtnl_link_vf_vlan_alloc(nl_vf_vlans_t **vf_vlans, int vlan_count) { nl_vf_vlans_t *vlans; nl_vf_vlan_info_t *vlan_info; if (vlan_count > MAX_VLAN_LIST_LEN) return -NLE_INVAL; vlans = calloc(1, sizeof(*vlans)); if (!vf_vlans) return -NLE_NOMEM; vlan_info = calloc(vlan_count+1, sizeof(*vlan_info)); if (!vlan_info) { free(vlans); return -NLE_NOMEM; } NL_DBG(4, "Allocated new SRIOV VF VLANs object %p\n", vlans); vlans->ce_refcnt = 1; vlans->size = vlan_count; vlans->vlans = vlan_info; *vf_vlans = vlans; return 0; } /** * Free an allocated SRIOV VF VLANs object * @param vf_vlans SRIOV VF VLANs object */ void rtnl_link_vf_vlan_free(nl_vf_vlans_t *vf_vlans) { if (!vf_vlans) return; if (vf_vlans->ce_refcnt > 0) NL_DBG(1, "Warning: Freeing SRIOV VF VLANs object in use...\n"); NL_DBG(4, "Freed SRIOV VF object %p\n", vf_vlans); free(vf_vlans->vlans); free(vf_vlans); return; } /** * Return SRIOV VF VLANs object to the owning SRIOV VF object. * @param vf_vlans SRIOV VF VLANs object */ void rtnl_link_vf_vlan_put(nl_vf_vlans_t *vf_vlans) { if (!vf_vlans) return; vf_vlans->ce_refcnt--; NL_DBG(4, "Returned SRIOV VF VLANs object reference %p, %i remaining\n", vf_vlans, vf_vlans->ce_refcnt); if (vf_vlans->ce_refcnt < 0) BUG(); if (vf_vlans->ce_refcnt <= 0) rtnl_link_vf_vlan_free(vf_vlans); return; } /** @} */ /** * @name Utilities * @{ */ static const struct trans_tbl vf_link_states[] = { __ADD(IFLA_VF_LINK_STATE_AUTO, autodetect), __ADD(IFLA_VF_LINK_STATE_ENABLE, up), __ADD(IFLA_VF_LINK_STATE_DISABLE, down), }; char *rtnl_link_vf_linkstate2str(uint32_t ls, char *buf, size_t len) { return __type2str(ls, buf, len, vf_link_states, ARRAY_SIZE(vf_link_states)); } int rtnl_link_vf_str2linkstate(const char *name) { return __str2type(name, vf_link_states, ARRAY_SIZE(vf_link_states)); } static const struct trans_tbl vf_vlan_proto[] = { __ADD(ETH_P_8021Q, 8021Q), __ADD(ETH_P_8021AD, 8021AD), }; char *rtnl_link_vf_vlanproto2str(uint16_t proto, char *buf, size_t len) { return __type2str(proto, buf, len, vf_vlan_proto, ARRAY_SIZE(vf_vlan_proto)); } int rtnl_link_vf_str2vlanproto(const char *name) { return __str2type(name, vf_vlan_proto, ARRAY_SIZE(vf_vlan_proto)); } /* Return a guid from a format checked string. * Format string must be xx:xx:xx:xx:xx:xx:xx:xx where XX can be an * arbitrary hex digit * * Function modified from original at iproute2/lib/utils.c:get_guid() * Original by Eli Cohen . * iproute2 git commit d91fb3f4c7e4dba806541bdc90b1fb60a3581541 */ int rtnl_link_vf_str2guid(uint64_t *guid, const char *guid_s) { unsigned long int tmp; char *endptr; int i; if (strlen(guid_s) != RTNL_VF_GUID_STR_LEN) return -1; for (i = 0; i < 7; i++) { if (guid_s[2 + i * 3] != ':') return -1; } *guid = 0; for (i = 0; i < 8; i++) { tmp = strtoul(guid_s + i * 3, &endptr, 16); if (endptr != guid_s + i * 3 + 2) return -1; if (tmp > 255) return -1; *guid |= tmp << (56 - 8 * i); } return 0; } /** @} */ /** @} */ libnl-3.2.29/lib/route/link/can.c0000644000175000017500000004173613023014600013376 00000000000000/* * lib/route/link/can.c CAN Link Info * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Benedikt Spranger */ /** * @ingroup link * @defgroup can CAN * Controller Area Network link module * * @details * \b Link Type Name: "can" * * @route_doc{link_can, CAN Documentation} * * @{ */ #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define CAN_HAS_BITTIMING (1<<0) #define CAN_HAS_BITTIMING_CONST (1<<1) #define CAN_HAS_CLOCK (1<<2) #define CAN_HAS_STATE (1<<3) #define CAN_HAS_CTRLMODE (1<<4) #define CAN_HAS_RESTART_MS (1<<5) #define CAN_HAS_RESTART (1<<6) #define CAN_HAS_BERR_COUNTER (1<<7) struct can_info { uint32_t ci_state; uint32_t ci_restart; uint32_t ci_restart_ms; struct can_ctrlmode ci_ctrlmode; struct can_bittiming ci_bittiming; struct can_bittiming_const ci_bittiming_const; struct can_clock ci_clock; struct can_berr_counter ci_berr_counter; uint32_t ci_mask; }; /** @endcond */ static struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { [IFLA_CAN_STATE] = { .type = NLA_U32 }, [IFLA_CAN_CTRLMODE] = { .minlen = sizeof(struct can_ctrlmode) }, [IFLA_CAN_RESTART_MS] = { .type = NLA_U32 }, [IFLA_CAN_RESTART] = { .type = NLA_U32 }, [IFLA_CAN_BITTIMING] = { .minlen = sizeof(struct can_bittiming) }, [IFLA_CAN_BITTIMING_CONST] = { .minlen = sizeof(struct can_bittiming_const) }, [IFLA_CAN_CLOCK] = { .minlen = sizeof(struct can_clock) }, [IFLA_CAN_BERR_COUNTER] = { .minlen = sizeof(struct can_berr_counter) }, }; static int can_alloc(struct rtnl_link *link) { struct can_info *ci; if (link->l_info) memset(link->l_info, 0, sizeof(*ci)); else { ci = calloc(1, sizeof(*ci)); if (!ci) return -NLE_NOMEM; link->l_info = ci; } return 0; } static int can_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[IFLA_CAN_MAX+1]; struct can_info *ci; int err; NL_DBG(3, "Parsing CAN link info\n"); if ((err = nla_parse_nested(tb, IFLA_CAN_MAX, data, can_policy)) < 0) goto errout; if ((err = can_alloc(link)) < 0) goto errout; ci = link->l_info; if (tb[IFLA_CAN_STATE]) { ci->ci_state = nla_get_u32(tb[IFLA_CAN_STATE]); ci->ci_mask |= CAN_HAS_STATE; } if (tb[IFLA_CAN_RESTART]) { ci->ci_restart = nla_get_u32(tb[IFLA_CAN_RESTART]); ci->ci_mask |= CAN_HAS_RESTART; } if (tb[IFLA_CAN_RESTART_MS]) { ci->ci_restart_ms = nla_get_u32(tb[IFLA_CAN_RESTART_MS]); ci->ci_mask |= CAN_HAS_RESTART_MS; } if (tb[IFLA_CAN_CTRLMODE]) { nla_memcpy(&ci->ci_ctrlmode, tb[IFLA_CAN_CTRLMODE], sizeof(ci->ci_ctrlmode)); ci->ci_mask |= CAN_HAS_CTRLMODE; } if (tb[IFLA_CAN_BITTIMING]) { nla_memcpy(&ci->ci_bittiming, tb[IFLA_CAN_BITTIMING], sizeof(ci->ci_bittiming)); ci->ci_mask |= CAN_HAS_BITTIMING; } if (tb[IFLA_CAN_BITTIMING_CONST]) { nla_memcpy(&ci->ci_bittiming_const, tb[IFLA_CAN_BITTIMING_CONST], sizeof(ci->ci_bittiming_const)); ci->ci_mask |= CAN_HAS_BITTIMING_CONST; } if (tb[IFLA_CAN_CLOCK]) { nla_memcpy(&ci->ci_clock, tb[IFLA_CAN_CLOCK], sizeof(ci->ci_clock)); ci->ci_mask |= CAN_HAS_CLOCK; } if (tb[IFLA_CAN_BERR_COUNTER]) { nla_memcpy(&ci->ci_berr_counter, tb[IFLA_CAN_BERR_COUNTER], sizeof(ci->ci_berr_counter)); ci->ci_mask |= CAN_HAS_BERR_COUNTER; } err = 0; errout: return err; } static void can_free(struct rtnl_link *link) { struct can_info *ci = link->l_info; free(ci); link->l_info = NULL; } static char *print_can_state (uint32_t state) { char *text; switch (state) { case CAN_STATE_ERROR_ACTIVE: text = "error active"; break; case CAN_STATE_ERROR_WARNING: text = "error warning"; break; case CAN_STATE_ERROR_PASSIVE: text = "error passive"; break; case CAN_STATE_BUS_OFF: text = "bus off"; break; case CAN_STATE_STOPPED: text = "stopped"; break; case CAN_STATE_SLEEPING: text = "sleeping"; break; default: text = "unknown state"; } return text; } static void can_dump_line(struct rtnl_link *link, struct nl_dump_params *p) { struct can_info *ci = link->l_info; char buf [64]; rtnl_link_can_ctrlmode2str(ci->ci_ctrlmode.flags, buf, sizeof(buf)); nl_dump(p, "bitrate %d %s <%s>", ci->ci_bittiming.bitrate, print_can_state(ci->ci_state), buf); } static void can_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { struct can_info *ci = link->l_info; char buf [64]; rtnl_link_can_ctrlmode2str(ci->ci_ctrlmode.flags, buf, sizeof(buf)); nl_dump(p, " bitrate %d %s <%s>", ci->ci_bittiming.bitrate, print_can_state(ci->ci_state), buf); if (ci->ci_mask & CAN_HAS_RESTART) { if (ci->ci_restart) nl_dump_line(p," restarting\n"); } if (ci->ci_mask & CAN_HAS_RESTART_MS) { nl_dump_line(p," restart interval %d ms\n", ci->ci_restart_ms); } if (ci->ci_mask & CAN_HAS_BITTIMING) { nl_dump_line(p," sample point %f %%\n", ((float) ci->ci_bittiming.sample_point)/10); nl_dump_line(p," time quanta %d ns\n", ci->ci_bittiming.tq); nl_dump_line(p," propagation segment %d tq\n", ci->ci_bittiming.prop_seg); nl_dump_line(p," phase buffer segment1 %d tq\n", ci->ci_bittiming.phase_seg1); nl_dump_line(p," phase buffer segment2 %d tq\n", ci->ci_bittiming.phase_seg2); nl_dump_line(p," synchronisation jump width %d tq\n", ci->ci_bittiming.sjw); nl_dump_line(p," bitrate prescaler %d\n", ci->ci_bittiming.brp); } if (ci->ci_mask & CAN_HAS_BITTIMING_CONST) { nl_dump_line(p," minimum tsig1 %d tq\n", ci->ci_bittiming_const.tseg1_min); nl_dump_line(p," maximum tsig1 %d tq\n", ci->ci_bittiming_const.tseg1_max); nl_dump_line(p," minimum tsig2 %d tq\n", ci->ci_bittiming_const.tseg2_min); nl_dump_line(p," maximum tsig2 %d tq\n", ci->ci_bittiming_const.tseg2_max); nl_dump_line(p," maximum sjw %d tq\n", ci->ci_bittiming_const.sjw_max); nl_dump_line(p," minimum brp %d\n", ci->ci_bittiming_const.brp_min); nl_dump_line(p," maximum brp %d\n", ci->ci_bittiming_const.brp_max); nl_dump_line(p," brp increment %d\n", ci->ci_bittiming_const.brp_inc); } if (ci->ci_mask & CAN_HAS_CLOCK) { nl_dump_line(p," base freq %d Hz\n", ci->ci_clock); } if (ci->ci_mask & CAN_HAS_BERR_COUNTER) { nl_dump_line(p," bus error RX %d\n", ci->ci_berr_counter.rxerr); nl_dump_line(p," bus error TX %d\n", ci->ci_berr_counter.txerr); } return; } static int can_clone(struct rtnl_link *dst, struct rtnl_link *src) { struct can_info *cdst, *csrc = src->l_info; int ret; dst->l_info = NULL; ret = rtnl_link_set_type(dst, "can"); if (ret < 0) return ret; cdst = malloc(sizeof(*cdst)); if (!cdst) return -NLE_NOMEM; *cdst = *csrc; dst->l_info = cdst; return 0; } static int can_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct can_info *ci = link->l_info; struct nlattr *data; data = nla_nest_start(msg, IFLA_INFO_DATA); if (!data) return -NLE_MSGSIZE; if (ci->ci_mask & CAN_HAS_RESTART) NLA_PUT_U32(msg, CAN_HAS_RESTART, ci->ci_restart); if (ci->ci_mask & CAN_HAS_RESTART_MS) NLA_PUT_U32(msg, CAN_HAS_RESTART_MS, ci->ci_restart_ms); if (ci->ci_mask & CAN_HAS_CTRLMODE) NLA_PUT(msg, CAN_HAS_CTRLMODE, sizeof(ci->ci_ctrlmode), &ci->ci_ctrlmode); if (ci->ci_mask & CAN_HAS_BITTIMING) NLA_PUT(msg, CAN_HAS_BITTIMING, sizeof(ci->ci_bittiming), &ci->ci_bittiming); if (ci->ci_mask & CAN_HAS_BITTIMING_CONST) NLA_PUT(msg, CAN_HAS_BITTIMING_CONST, sizeof(ci->ci_bittiming_const), &ci->ci_bittiming_const); if (ci->ci_mask & CAN_HAS_CLOCK) NLA_PUT(msg, CAN_HAS_CLOCK, sizeof(ci->ci_clock), &ci->ci_clock); nla_nest_end(msg, data); nla_put_failure: return 0; } static struct rtnl_link_info_ops can_info_ops = { .io_name = "can", .io_alloc = can_alloc, .io_parse = can_parse, .io_dump = { [NL_DUMP_LINE] = can_dump_line, [NL_DUMP_DETAILS] = can_dump_details, }, .io_clone = can_clone, .io_put_attrs = can_put_attrs, .io_free = can_free, }; /** @cond SKIP */ #define IS_CAN_LINK_ASSERT(link) \ if ((link)->l_info_ops != &can_info_ops) { \ APPBUG("Link is not a CAN link. set type \"can\" first."); \ return -NLE_OPNOTSUPP; \ } /** @endcond */ /** * @name CAN Object * @{ */ /** * Check if link is a CAN link * @arg link Link object * * @return True if link is a CAN link, otherwise false is returned. */ int rtnl_link_is_can(struct rtnl_link *link) { return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "can"); } /** * Restart CAN device * @arg link Link object * * @return 0 on success or a negative error code */ int rtnl_link_can_restart(struct rtnl_link *link) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); ci->ci_restart = 1; ci->ci_restart |= CAN_HAS_RESTART; return 0; } /** * Get CAN base frequency * @arg link Link object * @arg freq frequency in Hz * * @return 0 on success or a negative error code */ int rtnl_link_can_freq(struct rtnl_link *link, uint32_t *freq) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!freq) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_CLOCK) *freq = ci->ci_clock.freq; else return -NLE_AGAIN; return 0; } /** * Get CAN state * @arg link Link object * @arg state CAN bus state * @return 0 on success or a negative error code */ int rtnl_link_can_state(struct rtnl_link *link, uint32_t *state) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!state) return -NLE_INVAL; *state = ci->ci_state; return 0; } /** * Get CAN RX bus error count * @arg link Link object * * @return RX bus error count on success or a negative error code */ int rtnl_link_can_berr_rx(struct rtnl_link *link) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (ci->ci_mask & CAN_HAS_BERR_COUNTER) return ci->ci_berr_counter.rxerr; else return -NLE_AGAIN; } /** * Get CAN TX bus error count * @arg link Link object * * @return TX bus error count on success or a negative error code */ int rtnl_link_can_berr_tx(struct rtnl_link *link) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (ci->ci_mask & CAN_HAS_BERR_COUNTER) return ci->ci_berr_counter.txerr; else return -NLE_AGAIN; } /** * Get CAN bus error count * @arg link Link object * @arg berr Bus error count * * @return 0 on success or a negative error code */ int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!berr) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_BERR_COUNTER) *berr = ci->ci_berr_counter; else return -NLE_AGAIN; return 0; } /** * Get CAN harware-dependent bit-timing constant * @arg link Link object * @arg bt_const Bit-timing constant * * @return 0 on success or a negative error code */ int rtnl_link_can_get_bt_const(struct rtnl_link *link, struct can_bittiming_const *bt_const) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!bt_const) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_BITTIMING_CONST) *bt_const = ci->ci_bittiming_const; else return -NLE_AGAIN; return 0; } /** * Get CAN device bit-timing * @arg link Link object * @arg bit_timing CAN bit-timing * * @return 0 on success or a negative error code */ int rtnl_link_can_get_bittiming(struct rtnl_link *link, struct can_bittiming *bit_timing) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!bit_timing) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_BITTIMING) *bit_timing = ci->ci_bittiming; else return -NLE_AGAIN; return 0; } /** * Set CAN device bit-timing * @arg link Link object * @arg bit_timing CAN bit-timing * * @return 0 on success or a negative error code */ int rtnl_link_can_set_bittiming(struct rtnl_link *link, struct can_bittiming *bit_timing) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!bit_timing) return -NLE_INVAL; ci->ci_bittiming = *bit_timing; ci->ci_mask |= CAN_HAS_BITTIMING; return 0; } /** * Get CAN device bit-timing * @arg link Link object * @arg bitrate CAN bitrate * * @return 0 on success or a negative error code */ int rtnl_link_can_get_bitrate(struct rtnl_link *link, uint32_t *bitrate) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!bitrate) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_BITTIMING) *bitrate = ci->ci_bittiming.bitrate; else return -NLE_AGAIN; return 0; } /** * Set CAN device bit-rate * @arg link Link object * @arg bitrate CAN bitrate * * @return 0 on success or a negative error code */ int rtnl_link_can_set_bitrate(struct rtnl_link *link, uint32_t bitrate) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); ci->ci_bittiming.bitrate = bitrate; ci->ci_mask |= CAN_HAS_BITTIMING; return 0; } /** * Get CAN device sample point * @arg link Link object * @arg sp CAN sample point * * @return 0 on success or a negative error code */ int rtnl_link_can_get_sample_point(struct rtnl_link *link, uint32_t *sp) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!sp) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_BITTIMING) *sp = ci->ci_bittiming.sample_point; else return -NLE_AGAIN; return 0; } /** * Set CAN device sample point * @arg link Link object * @arg sp CAN sample point * * @return 0 on success or a negative error code */ int rtnl_link_can_set_sample_point(struct rtnl_link *link, uint32_t sp) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); ci->ci_bittiming.sample_point = sp; ci->ci_mask |= CAN_HAS_BITTIMING; return 0; } /** * Get CAN device restart intervall * @arg link Link object * @arg interval Restart intervall in ms * * @return 0 on success or a negative error code */ int rtnl_link_can_get_restart_ms(struct rtnl_link *link, uint32_t *interval) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!interval) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_RESTART_MS) *interval = ci->ci_restart_ms; else return -NLE_AGAIN; return 0; } /** * Set CAN device restart intervall * @arg link Link object * @arg interval Restart intervall in ms * * @return 0 on success or a negative error code */ int rtnl_link_can_set_restart_ms(struct rtnl_link *link, uint32_t interval) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); ci->ci_restart_ms = interval; ci->ci_mask |= CAN_HAS_RESTART_MS; return 0; } /** * Get CAN control mode * @arg link Link object * @arg ctrlmode CAN control mode * * @return 0 on success or a negative error code */ int rtnl_link_can_get_ctrlmode(struct rtnl_link *link, uint32_t *ctrlmode) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); if (!ctrlmode) return -NLE_INVAL; if (ci->ci_mask & CAN_HAS_CTRLMODE) *ctrlmode = ci->ci_ctrlmode.flags; else return -NLE_AGAIN; return 0; } /** * Set a CAN Control Mode * @arg link Link object * @arg ctrlmode CAN control mode * * @return 0 on success or a negative error code */ int rtnl_link_can_set_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); ci->ci_ctrlmode.flags |= ctrlmode; ci->ci_ctrlmode.mask |= ctrlmode; ci->ci_mask |= CAN_HAS_CTRLMODE; return 0; } /** * Unset a CAN Control Mode * @arg link Link object * @arg ctrlmode CAN control mode * * @return 0 on success or a negative error code */ int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode) { struct can_info *ci = link->l_info; IS_CAN_LINK_ASSERT(link); ci->ci_ctrlmode.flags &= ~ctrlmode; ci->ci_ctrlmode.mask |= ctrlmode; ci->ci_mask |= CAN_HAS_CTRLMODE; return 0; } /** @} */ /** * @name Control Mode Translation * @{ */ static const struct trans_tbl can_ctrlmode[] = { __ADD(CAN_CTRLMODE_LOOPBACK, loopback), __ADD(CAN_CTRLMODE_LISTENONLY, listen-only), __ADD(CAN_CTRLMODE_3_SAMPLES, triple-sampling), __ADD(CAN_CTRLMODE_ONE_SHOT, one-shot), __ADD(CAN_CTRLMODE_BERR_REPORTING, berr-reporting), }; char *rtnl_link_can_ctrlmode2str(int ctrlmode, char *buf, size_t len) { return __flags2str(ctrlmode, buf, len, can_ctrlmode, ARRAY_SIZE(can_ctrlmode)); } int rtnl_link_can_str2ctrlmode(const char *name) { return __str2flags(name, can_ctrlmode, ARRAY_SIZE(can_ctrlmode)); } /** @} */ static void __init can_init(void) { rtnl_link_register_info(&can_info_ops); } static void __exit can_exit(void) { rtnl_link_unregister_info(&can_info_ops); } /** @} */ libnl-3.2.29/lib/route/pktloc.c0000644000175000017500000001305113023014600013161 00000000000000/* * lib/route/pktloc.c Packet Location Aliasing * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008-2013 Thomas Graf */ /** * @ingroup tc * @defgroup pktloc Packet Location Aliasing * Packet Location Aliasing * * The packet location aliasing interface eases the use of offset definitions * inside packets by allowing them to be referenced by name. Known positions * of protocol fields are stored in a configuration file and associated with * a name for later reference. The configuration file is distributed with the * library and provides a well defined set of definitions for most common * protocol fields. * * @section pktloc_examples Examples * @par Example 1.1 Looking up a packet location * @code * struct rtnl_pktloc *loc; * * rtnl_pktloc_lookup("ip.src", &loc); * @endcode * @{ */ #include #include #include #include #include #include "pktloc_syntax.h" #include "pktloc_grammar.h" /** @cond SKIP */ #define PKTLOC_NAME_HT_SIZ 256 static struct nl_list_head pktloc_name_ht[PKTLOC_NAME_HT_SIZ]; /* djb2 */ static unsigned int pktloc_hash(const char *str) { unsigned long hash = 5381; int c; while ((c = *str++)) hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ return hash % PKTLOC_NAME_HT_SIZ; } static int __pktloc_lookup(const char *name, struct rtnl_pktloc **result) { struct rtnl_pktloc *loc; int hash; hash = pktloc_hash(name); nl_list_for_each_entry(loc, &pktloc_name_ht[hash], list) { if (!strcasecmp(loc->name, name)) { loc->refcnt++; *result = loc; return 0; } } return -NLE_OBJ_NOTFOUND; } extern int pktloc_parse(void *scanner); static void rtnl_pktloc_free(struct rtnl_pktloc *loc) { if (!loc) return; free(loc->name); free(loc); } static int read_pktlocs(void) { YY_BUFFER_STATE buf = NULL; yyscan_t scanner = NULL; static time_t last_read; struct stat st; char *path; int i, err; FILE *fd; if (build_sysconf_path(&path, "pktloc") < 0) return -NLE_NOMEM; /* if stat fails, just try to read the file */ if (stat(path, &st) == 0) { /* Don't re-read file if file is unchanged */ if (last_read == st.st_mtime) { err = 0; goto errout; } } NL_DBG(2, "Reading packet location file \"%s\"\n", path); if (!(fd = fopen(path, "r"))) { err = -NLE_PKTLOC_FILE; goto errout; } for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) { struct rtnl_pktloc *loc, *n; nl_list_for_each_entry_safe(loc, n, &pktloc_name_ht[i], list) rtnl_pktloc_put(loc); nl_init_list_head(&pktloc_name_ht[i]); } if ((err = pktloc_lex_init(&scanner)) < 0) { err = -NLE_FAILURE; goto errout_close; } buf = pktloc__create_buffer(fd, YY_BUF_SIZE, scanner); pktloc__switch_to_buffer(buf, scanner); if ((err = pktloc_parse(scanner)) != 0) { pktloc__delete_buffer(buf, scanner); err = -NLE_PARSE_ERR; goto errout_scanner; } last_read = st.st_mtime; errout_scanner: pktloc_lex_destroy(scanner); errout_close: fclose(fd); errout: free(path); return err; } /** @endcond */ /** * Lookup packet location alias * @arg name Name of packet location. * @arg result Result pointer * * Tries to find a matching packet location alias for the supplied * packet location name. * * The file containing the packet location definitions is automatically * re-read if its modification time has changed since the last call. * * The returned packet location has to be returned after use by calling * rtnl_pktloc_put() in order to allow freeing its memory after the last * user has abandoned it. * * @return 0 on success or a negative error code. * @retval NLE_PKTLOC_FILE Unable to open packet location file. * @retval NLE_OBJ_NOTFOUND No matching packet location alias found. */ int rtnl_pktloc_lookup(const char *name, struct rtnl_pktloc **result) { int err; if ((err = read_pktlocs()) < 0) return err; return __pktloc_lookup(name, result); } /** * Allocate packet location object */ struct rtnl_pktloc *rtnl_pktloc_alloc(void) { struct rtnl_pktloc *loc; if (!(loc = calloc(1, sizeof(*loc)))) return NULL; loc->refcnt = 1; nl_init_list_head(&loc->list); return loc; } /** * Return reference of a packet location * @arg loc packet location object. */ void rtnl_pktloc_put(struct rtnl_pktloc *loc) { if (!loc) return; loc->refcnt--; if (loc->refcnt <= 0) rtnl_pktloc_free(loc); } /** * Add a packet location to the hash table * @arg loc packet location object * * @return 0 on success or a negative error code. */ int rtnl_pktloc_add(struct rtnl_pktloc *loc) { struct rtnl_pktloc *l; if (__pktloc_lookup(loc->name, &l) == 0) { rtnl_pktloc_put(l); return -NLE_EXIST; } NL_DBG(2, "New packet location entry \"%s\" align=%u layer=%u " "offset=%u mask=%#x shift=%u refnt=%u\n", loc->name, loc->align, loc->layer, loc->offset, loc->mask, loc->shift, loc->refcnt); nl_list_add_tail(&loc->list, &pktloc_name_ht[pktloc_hash(loc->name)]); return 0; } void rtnl_pktloc_foreach(void (*cb)(struct rtnl_pktloc *, void *), void *arg) { struct rtnl_pktloc *loc; int i; /* ignore errors */ read_pktlocs(); for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) nl_list_for_each_entry(loc, &pktloc_name_ht[i], list) cb(loc, arg); } static int __init pktloc_init(void) { int i; for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) nl_init_list_head(&pktloc_name_ht[i]); return 0; } /** @} */ libnl-3.2.29/lib/route/pktloc_syntax.y0000644000175000017500000000271713023014600014624 00000000000000%{ #include #include #include #include #include %} %locations %error-verbose %define api.pure %name-prefix "pktloc_" %parse-param {void *scanner} %lex-param {void *scanner} %expect 1 %union { struct rtnl_pktloc *l; uint32_t i; char *s; } %{ extern int pktloc_lex(YYSTYPE *, YYLTYPE *, void *); static void yyerror(YYLTYPE *locp, void *scanner, const char *msg) { NL_DBG(1, "Error while parsing packet location file: %s\n", msg); } %} %token ERROR NUMBER LAYER ALIGN %token NAME %type mask layer align shift %type location %destructor { free($$); } NAME %start input %% input: /* empty */ | location input ; location: NAME align layer NUMBER mask shift { struct rtnl_pktloc *loc; if (!(loc = rtnl_pktloc_alloc())) { NL_DBG(1, "Allocating a packet location " "object failed.\n"); YYABORT; } loc->name = $1; loc->align = $2; loc->layer = $3; loc->offset = $4; loc->mask = $5; loc->shift = $6; if (rtnl_pktloc_add(loc) < 0) { NL_DBG(1, "Duplicate packet location entry " "\"%s\"\n", $1); } $$ = loc; } ; align: ALIGN { $$ = $1; } | NUMBER { $$ = $1; } ; layer: /* empty */ { $$ = TCF_LAYER_NETWORK; } | LAYER '+' { $$ = $1; } ; mask: /* empty */ { $$ = 0; } | NUMBER { $$ = $1; } ; shift: /* empty */ { $$ = 0; } | NUMBER { $$ = $1; } ; libnl-3.2.29/lib/route/act.c0000644000175000017500000003250213023014600012436 00000000000000/* * lib/route/act.c Action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ /** * @ingroup tc * @defgroup act Action * @{ */ #include #include #include #include #include #include #include static struct nl_object_ops act_obj_ops; static struct nl_cache_ops rtnl_act_ops; int rtnl_act_append(struct rtnl_act **head, struct rtnl_act *new) { struct rtnl_act *p_act; int count = 1; if (*head == NULL) { *head = new; return 0; } p_act = *head; while (p_act->a_next) { ++count; p_act = p_act->a_next; } if (count > TCA_ACT_MAX_PRIO) return -NLE_RANGE; p_act->a_next = new; return 0; } int rtnl_act_remove(struct rtnl_act **head, struct rtnl_act *act) { struct rtnl_act *a, **ap; for (ap = head; (a = *ap) != NULL; ap = &a->a_next) if (a == act) break; if (a) { *ap = a->a_next; a->a_next = NULL; return 0; } return -NLE_OBJ_NOTFOUND; } static int rtnl_act_fill_one(struct nl_msg *msg, struct rtnl_act *act, int order) { struct rtnl_tc *tc = TC_CAST(act); struct rtnl_tc_ops *ops; struct nlattr *nest; int err = -NLE_NOMEM; nest = nla_nest_start(msg, order); if (!nest) goto nla_put_failure; if (tc->ce_mask & TCA_ATTR_KIND) NLA_PUT_STRING(msg, TCA_ACT_KIND, tc->tc_kind); ops = rtnl_tc_get_ops(tc); if (ops && (ops->to_msg_fill || ops->to_msg_fill_raw)) { struct nlattr *opts; void *data = rtnl_tc_data(tc); if (ops->to_msg_fill) { if (!(opts = nla_nest_start(msg, TCA_ACT_OPTIONS))) goto nla_put_failure; if ((err = ops->to_msg_fill(tc, data, msg)) < 0) goto nla_put_failure; nla_nest_end(msg, opts); } else if ((err = ops->to_msg_fill_raw(tc, data, msg)) < 0) goto nla_put_failure; } nla_nest_end(msg, nest); return 0; nla_put_failure: return err; } int rtnl_act_fill(struct nl_msg *msg, int attrtype, struct rtnl_act *act) { struct rtnl_act *p_act = act; struct nlattr *nest; int err, order = 0; nest = nla_nest_start(msg, attrtype); if (!nest) return -NLE_MSGSIZE; while (p_act) { err = rtnl_act_fill_one(msg, p_act, ++order); if (err) return err; p_act = p_act->a_next; } nla_nest_end(msg, nest); return 0; } static int rtnl_act_msg_build(struct rtnl_act *act, int type, int flags, struct nl_msg **result) { struct nl_msg *msg; struct tcamsg tcahdr = { .tca_family = AF_UNSPEC, }; int err = -NLE_MSGSIZE; msg = nlmsg_alloc_simple(type, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &tcahdr, sizeof(tcahdr), NLMSG_ALIGNTO) < 0) goto nla_put_failure; err = rtnl_act_fill(msg, TCA_ACT_TAB, act); if (err < 0) goto nla_put_failure; *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return err; } static int act_build(struct rtnl_act *act, int type, int flags, struct nl_msg **result) { int err; err = rtnl_act_msg_build(act, type, flags, result); if (err < 0) return err; return 0; } /** * @name Allocation/Freeing * @{ */ struct rtnl_act *rtnl_act_alloc(void) { struct rtnl_tc *tc; tc = TC_CAST(nl_object_alloc(&act_obj_ops)); if (tc) tc->tc_type = RTNL_TC_TYPE_ACT; return (struct rtnl_act *) tc; } void rtnl_act_get(struct rtnl_act *act) { nl_object_get(OBJ_CAST(act)); } void rtnl_act_put(struct rtnl_act *act) { nl_object_put((struct nl_object *) act); } /** @} */ /** * @name Addition/Modification/Deletion * @{ */ /** * Build a netlink message requesting the addition of an action * @arg act Action to add * @arg flags Additional netlink message flags * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_act_add() with * the exception that it will not send the message but return it int the * provided return pointer instead. * * @see rtnl_act_add() * * @return 0 on success or a negative error code. */ int rtnl_act_build_add_request(struct rtnl_act *act, int flags, struct nl_msg **result) { return act_build(act, RTM_NEWACTION, flags, result); } /** * Add/Update action * @arg sk Netlink socket * @arg act Action to add/update * @arg flags Additional netlink message flags * * Builds a \c RTM_NEWACTION netlink message requesting the addition * of a new action and sends the message to the kernel. The * configuration of the action is derived from the attributes of * the specified traffic class. * * The following flags may be specified: * - \c NLM_F_CREATE: Create action if it does not exist, * otherwise -NLE_OBJ_NOTFOUND is returned. * - \c NLM_F_EXCL: Return -NLE_EXISTS if an action with * matching handle exists already. * * Existing actions with matching handles will be updated, unless * the flag \c NLM_F_EXCL is specified. If no matching action * exists, it will be created if the flag \c NLM_F_CREATE is set, * otherwise the error -NLE_OBJ_NOTFOUND is returned. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_act_add(struct nl_sock *sk, struct rtnl_act *act, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_act_build_add_request(act, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** * Build a netlink message to change action attributes * @arg act Action to change * @arg flags additional netlink message flags * @arg result Pointer to store resulting message. * * Builds a new netlink message requesting a change of a neigh * attributes. The netlink message header isn't fully equipped with * all relevant fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. * * @return 0 on success or a negative error code. */ int rtnl_act_build_change_request(struct rtnl_act *act, int flags, struct nl_msg **result) { return act_build(act, RTM_NEWACTION, NLM_F_REPLACE | flags, result); } /** * Change an action * @arg sk Netlink socket. * @arg act action to change * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_act_build_change_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been processed. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_act_change(struct nl_sock *sk, struct rtnl_act *act, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_act_build_change_request(act, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** * Build netlink message requesting the deletion of an action * @arg act Action to delete * @arg flags Additional netlink message flags * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_act_delete() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_act_delete() * * @return 0 on success or a negative error code. */ int rtnl_act_build_delete_request(struct rtnl_act *act, int flags, struct nl_msg **result) { return act_build(act, RTM_DELACTION, flags, result); } /** * Delete action * @arg sk Netlink socket * @arg act Action to delete * @arg flags Additional netlink message flags * * Builds a \c RTM_DELACTION netlink message requesting the deletion * of an action and sends the message to the kernel. * * The message is constructed out of the following attributes: * - \c ifindex (required) * - \c prio (required) * - \c protocol (required) * - \c handle (required) * - \c parent (optional, if not specified parent equals root-qdisc) * - \c kind (optional, must match if provided) * * All other action attributes including all class type specific * attributes are ignored. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_act_delete(struct nl_sock *sk, struct rtnl_act *act, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_act_build_delete_request(act, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** @} */ static void act_dump_line(struct rtnl_tc *tc, struct nl_dump_params *p) { } void rtnl_act_put_all(struct rtnl_act **head) { struct rtnl_act *curr, *next; curr = *head; while (curr) { next = curr->a_next; rtnl_act_put(curr); curr = next; } *head = NULL; } int rtnl_act_parse(struct rtnl_act **head, struct nlattr *tb) { struct rtnl_act *act; struct rtnl_tc_ops *ops; struct nlattr *tb2[TCA_ACT_MAX + 1]; struct nlattr *nla[TCA_ACT_MAX_PRIO + 1]; char kind[TCKINDSIZ]; int err, i; err = nla_parse(nla, TCA_ACT_MAX_PRIO, nla_data(tb), NLMSG_ALIGN(nla_len(tb)), NULL); if (err < 0) return err; for (i = 0; i < TCA_ACT_MAX_PRIO; i++) { struct rtnl_tc *tc; if (nla[i] == NULL) continue; act = rtnl_act_alloc(); if (!act) { err = -NLE_NOMEM; goto err_free; } tc = TC_CAST(act); err = nla_parse(tb2, TCA_ACT_MAX, nla_data(nla[i]), nla_len(nla[i]), NULL); if (err < 0) goto err_free; if (tb2[TCA_ACT_KIND] == NULL) { err = -NLE_MISSING_ATTR; goto err_free; } nla_strlcpy(kind, tb2[TCA_ACT_KIND], sizeof(kind)); rtnl_tc_set_kind(tc, kind); if (tb2[TCA_ACT_OPTIONS]) { tc->tc_opts = nl_data_alloc_attr(tb2[TCA_ACT_OPTIONS]); if (!tc->tc_opts) { err = -NLE_NOMEM; goto err_free; } tc->ce_mask |= TCA_ATTR_OPTS; } ops = rtnl_tc_get_ops(tc); if (ops && ops->to_msg_parser) { void *data = rtnl_tc_data(tc); if (!data) { err = -NLE_NOMEM; goto err_free; } err = ops->to_msg_parser(tc, data); if (err < 0) goto err_free; } err = rtnl_act_append(head, act); if (err < 0) goto err_free; } return 0; err_free: rtnl_act_put (act); rtnl_act_put_all(head); return err; } static int rtnl_act_msg_parse(struct nlmsghdr *n, struct rtnl_act **act) { struct rtnl_tc *tc = TC_CAST(*act); struct nl_cache *link_cache; struct nlattr *tb[TCAA_MAX + 1]; struct tcamsg *tm; int err; tc->ce_msgtype = n->nlmsg_type; err = nlmsg_parse(n, sizeof(*tm), tb, TCAA_MAX, NULL); if (err < 0) return err; tm = nlmsg_data(n); tc->tc_family = tm->tca_family; if (tb[TCA_ACT_TAB] == NULL) return -NLE_MISSING_ATTR; err = rtnl_act_parse(act, tb[TCA_ACT_TAB]); if (err < 0) return err; if ((link_cache = __nl_cache_mngt_require("route/link"))) { struct rtnl_link *link; if ((link = rtnl_link_get(link_cache, tc->tc_ifindex))) { rtnl_tc_set_link(tc, link); /* rtnl_tc_set_link incs refcnt */ rtnl_link_put(link); } } return 0; } static int act_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct rtnl_act *act, *p_act; int err; if (!(act = rtnl_act_alloc())) return -NLE_NOMEM; if ((err = rtnl_act_msg_parse(nlh, &act)) < 0) goto errout; p_act = act; while(p_act) { err = pp->pp_cb(OBJ_CAST(act), pp); if (err) break; p_act = p_act->a_next; } errout: rtnl_act_put(act); return err; } static int act_request_update(struct nl_cache *cache, struct nl_sock *sk) { struct tcamsg tcahdr = { .tca_family = AF_UNSPEC, }; return nl_send_simple(sk, RTM_GETACTION, NLM_F_DUMP, &tcahdr, sizeof(tcahdr)); } static struct rtnl_tc_type_ops act_ops = { .tt_type = RTNL_TC_TYPE_ACT, .tt_dump_prefix = "act", .tt_dump = { [NL_DUMP_LINE] = act_dump_line, }, }; static struct nl_cache_ops rtnl_act_ops = { .co_name = "route/act", .co_hdrsize = sizeof(struct tcmsg), .co_msgtypes = { { RTM_NEWACTION, NL_ACT_NEW, "new" }, { RTM_DELACTION, NL_ACT_DEL, "del" }, { RTM_GETACTION, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_request_update = act_request_update, .co_msg_parser = act_msg_parser, .co_obj_ops = &act_obj_ops, }; static struct nl_object_ops act_obj_ops = { .oo_name = "route/act", .oo_size = sizeof(struct rtnl_act), .oo_free_data = rtnl_tc_free_data, .oo_clone = rtnl_tc_clone, .oo_dump = { [NL_DUMP_LINE] = rtnl_tc_dump_line, [NL_DUMP_DETAILS] = rtnl_tc_dump_details, [NL_DUMP_STATS] = rtnl_tc_dump_stats, }, .oo_compare = rtnl_tc_compare, .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), }; static void __init act_init(void) { rtnl_tc_type_register(&act_ops); nl_cache_mngt_register(&rtnl_act_ops); } static void __exit act_exit(void) { nl_cache_mngt_unregister(&rtnl_act_ops); rtnl_tc_type_unregister(&act_ops); } /** @} */ libnl-3.2.29/lib/route/cls.c0000644000175000017500000002667213023014600012463 00000000000000/* * lib/route/classifier.c Classifier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ /** * @ingroup tc * @defgroup cls Classifiers * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define CLS_ATTR_PRIO (TCA_ATTR_MAX << 1) #define CLS_ATTR_PROTOCOL (TCA_ATTR_MAX << 2) /** @endcond */ static struct nl_object_ops cls_obj_ops; static struct nl_cache_ops rtnl_cls_ops; static int cls_build(struct rtnl_cls *cls, int type, int flags, struct nl_msg **result) { int err, prio, proto; struct tcmsg *tchdr; uint32_t required = TCA_ATTR_IFINDEX; if ((cls->ce_mask & required) != required) { APPBUG("ifindex must be specified"); return -NLE_MISSING_ATTR; } err = rtnl_tc_msg_build(TC_CAST(cls), type, flags, result); if (err < 0) return err; tchdr = nlmsg_data(nlmsg_hdr(*result)); prio = rtnl_cls_get_prio(cls); proto = rtnl_cls_get_protocol(cls); tchdr->tcm_info = TC_H_MAKE(prio << 16, htons(proto)); return 0; } /** * @name Allocation/Freeing * @{ */ struct rtnl_cls *rtnl_cls_alloc(void) { struct rtnl_tc *tc; tc = TC_CAST(nl_object_alloc(&cls_obj_ops)); if (tc) tc->tc_type = RTNL_TC_TYPE_CLS; return (struct rtnl_cls *) tc; } void rtnl_cls_put(struct rtnl_cls *cls) { nl_object_put((struct nl_object *) cls); } /** @} */ /** * @name Attributes * @{ */ void rtnl_cls_set_prio(struct rtnl_cls *cls, uint16_t prio) { cls->c_prio = prio; cls->ce_mask |= CLS_ATTR_PRIO; } uint16_t rtnl_cls_get_prio(struct rtnl_cls *cls) { if (cls->ce_mask & CLS_ATTR_PRIO) return cls->c_prio; else return 0; } void rtnl_cls_set_protocol(struct rtnl_cls *cls, uint16_t protocol) { cls->c_protocol = protocol; cls->ce_mask |= CLS_ATTR_PROTOCOL; } uint16_t rtnl_cls_get_protocol(struct rtnl_cls *cls) { if (cls->ce_mask & CLS_ATTR_PROTOCOL) return cls->c_protocol; else return ETH_P_ALL; } /** @} */ /** * @name Addition/Modification/Deletion * @{ */ /** * Build a netlink message requesting the addition of a classifier * @arg cls Classifier to add * @arg flags Additional netlink message flags * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_cls_add() with * the exception that it will not send the message but return it int the * provided return pointer instead. * * @see rtnl_cls_add() * * @return 0 on success or a negative error code. */ int rtnl_cls_build_add_request(struct rtnl_cls *cls, int flags, struct nl_msg **result) { if (!(flags & NLM_F_CREATE) && !(cls->ce_mask & CLS_ATTR_PRIO)) { APPBUG("prio must be specified if not a new classifier"); return -NLE_MISSING_ATTR; } return cls_build(cls, RTM_NEWTFILTER, flags, result); } /** * Add/Update classifier * @arg sk Netlink socket * @arg cls Classifier to add/update * @arg flags Additional netlink message flags * * Builds a \c RTM_NEWTFILTER netlink message requesting the addition * of a new classifier and sends the message to the kernel. The * configuration of the classifier is derived from the attributes of * the specified traffic class. * * The following flags may be specified: * - \c NLM_F_CREATE: Create classifier if it does not exist, * otherwise -NLE_OBJ_NOTFOUND is returned. * - \c NLM_F_EXCL: Return -NLE_EXISTS if a classifier with * matching handle exists already. * * Existing classifiers with matching handles will be updated, unless * the flag \c NLM_F_EXCL is specified. If no matching classifier * exists, it will be created if the flag \c NLM_F_CREATE is set, * otherwise the error -NLE_OBJ_NOTFOUND is returned. * * If the parent qdisc does not support classes, the error * \c NLE_OPNOTSUPP is returned. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_cls_add(struct nl_sock *sk, struct rtnl_cls *cls, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_cls_build_add_request(cls, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** * Build a netlink message to change classifier attributes * @arg cls classifier to change * @arg flags additional netlink message flags * @arg result Pointer to store resulting message. * * Builds a new netlink message requesting a change of a neigh * attributes. The netlink message header isn't fully equipped with * all relevant fields and must thus be sent out via nl_send_auto_complete() * or supplemented as needed. * * @return 0 on success or a negative error code. */ int rtnl_cls_build_change_request(struct rtnl_cls *cls, int flags, struct nl_msg **result) { return cls_build(cls, RTM_NEWTFILTER, NLM_F_REPLACE | flags, result); } /** * Change a classifier * @arg sk Netlink socket. * @arg cls classifier to change * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_cls_build_change_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been processed. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_cls_change(struct nl_sock *sk, struct rtnl_cls *cls, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_cls_build_change_request(cls, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** * Build netlink message requesting the deletion of a classifier * @arg cls Classifier to delete * @arg flags Additional netlink message flags * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_cls_delete() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_cls_delete() * * @return 0 on success or a negative error code. */ int rtnl_cls_build_delete_request(struct rtnl_cls *cls, int flags, struct nl_msg **result) { uint32_t required = CLS_ATTR_PRIO; if ((cls->ce_mask & required) != required) { APPBUG("prio must be specified"); return -NLE_MISSING_ATTR; } return cls_build(cls, RTM_DELTFILTER, flags, result); } /** * Delete classifier * @arg sk Netlink socket * @arg cls Classifier to delete * @arg flags Additional netlink message flags * * Builds a \c RTM_DELTFILTER netlink message requesting the deletion * of a classifier and sends the message to the kernel. * * The message is constructed out of the following attributes: * - \c ifindex (required) * - \c prio (required) * - \c protocol (required) * - \c handle (required) * - \c parent (optional, if not specified parent equals root-qdisc) * - \c kind (optional, must match if provided) * * All other classifier attributes including all class type specific * attributes are ignored. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_cls_delete(struct nl_sock *sk, struct rtnl_cls *cls, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_cls_build_delete_request(cls, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** @} */ /** * @name Cache Related Functions * @{ */ /** * Allocate a cache and fill it with all configured classifiers * @arg sk Netlink socket * @arg ifindex Interface index of the network device * @arg parent Parent qdisc/traffic class class * @arg result Pointer to store the created cache * * Allocates a new classifier cache and fills it with a list of all * configured classifier attached to the specified parent qdisc/traffic * class on the specified network device. Release the cache with * nl_cache_free(). * * @return 0 on success or a negative error code. */ int rtnl_cls_alloc_cache(struct nl_sock *sk, int ifindex, uint32_t parent, struct nl_cache **result) { struct nl_cache * cache; int err; if (!(cache = nl_cache_alloc(&rtnl_cls_ops))) return -NLE_NOMEM; cache->c_iarg1 = ifindex; cache->c_iarg2 = parent; if (sk && (err = nl_cache_refill(sk, cache)) < 0) { nl_cache_free(cache); return err; } *result = cache; return 0; } /** @} */ static void cls_dump_line(struct rtnl_tc *tc, struct nl_dump_params *p) { struct rtnl_cls *cls = (struct rtnl_cls *) tc; char buf[32]; nl_dump(p, " prio %u protocol %s", cls->c_prio, nl_ether_proto2str(cls->c_protocol, buf, sizeof(buf))); } static int cls_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct rtnl_cls *cls; int err; if (!(cls = rtnl_cls_alloc())) return -NLE_NOMEM; if ((err = rtnl_tc_msg_parse(nlh, TC_CAST(cls))) < 0) goto errout; cls->c_prio = TC_H_MAJ(cls->c_info) >> 16; if (cls->c_prio) cls->ce_mask |= CLS_ATTR_PRIO; cls->c_protocol = ntohs(TC_H_MIN(cls->c_info)); if (cls->c_protocol) cls->ce_mask |= CLS_ATTR_PROTOCOL; err = pp->pp_cb(OBJ_CAST(cls), pp); errout: rtnl_cls_put(cls); return err; } static int cls_request_update(struct nl_cache *cache, struct nl_sock *sk) { struct tcmsg tchdr = { .tcm_family = AF_UNSPEC, .tcm_ifindex = cache->c_iarg1, .tcm_parent = cache->c_iarg2, }; return nl_send_simple(sk, RTM_GETTFILTER, NLM_F_DUMP, &tchdr, sizeof(tchdr)); } static struct rtnl_tc_type_ops cls_ops = { .tt_type = RTNL_TC_TYPE_CLS, .tt_dump_prefix = "cls", .tt_dump = { [NL_DUMP_LINE] = cls_dump_line, }, }; static struct nl_cache_ops rtnl_cls_ops = { .co_name = "route/cls", .co_hdrsize = sizeof(struct tcmsg), .co_msgtypes = { { RTM_NEWTFILTER, NL_ACT_NEW, "new" }, { RTM_DELTFILTER, NL_ACT_DEL, "del" }, { RTM_GETTFILTER, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_groups = tc_groups, .co_request_update = cls_request_update, .co_msg_parser = cls_msg_parser, .co_obj_ops = &cls_obj_ops, }; static struct nl_object_ops cls_obj_ops = { .oo_name = "route/cls", .oo_size = sizeof(struct rtnl_cls), .oo_free_data = rtnl_tc_free_data, .oo_clone = rtnl_tc_clone, .oo_dump = { [NL_DUMP_LINE] = rtnl_tc_dump_line, [NL_DUMP_DETAILS] = rtnl_tc_dump_details, [NL_DUMP_STATS] = rtnl_tc_dump_stats, }, .oo_compare = rtnl_tc_compare, .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), }; static void __init cls_init(void) { rtnl_tc_type_register(&cls_ops); nl_cache_mngt_register(&rtnl_cls_ops); } static void __exit cls_exit(void) { nl_cache_mngt_unregister(&rtnl_cls_ops); rtnl_tc_type_unregister(&cls_ops); } /** @} */ libnl-3.2.29/lib/route/route_utils.c0000644000175000017500000000744713023014600014257 00000000000000/* * lib/route/route_utils.c Routing Utilities * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2006 Thomas Graf */ /** * @ingroup route * @defgroup route_utils Utilities * @brief Routing Utility Functions * * * @par 1) Translating Routing Table Names * @code * // libnl is only aware of the de facto standard routing table names. * // Additional name <-> identifier associations have to be read in via * // a configuration file, f.e. /etc/iproute2/rt_tables * err = rtnl_route_read_table_names("/etc/iproute2/rt_tables"); * * // Translating a table name to its idenfier * int table = rtnl_route_str2table("main"); * * // ... and the other way around. * char buf[32]; * printf("Name: %s\n", * rtnl_route_table2str(table, buf, sizeof(buf))); * @endcode * * * * * @{ */ #include #include #include #include #include /** * @name Routing Table Identifier Translations * @{ */ static NL_LIST_HEAD(table_names); static int add_routing_table_name(long id, const char *name) { return __trans_list_add(id, name, &table_names); } static void __init init_routing_table_names(void) { add_routing_table_name(RT_TABLE_UNSPEC, "unspec"); add_routing_table_name(RT_TABLE_COMPAT, "compat"); add_routing_table_name(RT_TABLE_DEFAULT, "default"); add_routing_table_name(RT_TABLE_MAIN, "main"); add_routing_table_name(RT_TABLE_LOCAL, "local"); }; static void __exit release_routing_table_names(void) { __trans_list_clear(&table_names); } int rtnl_route_read_table_names(const char *path) { __trans_list_clear(&table_names); return __nl_read_num_str_file(path, &add_routing_table_name); } char *rtnl_route_table2str(int table, char *buf, size_t size) { return __list_type2str(table, buf, size, &table_names); } int rtnl_route_str2table(const char *name) { return __list_str2type(name, &table_names); } /** @} */ /** * @name Routing Protocol Translations * @{ */ static NL_LIST_HEAD(proto_names); static int add_proto_name(long id, const char *name) { return __trans_list_add(id, name, &proto_names); } static void __init init_proto_names(void) { add_proto_name(RTPROT_UNSPEC, "unspec"); add_proto_name(RTPROT_REDIRECT, "redirect"); add_proto_name(RTPROT_KERNEL, "kernel"); add_proto_name(RTPROT_BOOT, "boot"); add_proto_name(RTPROT_STATIC, "static"); }; static void __exit release_proto_names(void) { __trans_list_clear(&proto_names); } int rtnl_route_read_protocol_names(const char *path) { __trans_list_clear(&proto_names); return __nl_read_num_str_file(path, &add_proto_name); } char *rtnl_route_proto2str(int proto, char *buf, size_t size) { return __list_type2str(proto, buf, size, &proto_names); } int rtnl_route_str2proto(const char *name) { return __list_str2type(name, &proto_names); } /** @} */ /** * @name Routing Metrices Translations * @{ */ static const struct trans_tbl route_metrices[] = { __ADD(RTAX_UNSPEC, unspec), __ADD(RTAX_LOCK, lock), __ADD(RTAX_MTU, mtu), __ADD(RTAX_WINDOW, window), __ADD(RTAX_RTT, rtt), __ADD(RTAX_RTTVAR, rttvar), __ADD(RTAX_SSTHRESH, ssthresh), __ADD(RTAX_CWND, cwnd), __ADD(RTAX_ADVMSS, advmss), __ADD(RTAX_REORDERING, reordering), __ADD(RTAX_HOPLIMIT, hoplimit), __ADD(RTAX_INITCWND, initcwnd), __ADD(RTAX_FEATURES, features), }; char *rtnl_route_metric2str(int metric, char *buf, size_t size) { return __type2str(metric, buf, size, route_metrices, ARRAY_SIZE(route_metrices)); } int rtnl_route_str2metric(const char *name) { return __str2type(name, route_metrices, ARRAY_SIZE(route_metrices)); } /** @} */ /** @} */ libnl-3.2.29/lib/route/route.c0000644000175000017500000001067013023014600013027 00000000000000/* * lib/route/route.c Routes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2008 Thomas Graf */ /** * @ingroup rtnl * @defgroup route Routing * @brief * @{ */ #include #include #include #include #include #include #include #include static struct nl_cache_ops rtnl_route_ops; static int route_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct rtnl_route *route; int err; if ((err = rtnl_route_parse(nlh, &route)) < 0) return err; err = pp->pp_cb((struct nl_object *) route, pp); rtnl_route_put(route); return err; } static int route_request_update(struct nl_cache *c, struct nl_sock *h) { struct rtmsg rhdr = { .rtm_family = c->c_iarg1, }; if (c->c_iarg2 & ROUTE_CACHE_CONTENT) rhdr.rtm_flags |= RTM_F_CLONED; return nl_send_simple(h, RTM_GETROUTE, NLM_F_DUMP, &rhdr, sizeof(rhdr)); } /** * @name Cache Management * @{ */ /** * Build a route cache holding all routes currently configured in the kernel * @arg sk Netlink socket. * @arg family Address family of routes to cover or AF_UNSPEC * @arg flags Flags * @arg result Result pointer * * Allocates a new cache, initializes it properly and updates it to * contain all routes currently configured in the kernel. * * Valid flags: * * ROUTE_CACHE_CONTENT - Cache will contain contents of routing cache * instead of actual routes. * * @note The caller is responsible for destroying and freeing the * cache after using it. * @return 0 on success or a negative error code. */ int rtnl_route_alloc_cache(struct nl_sock *sk, int family, int flags, struct nl_cache **result) { struct nl_cache *cache; int err; if (!(cache = nl_cache_alloc(&rtnl_route_ops))) return -NLE_NOMEM; cache->c_iarg1 = family; cache->c_iarg2 = flags; if (sk && (err = nl_cache_refill(sk, cache)) < 0) { free(cache); return err; } *result = cache; return 0; } /** @} */ /** * @name Route Addition * @{ */ static int build_route_msg(struct rtnl_route *tmpl, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; int err; if (!(msg = nlmsg_alloc_simple(cmd, flags))) return -NLE_NOMEM; if ((err = rtnl_route_build_msg(msg, tmpl)) < 0) { nlmsg_free(msg); return err; } *result = msg; return 0; } int rtnl_route_build_add_request(struct rtnl_route *tmpl, int flags, struct nl_msg **result) { return build_route_msg(tmpl, RTM_NEWROUTE, NLM_F_CREATE | flags, result); } int rtnl_route_add(struct nl_sock *sk, struct rtnl_route *route, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_route_build_add_request(route, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } int rtnl_route_build_del_request(struct rtnl_route *tmpl, int flags, struct nl_msg **result) { return build_route_msg(tmpl, RTM_DELROUTE, flags, result); } int rtnl_route_delete(struct nl_sock *sk, struct rtnl_route *route, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_route_build_del_request(route, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); } /** @} */ static struct nl_af_group route_groups[] = { { AF_INET, RTNLGRP_IPV4_ROUTE }, { AF_INET6, RTNLGRP_IPV6_ROUTE }, { AF_DECnet, RTNLGRP_DECnet_ROUTE }, { END_OF_GROUP_LIST }, }; static struct nl_cache_ops rtnl_route_ops = { .co_name = "route/route", .co_hdrsize = sizeof(struct rtmsg), .co_msgtypes = { { RTM_NEWROUTE, NL_ACT_NEW, "new" }, { RTM_DELROUTE, NL_ACT_DEL, "del" }, { RTM_GETROUTE, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_groups = route_groups, .co_request_update = route_request_update, .co_msg_parser = route_msg_parser, .co_obj_ops = &route_obj_ops, }; static void __init route_init(void) { nl_cache_mngt_register(&rtnl_route_ops); } static void __exit route_exit(void) { nl_cache_mngt_unregister(&rtnl_route_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/0000755000175000017500000000000013031473756012730 500000000000000libnl-3.2.29/lib/route/qdisc/hfsc.c0000644000175000017500000001750513023014600013723 00000000000000/* * lib/route/qdisc/hfsc.c HFSC Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2014 Cong Wang */ /** * @ingroup qdisc * @ingroup class * @defgroup qdisc_hfsc Hierarchical Fair Service Curve (HFSC) * @{ */ #include #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_HFSC_CLS_HAS_RSC 0x001 #define SCH_HFSC_CLS_HAS_FSC 0x002 #define SCH_HFSC_CLS_HAS_USC 0x004 #define SCH_HFSC_QD_HAS_DEFCLS 0x01 /** @endcond */ static struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = { [TCA_HFSC_RSC] = { .minlen = sizeof(struct tc_service_curve) }, [TCA_HFSC_FSC] = { .minlen = sizeof(struct tc_service_curve) }, [TCA_HFSC_USC] = { .minlen = sizeof(struct tc_service_curve) }, }; static int hfsc_qdisc_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_hfsc_qdisc *hfsc = data; struct tc_hfsc_qopt *opts; opts = (struct tc_hfsc_qopt *) tc->tc_opts->d_data; hfsc->qh_defcls = opts->defcls; hfsc->qh_mask |= SCH_HFSC_QD_HAS_DEFCLS; return 0; } static int hfsc_class_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_HFSC_MAX + 1]; struct rtnl_hfsc_class *hfsc = data; int err; if ((err = tca_parse(tb, TCA_HFSC_MAX, tc, hfsc_policy)) < 0) return err; if (tb[TCA_HFSC_RSC]) { struct tc_service_curve tsc; nla_memcpy(&tsc, tb[TCA_HFSC_RSC], sizeof(tsc)); hfsc->ch_rsc = tsc; hfsc->ch_mask |= SCH_HFSC_CLS_HAS_RSC; } if (tb[TCA_HFSC_FSC]) { struct tc_service_curve tsc; nla_memcpy(&tsc, tb[TCA_HFSC_FSC], sizeof(tsc)); hfsc->ch_fsc = tsc; hfsc->ch_mask |= SCH_HFSC_CLS_HAS_FSC; } if (tb[TCA_HFSC_USC]) { struct tc_service_curve tsc; nla_memcpy(&tsc, tb[TCA_HFSC_USC], sizeof(tsc)); hfsc->ch_usc = tsc; hfsc->ch_mask |= SCH_HFSC_CLS_HAS_USC; } return 0; } static void hfsc_qdisc_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_hfsc_qdisc *hfsc = data; if (!hfsc) return; if (hfsc->qh_mask & SCH_HFSC_QD_HAS_DEFCLS) { char buf[64]; nl_dump(p, " default-class %s", rtnl_tc_handle2str(hfsc->qh_defcls, buf, sizeof(buf))); } } static void hfsc_dump_tsc(struct nl_dump_params *p, struct tc_service_curve *tsc) { nl_dump(p, " m1 %u d %u m2 %u\n", tsc->m1, tsc->d, tsc->m2); } static void hfsc_class_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_hfsc_class *hfsc = data; if (!hfsc) return; if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_RSC) hfsc_dump_tsc(p, &hfsc->ch_rsc); if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_FSC) hfsc_dump_tsc(p, &hfsc->ch_fsc); if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_USC) hfsc_dump_tsc(p, &hfsc->ch_usc); } static void hfsc_class_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { return; } static int hfsc_qdisc_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_hfsc_qdisc *hfsc = data; struct tc_hfsc_qopt opts = {0}; if (!hfsc) BUG(); opts.defcls = hfsc->qh_defcls; return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD); } static int hfsc_class_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_hfsc_class *hfsc = data; struct tc_service_curve tsc; if (!hfsc) BUG(); if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_RSC) { tsc = hfsc->ch_rsc; NLA_PUT(msg, TCA_HFSC_RSC, sizeof(tsc), &tsc); } if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_FSC) { tsc = hfsc->ch_fsc; NLA_PUT(msg, TCA_HFSC_FSC, sizeof(tsc), &tsc); } if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_USC) { tsc = hfsc->ch_usc; NLA_PUT(msg, TCA_HFSC_USC, sizeof(tsc), &tsc); } return 0; nla_put_failure: return -NLE_MSGSIZE; } static struct rtnl_tc_ops hfsc_qdisc_ops; static struct rtnl_tc_ops hfsc_class_ops; static struct rtnl_hfsc_qdisc *hfsc_qdisc_data(const struct rtnl_qdisc *qdisc, int *err) { return rtnl_tc_data_check(TC_CAST(qdisc), &hfsc_qdisc_ops, err); } static struct rtnl_hfsc_class *hfsc_class_data(const struct rtnl_class *class, int *err) { return rtnl_tc_data_check(TC_CAST(class), &hfsc_class_ops, err); } /** * @name Attribute Modifications * @{ */ /** * Return default class of HFSC qdisc * @arg qdisc hfsc qdisc object * * Returns the classid of the class where all unclassified traffic * goes to. * * @return classid or TC_H_UNSPEC if unspecified. */ uint32_t rtnl_qdisc_hfsc_get_defcls(const struct rtnl_qdisc *qdisc) { struct rtnl_hfsc_qdisc *hfsc; if ((hfsc = hfsc_qdisc_data(qdisc, NULL)) && (hfsc->qh_mask & SCH_HFSC_QD_HAS_DEFCLS)) return hfsc->qh_defcls; return TC_H_UNSPEC; } /** * Set default class of the hfsc qdisc to the specified value * @arg qdisc qdisc to change * @arg defcls new default class */ int rtnl_qdisc_hfsc_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls) { struct rtnl_hfsc_qdisc *hfsc; int err; if (!(hfsc = hfsc_qdisc_data(qdisc, &err))) return err; hfsc->qh_defcls = defcls; hfsc->qh_mask |= SCH_HFSC_QD_HAS_DEFCLS; return 0; } int rtnl_class_hfsc_get_rsc(const struct rtnl_class *class, struct tc_service_curve *tsc) { struct rtnl_hfsc_class *hfsc; int err = -NLE_OPNOTSUPP; if ((hfsc = hfsc_class_data(class, &err)) && (hfsc->ch_mask & SCH_HFSC_CLS_HAS_RSC)) { *tsc = hfsc->ch_rsc; return 0; } return err; } int rtnl_class_hfsc_set_rsc(struct rtnl_class *class, const struct tc_service_curve *tsc) { struct rtnl_hfsc_class *hfsc; int err; if (!(hfsc = hfsc_class_data(class, &err))) return err; hfsc->ch_rsc = *tsc; hfsc->ch_mask |= SCH_HFSC_CLS_HAS_RSC; return 0; } int rtnl_class_hfsc_get_fsc(const struct rtnl_class *class, struct tc_service_curve *tsc) { struct rtnl_hfsc_class *hfsc; int err = -NLE_OPNOTSUPP; if ((hfsc = hfsc_class_data(class, &err)) && (hfsc->ch_mask & SCH_HFSC_CLS_HAS_FSC)) { *tsc = hfsc->ch_fsc; return 0; } return err; } int rtnl_class_hfsc_set_fsc(struct rtnl_class *class, const struct tc_service_curve *tsc) { struct rtnl_hfsc_class *hfsc; int err; if (!(hfsc = hfsc_class_data(class, &err))) return err; hfsc->ch_fsc = *tsc; hfsc->ch_mask |= SCH_HFSC_CLS_HAS_FSC; return 0; } int rtnl_class_hfsc_get_usc(const struct rtnl_class *class, struct tc_service_curve *tsc) { struct rtnl_hfsc_class *hfsc; int err = -NLE_OPNOTSUPP; if ((hfsc = hfsc_class_data(class, &err)) && (hfsc->ch_mask & SCH_HFSC_CLS_HAS_USC)) { *tsc = hfsc->ch_usc; return 0; } return err; } int rtnl_class_hfsc_set_usc(struct rtnl_class *class, const struct tc_service_curve *tsc) { struct rtnl_hfsc_class *hfsc; int err; if (!(hfsc = hfsc_class_data(class, &err))) return err; hfsc->ch_usc = *tsc; hfsc->ch_mask |= SCH_HFSC_CLS_HAS_USC; return 0; } /** @} */ static struct rtnl_tc_ops hfsc_qdisc_ops = { .to_kind = "hfsc", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_hfsc_qdisc), .to_msg_parser = hfsc_qdisc_msg_parser, .to_dump[NL_DUMP_LINE] = hfsc_qdisc_dump_line, .to_msg_fill = hfsc_qdisc_msg_fill, }; static struct rtnl_tc_ops hfsc_class_ops = { .to_kind = "hfsc", .to_type = RTNL_TC_TYPE_CLASS, .to_size = sizeof(struct rtnl_hfsc_class), .to_msg_parser = hfsc_class_msg_parser, .to_dump = { [NL_DUMP_LINE] = hfsc_class_dump_line, [NL_DUMP_DETAILS] = hfsc_class_dump_details, }, .to_msg_fill = hfsc_class_msg_fill, }; static void __init hfsc_init(void) { rtnl_tc_register(&hfsc_qdisc_ops); rtnl_tc_register(&hfsc_class_ops); } static void __exit hfsc_exit(void) { rtnl_tc_unregister(&hfsc_qdisc_ops); rtnl_tc_unregister(&hfsc_class_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/htb.c0000644000175000017500000003545113023014600013555 00000000000000/* * lib/route/qdisc/htb.c HTB Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf * Copyright (c) 2005-2006 Petr Gotthard * Copyright (c) 2005-2006 Siemens AG Oesterreich */ /** * @ingroup qdisc * @ingroup class * @defgroup qdisc_htb Hierachical Token Bucket (HTB) * @{ */ #include #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_HTB_HAS_RATE2QUANTUM 0x01 #define SCH_HTB_HAS_DEFCLS 0x02 #define SCH_HTB_HAS_PRIO 0x001 #define SCH_HTB_HAS_RATE 0x002 #define SCH_HTB_HAS_CEIL 0x004 #define SCH_HTB_HAS_RBUFFER 0x008 #define SCH_HTB_HAS_CBUFFER 0x010 #define SCH_HTB_HAS_QUANTUM 0x020 #define SCH_HTB_HAS_LEVEL 0x040 /** @endcond */ static struct nla_policy htb_policy[TCA_HTB_MAX+1] = { [TCA_HTB_INIT] = { .minlen = sizeof(struct tc_htb_glob) }, [TCA_HTB_PARMS] = { .minlen = sizeof(struct tc_htb_opt) }, }; static int htb_qdisc_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_HTB_MAX + 1]; struct rtnl_htb_qdisc *htb = data; int err; if ((err = tca_parse(tb, TCA_HTB_MAX, tc, htb_policy)) < 0) return err; if (tb[TCA_HTB_INIT]) { struct tc_htb_glob opts; nla_memcpy(&opts, tb[TCA_HTB_INIT], sizeof(opts)); htb->qh_rate2quantum = opts.rate2quantum; htb->qh_defcls = opts.defcls; htb->qh_direct_pkts = opts.direct_pkts; htb->qh_mask = (SCH_HTB_HAS_RATE2QUANTUM | SCH_HTB_HAS_DEFCLS); } return 0; } static int htb_class_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_HTB_MAX + 1]; struct rtnl_htb_class *htb = data; int err; if ((err = tca_parse(tb, TCA_HTB_MAX, tc, htb_policy)) < 0) return err; if (tb[TCA_HTB_PARMS]) { struct tc_htb_opt opts; nla_memcpy(&opts, tb[TCA_HTB_PARMS], sizeof(opts)); htb->ch_prio = opts.prio; rtnl_copy_ratespec(&htb->ch_rate, &opts.rate); rtnl_copy_ratespec(&htb->ch_ceil, &opts.ceil); htb->ch_rbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.buffer), opts.rate.rate); htb->ch_cbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.cbuffer), opts.ceil.rate); htb->ch_quantum = opts.quantum; htb->ch_level = opts.level; rtnl_tc_set_mpu(tc, htb->ch_rate.rs_mpu); rtnl_tc_set_overhead(tc, htb->ch_rate.rs_overhead); htb->ch_mask = (SCH_HTB_HAS_PRIO | SCH_HTB_HAS_RATE | SCH_HTB_HAS_CEIL | SCH_HTB_HAS_RBUFFER | SCH_HTB_HAS_CBUFFER | SCH_HTB_HAS_QUANTUM | SCH_HTB_HAS_LEVEL); } return 0; } static void htb_qdisc_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_htb_qdisc *htb = data; if (!htb) return; if (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM) nl_dump(p, " r2q %u", htb->qh_rate2quantum); if (htb->qh_mask & SCH_HTB_HAS_DEFCLS) { char buf[64]; nl_dump(p, " default-class %s", rtnl_tc_handle2str(htb->qh_defcls, buf, sizeof(buf))); } } static void htb_class_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_htb_class *htb = data; if (!htb) return; if (htb->ch_mask & SCH_HTB_HAS_RATE) { double r, rbit; char *ru, *rubit; r = nl_cancel_down_bytes(htb->ch_rate.rs_rate, &ru); rbit = nl_cancel_down_bits(htb->ch_rate.rs_rate*8, &rubit); nl_dump(p, " rate %.2f%s/s (%.0f%s) log %u", r, ru, rbit, rubit, 1<ch_rate.rs_cell_log); } } static void htb_class_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_htb_class *htb = data; if (!htb) return; /* line 1 */ if (htb->ch_mask & SCH_HTB_HAS_CEIL) { double r, rbit; char *ru, *rubit; r = nl_cancel_down_bytes(htb->ch_ceil.rs_rate, &ru); rbit = nl_cancel_down_bits(htb->ch_ceil.rs_rate*8, &rubit); nl_dump(p, " ceil %.2f%s/s (%.0f%s) log %u", r, ru, rbit, rubit, 1<ch_ceil.rs_cell_log); } if (htb->ch_mask & SCH_HTB_HAS_PRIO) nl_dump(p, " prio %u", htb->ch_prio); if (htb->ch_mask & SCH_HTB_HAS_RBUFFER) { double b; char *bu; b = nl_cancel_down_bytes(htb->ch_rbuffer, &bu); nl_dump(p, " rbuffer %.2f%s", b, bu); } if (htb->ch_mask & SCH_HTB_HAS_CBUFFER) { double b; char *bu; b = nl_cancel_down_bytes(htb->ch_cbuffer, &bu); nl_dump(p, " cbuffer %.2f%s", b, bu); } if (htb->ch_mask & SCH_HTB_HAS_QUANTUM) nl_dump(p, " quantum %u", htb->ch_quantum); } static int htb_qdisc_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_htb_qdisc *htb = data; struct tc_htb_glob opts = { .version = TC_HTB_PROTOVER, .rate2quantum = 10, }; if (htb) { if (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM) opts.rate2quantum = htb->qh_rate2quantum; if (htb->qh_mask & SCH_HTB_HAS_DEFCLS) opts.defcls = htb->qh_defcls; } return nla_put(msg, TCA_HTB_INIT, sizeof(opts), &opts); } static int htb_class_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_htb_class *htb = data; uint32_t mtu, rtable[RTNL_TC_RTABLE_SIZE], ctable[RTNL_TC_RTABLE_SIZE]; struct tc_htb_opt opts; int buffer, cbuffer; if (!htb || !(htb->ch_mask & SCH_HTB_HAS_RATE)) BUG(); memset(&opts, 0, sizeof(opts)); /* if not set, zero (0) is used as priority */ if (htb->ch_mask & SCH_HTB_HAS_PRIO) opts.prio = htb->ch_prio; mtu = rtnl_tc_get_mtu(tc); rtnl_tc_build_rate_table(tc, &htb->ch_rate, rtable); rtnl_rcopy_ratespec(&opts.rate, &htb->ch_rate); if (htb->ch_mask & SCH_HTB_HAS_CEIL) { rtnl_tc_build_rate_table(tc, &htb->ch_ceil, ctable); rtnl_rcopy_ratespec(&opts.ceil, &htb->ch_ceil); } else { /* * If not set, configured rate is used as ceil, which implies * no borrowing. */ memcpy(&opts.ceil, &opts.rate, sizeof(struct tc_ratespec)); } if (htb->ch_mask & SCH_HTB_HAS_RBUFFER) buffer = htb->ch_rbuffer; else buffer = opts.rate.rate / nl_get_psched_hz() + mtu; /* XXX */ opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime(buffer, opts.rate.rate)); if (htb->ch_mask & SCH_HTB_HAS_CBUFFER) cbuffer = htb->ch_cbuffer; else cbuffer = opts.ceil.rate / nl_get_psched_hz() + mtu; /* XXX */ opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime(cbuffer, opts.ceil.rate)); if (htb->ch_mask & SCH_HTB_HAS_QUANTUM) opts.quantum = htb->ch_quantum; NLA_PUT(msg, TCA_HTB_PARMS, sizeof(opts), &opts); NLA_PUT(msg, TCA_HTB_RTAB, sizeof(rtable), &rtable); NLA_PUT(msg, TCA_HTB_CTAB, sizeof(ctable), &ctable); return 0; nla_put_failure: return -NLE_MSGSIZE; } static struct rtnl_tc_ops htb_qdisc_ops; static struct rtnl_tc_ops htb_class_ops; static struct rtnl_htb_qdisc *htb_qdisc_data(struct rtnl_qdisc *qdisc, int *err) { return rtnl_tc_data_check(TC_CAST(qdisc), &htb_qdisc_ops, err); } static struct rtnl_htb_class *htb_class_data(struct rtnl_class *class, int *err) { return rtnl_tc_data_check(TC_CAST(class), &htb_class_ops, err); } /** * @name Attribute Modifications * @{ */ /** * Return rate/quantum ratio of HTB qdisc * @arg qdisc htb qdisc object * * @return rate/quantum ratio or 0 if unspecified */ uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *qdisc) { struct rtnl_htb_qdisc *htb; if ((htb = htb_qdisc_data(qdisc, NULL)) && (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM)) return htb->qh_rate2quantum; return 0; } int rtnl_htb_set_rate2quantum(struct rtnl_qdisc *qdisc, uint32_t rate2quantum) { struct rtnl_htb_qdisc *htb; int err; if (!(htb = htb_qdisc_data(qdisc, &err))) return err; htb->qh_rate2quantum = rate2quantum; htb->qh_mask |= SCH_HTB_HAS_RATE2QUANTUM; return 0; } /** * Return default class of HTB qdisc * @arg qdisc htb qdisc object * * Returns the classid of the class where all unclassified traffic * goes to. * * @return classid or TC_H_UNSPEC if unspecified. */ uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *qdisc) { struct rtnl_htb_qdisc *htb; if ((htb = htb_qdisc_data(qdisc, NULL)) && htb->qh_mask & SCH_HTB_HAS_DEFCLS) return htb->qh_defcls; return TC_H_UNSPEC; } /** * Set default class of the htb qdisc to the specified value * @arg qdisc qdisc to change * @arg defcls new default class */ int rtnl_htb_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls) { struct rtnl_htb_qdisc *htb; int err; if (!(htb = htb_qdisc_data(qdisc, &err))) return err; htb->qh_defcls = defcls; htb->qh_mask |= SCH_HTB_HAS_DEFCLS; return 0; } uint32_t rtnl_htb_get_prio(struct rtnl_class *class) { struct rtnl_htb_class *htb; if ((htb = htb_class_data(class, NULL)) && (htb->ch_mask & SCH_HTB_HAS_PRIO)) return htb->ch_prio; return 0; } int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio) { struct rtnl_htb_class *htb; int err; if (!(htb = htb_class_data(class, &err))) return err; htb->ch_prio = prio; htb->ch_mask |= SCH_HTB_HAS_PRIO; return 0; } /** * Return rate of HTB class * @arg class htb class object * * @return Rate in bytes/s or 0 if unspecified. */ uint32_t rtnl_htb_get_rate(struct rtnl_class *class) { struct rtnl_htb_class *htb; if ((htb = htb_class_data(class, NULL)) && (htb->ch_mask & SCH_HTB_HAS_RATE)) return htb->ch_rate.rs_rate; return 0; } /** * Set rate of HTB class * @arg class htb class object * @arg rate new rate in bytes per second * * @return 0 on success or a negative error code. */ int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate) { struct rtnl_htb_class *htb; int err; if (!(htb = htb_class_data(class, &err))) return err; htb->ch_rate.rs_cell_log = UINT8_MAX; /* use default value */ htb->ch_rate.rs_rate = rate; htb->ch_mask |= SCH_HTB_HAS_RATE; return 0; } /** * Return ceil rate of HTB class * @arg class htb class object * * @return Ceil rate in bytes/s or 0 if unspecified */ uint32_t rtnl_htb_get_ceil(struct rtnl_class *class) { struct rtnl_htb_class *htb; if ((htb = htb_class_data(class, NULL)) && (htb->ch_mask & SCH_HTB_HAS_CEIL)) return htb->ch_ceil.rs_rate; return 0; } /** * Set ceil rate of HTB class * @arg class htb class object * @arg ceil new ceil rate number of bytes per second * * @return 0 on success or a negative error code. */ int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil) { struct rtnl_htb_class *htb; int err; if (!(htb = htb_class_data(class, &err))) return err; htb->ch_ceil.rs_cell_log = UINT8_MAX; /* use default value */ htb->ch_ceil.rs_rate = ceil; htb->ch_mask |= SCH_HTB_HAS_CEIL; return 0; } /** * Return burst buffer size of HTB class * @arg class htb class object * * @return Burst buffer size or 0 if unspecified */ uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *class) { struct rtnl_htb_class *htb; if ((htb = htb_class_data(class, NULL)) && htb->ch_mask & SCH_HTB_HAS_RBUFFER) return htb->ch_rbuffer; return 0; } /** * Set size of the rate bucket of HTB class. * @arg class HTB class to be modified. * @arg rbuffer New size in bytes. */ int rtnl_htb_set_rbuffer(struct rtnl_class *class, uint32_t rbuffer) { struct rtnl_htb_class *htb; int err; if (!(htb = htb_class_data(class, &err))) return err; htb->ch_rbuffer = rbuffer; htb->ch_mask |= SCH_HTB_HAS_RBUFFER; return 0; } /** * Return ceil burst buffer size of HTB class * @arg class htb class object * * @return Ceil burst buffer size or 0 if unspecified */ uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *class) { struct rtnl_htb_class *htb; if ((htb = htb_class_data(class, NULL)) && htb->ch_mask & SCH_HTB_HAS_CBUFFER) return htb->ch_cbuffer; return 0; } /** * Set size of the ceil bucket of HTB class. * @arg class HTB class to be modified. * @arg cbuffer New size in bytes. */ int rtnl_htb_set_cbuffer(struct rtnl_class *class, uint32_t cbuffer) { struct rtnl_htb_class *htb; int err; if (!(htb = htb_class_data(class, &err))) return err; htb->ch_cbuffer = cbuffer; htb->ch_mask |= SCH_HTB_HAS_CBUFFER; return 0; } /** * Return quantum of HTB class * @arg class htb class object * * See XXX[quantum def] * * @return Quantum or 0 if unspecified. */ uint32_t rtnl_htb_get_quantum(struct rtnl_class *class) { struct rtnl_htb_class *htb; if ((htb = htb_class_data(class, NULL)) && htb->ch_mask & SCH_HTB_HAS_QUANTUM) return htb->ch_quantum; return 0; } /** * Set quantum of HTB class (overwrites value calculated based on r2q) * @arg class htb class object * @arg quantum new quantum in number of bytes * * See XXX[quantum def] * * @return 0 on success or a negative error code. */ int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum) { struct rtnl_htb_class *htb; int err; if (!(htb = htb_class_data(class, &err))) return err; htb->ch_quantum = quantum; htb->ch_mask |= SCH_HTB_HAS_QUANTUM; return 0; } /** * Return level of HTB class * @arg class htb class object * * Returns the level of the HTB class. Leaf classes are assigned level * 0, root classes have level (TC_HTB_MAXDEPTH - 1). Interior classes * have a level of one less than their parent. * * @return Level or a negative error code. */ int rtnl_htb_get_level(struct rtnl_class *class) { struct rtnl_htb_class *htb; int err = -NLE_OPNOTSUPP; if ((htb = htb_class_data(class, &err)) && (htb->ch_mask & SCH_HTB_HAS_LEVEL)) return htb->ch_level; return err; } /** * Set level of HTB class * @arg class htb class object * @arg level new level of HTB class * * Sets the level of a HTB class. Note that changing the level of a HTB * class does not change the level of its in kernel counterpart. This * function is provided only to create HTB objects which can be compared * against or filtered upon. * * @return 0 on success or a negative error code. */ int rtnl_htb_set_level(struct rtnl_class *class, int level) { struct rtnl_htb_class *htb; int err; if (!(htb = htb_class_data(class, &err))) return err; htb->ch_level = level; htb->ch_mask |= SCH_HTB_HAS_LEVEL; return 0; } /** @} */ static struct rtnl_tc_ops htb_qdisc_ops = { .to_kind = "htb", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_htb_qdisc), .to_msg_parser = htb_qdisc_msg_parser, .to_dump[NL_DUMP_LINE] = htb_qdisc_dump_line, .to_msg_fill = htb_qdisc_msg_fill, }; static struct rtnl_tc_ops htb_class_ops = { .to_kind = "htb", .to_type = RTNL_TC_TYPE_CLASS, .to_size = sizeof(struct rtnl_htb_class), .to_msg_parser = htb_class_msg_parser, .to_dump = { [NL_DUMP_LINE] = htb_class_dump_line, [NL_DUMP_DETAILS] = htb_class_dump_details, }, .to_msg_fill = htb_class_msg_fill, }; static void __init htb_init(void) { rtnl_tc_register(&htb_qdisc_ops); rtnl_tc_register(&htb_class_ops); } static void __exit htb_exit(void) { rtnl_tc_unregister(&htb_qdisc_ops); rtnl_tc_unregister(&htb_class_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/blackhole.c0000644000175000017500000000142613023014600014717 00000000000000/* * lib/route/qdisc/blackhole.c Blackhole Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @defgroup qdisc_blackhole Blackhole * @{ */ #include #include #include static struct rtnl_tc_ops blackhole_ops = { .to_kind = "blackhole", .to_type = RTNL_TC_TYPE_QDISC, }; static void __init blackhole_init(void) { rtnl_tc_register(&blackhole_ops); } static void __exit blackhole_exit(void) { rtnl_tc_unregister(&blackhole_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/fq_codel.c0000644000175000017500000002245613023014600014555 00000000000000/* * lib/route/qdisc/fq_codel.c fq_codel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ /** * @ingroup qdisc * @defgroup qdisc_fq_codel Fair Queue CoDel * @brief * * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_FQ_CODEL_ATTR_TARGET 0x1 #define SCH_FQ_CODEL_ATTR_LIMIT 0x2 #define SCH_FQ_CODEL_ATTR_INTERVAL 0x4 #define SCH_FQ_CODEL_ATTR_FLOWS 0x8 #define SCH_FQ_CODEL_ATTR_QUANTUM 0x10 #define SCH_FQ_CODEL_ATTR_ECN 0x20 /** @endcond */ static struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = { [TCA_FQ_CODEL_TARGET] = { .type = NLA_U32 }, [TCA_FQ_CODEL_LIMIT] = { .type = NLA_U32 }, [TCA_FQ_CODEL_INTERVAL] = { .type = NLA_U32 }, [TCA_FQ_CODEL_ECN] = { .type = NLA_U32 }, [TCA_FQ_CODEL_FLOWS] = { .type = NLA_U32 }, [TCA_FQ_CODEL_QUANTUM] = { .type = NLA_U32 }, }; static int fq_codel_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_fq_codel *fq_codel = data; struct nlattr *tb[TCA_FQ_CODEL_MAX + 1]; int err; err = tca_parse(tb, TCA_FQ_CODEL_MAX, tc, fq_codel_policy); if (err < 0) return err; if (tb[TCA_FQ_CODEL_TARGET]) { fq_codel->fq_target = nla_get_u32(tb[TCA_FQ_CODEL_TARGET]); fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_TARGET; } if (tb[TCA_FQ_CODEL_INTERVAL]) { fq_codel->fq_interval = nla_get_u32(tb[TCA_FQ_CODEL_INTERVAL]); fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_INTERVAL; } if (tb[TCA_FQ_CODEL_LIMIT]) { fq_codel->fq_limit = nla_get_u32(tb[TCA_FQ_CODEL_LIMIT]); fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_LIMIT; } if (tb[TCA_FQ_CODEL_QUANTUM]) { fq_codel->fq_quantum = nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM]); fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_QUANTUM; } if (tb[TCA_FQ_CODEL_FLOWS]) { fq_codel->fq_flows = nla_get_u32(tb[TCA_FQ_CODEL_FLOWS]); fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_FLOWS; } if (tb[TCA_FQ_CODEL_ECN]) { fq_codel->fq_ecn = nla_get_u32(tb[TCA_FQ_CODEL_ECN]); fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_ECN; } return 0; } static void fq_codel_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_fq_codel *fq_codel = data; if (!fq_codel) return; if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_LIMIT) nl_dump(p, " limit %u packets", fq_codel->fq_limit); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_TARGET) nl_dump(p, " target %u", fq_codel->fq_target); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_INTERVAL) nl_dump(p, " interval %u", fq_codel->fq_interval); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_ECN) nl_dump(p, " ecn %u", fq_codel->fq_ecn); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_FLOWS) nl_dump(p, " flows %u", fq_codel->fq_flows); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_QUANTUM) nl_dump(p, " quantum %u", fq_codel->fq_quantum); } static int fq_codel_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_fq_codel *fq_codel = data; if (!fq_codel) return -NLE_INVAL; if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_LIMIT) NLA_PUT_U32(msg, TCA_FQ_CODEL_LIMIT, fq_codel->fq_limit); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_INTERVAL) NLA_PUT_U32(msg, TCA_FQ_CODEL_INTERVAL, fq_codel->fq_interval); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_TARGET) NLA_PUT_U32(msg, TCA_FQ_CODEL_TARGET, fq_codel->fq_target); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_QUANTUM) NLA_PUT_U32(msg, TCA_FQ_CODEL_QUANTUM, fq_codel->fq_quantum); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_FLOWS) NLA_PUT_U32(msg, TCA_FQ_CODEL_FLOWS, fq_codel->fq_flows); if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_ECN) NLA_PUT_U32(msg, TCA_FQ_CODEL_ECN, fq_codel->fq_ecn); return 0; nla_put_failure: return -NLE_MSGSIZE; } /** * @name Attribute Modification * @{ */ /** * Set limit of fq_codel qdisc. * @arg qdisc fq_codel qdisc to be modified. * @arg limit New limit. * @return 0 on success or a negative error code. */ int rtnl_qdisc_fq_codel_set_limit(struct rtnl_qdisc *qdisc, int limit) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; fq_codel->fq_limit = limit; fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_LIMIT; return 0; } /** * Get limit of a fq_codel qdisc. * @arg qdisc fq_codel qdisc. * @return Numeric limit or a negative error code. */ int rtnl_qdisc_fq_codel_get_limit(struct rtnl_qdisc *qdisc) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_LIMIT) return fq_codel->fq_limit; else return -NLE_NOATTR; } /** * Set target of fq_codel qdisc. * @arg qdisc fq_codel qdisc to be modified. * @arg target New target. * @return 0 on success or a negative error code. */ int rtnl_qdisc_fq_codel_set_target(struct rtnl_qdisc *qdisc, uint32_t target) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; fq_codel->fq_target = target; fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_TARGET; return 0; } /** * Get target of a fq_codel qdisc. * @arg qdisc fq_codel qdisc. * @return Numeric target or zero. */ uint32_t rtnl_qdisc_fq_codel_get_target(struct rtnl_qdisc *qdisc) { struct rtnl_fq_codel *fq_codel; if ((fq_codel = rtnl_tc_data(TC_CAST(qdisc))) && fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_TARGET) return fq_codel->fq_target; else return 0; } /** * Set interval of fq_codel qdisc. * @arg qdisc fq_codel qdisc to be modified. * @arg interval New interval. * @return 0 on success or a negative error code. */ int rtnl_qdisc_fq_codel_set_interval(struct rtnl_qdisc *qdisc, uint32_t interval) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; fq_codel->fq_interval = interval; fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_INTERVAL; return 0; } /** * Get target of a fq_codel qdisc. * @arg qdisc fq_codel qdisc. * @return Numeric interval or zero. */ uint32_t rtnl_qdisc_fq_codel_get_interval(struct rtnl_qdisc *qdisc) { struct rtnl_fq_codel *fq_codel; if ((fq_codel = rtnl_tc_data(TC_CAST(qdisc))) && fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_INTERVAL) return fq_codel->fq_interval; else return 0; } /** * Set quantum of fq_codel qdisc. * @arg qdisc fq_codel qdisc to be modified. * @arg quantum New quantum. * @return 0 on success or a negative error code. */ int rtnl_qdisc_fq_codel_set_quantum(struct rtnl_qdisc *qdisc, uint32_t quantum) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; fq_codel->fq_quantum = quantum; fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_QUANTUM; return 0; } /** * Get quantum of a fq_codel qdisc. * @arg qdisc fq_codel qdisc. * @return Numeric quantum or zero. */ uint32_t rtnl_qdisc_fq_codel_get_quantum(struct rtnl_qdisc *qdisc) { struct rtnl_fq_codel *fq_codel; if ((fq_codel = rtnl_tc_data(TC_CAST(qdisc))) && (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_QUANTUM)) return fq_codel->fq_quantum; else return 0; } /** * Set flows of fq_codel qdisc. * @arg qdisc fq_codel qdisc to be modified. * @arg flows New flows value. * @return 0 on success or a negative error code. */ int rtnl_qdisc_fq_codel_set_flows(struct rtnl_qdisc *qdisc, int flows) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; fq_codel->fq_flows = flows; fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_FLOWS; return 0; } /** * Get flows of a fq_codel qdisc. * @arg qdisc fq_codel qdisc. * @return Numeric flows or a negative error code. */ int rtnl_qdisc_fq_codel_get_flows(struct rtnl_qdisc *qdisc) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_FLOWS) return fq_codel->fq_flows; else return -NLE_NOATTR; } /** * Set ecn of fq_codel qdisc. * @arg qdisc fq_codel qdisc to be modified. * @arg ecn New ecn value. * @return 0 on success or a negative error code. */ int rtnl_qdisc_fq_codel_set_ecn(struct rtnl_qdisc *qdisc, int ecn) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; fq_codel->fq_ecn = ecn; fq_codel->fq_mask |= SCH_FQ_CODEL_ATTR_ECN; return 0; } /** * Get ecn of a fq_codel qdisc. * @arg qdisc fq_codel qdisc. * @return Numeric ecn or a negative error code. */ int rtnl_qdisc_fq_codel_get_ecn(struct rtnl_qdisc *qdisc) { struct rtnl_fq_codel *fq_codel; if (!(fq_codel = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (fq_codel->fq_mask & SCH_FQ_CODEL_ATTR_ECN) return fq_codel->fq_ecn; else return -NLE_NOATTR; } /** @} */ static struct rtnl_tc_ops fq_codel_ops = { .to_kind = "fq_codel", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_fq_codel), .to_msg_parser = fq_codel_msg_parser, .to_dump[NL_DUMP_LINE] = fq_codel_dump_line, .to_msg_fill = fq_codel_msg_fill, }; static void __init fq_codel_init(void) { rtnl_tc_register(&fq_codel_ops); } static void __exit fq_codel_exit(void) { rtnl_tc_unregister(&fq_codel_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/plug.c0000644000175000017500000001125713023014600013745 00000000000000/* * lib/route/qdisc/plug.c PLUG Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2012 Shriram Rajagopalan */ /** * @ingroup qdisc * @defgroup qdisc_plug Plug/Unplug Traffic (PLUG) * @brief * * Queue traffic until an explicit release command. * * There are two ways to use this qdisc: * 1. A simple "instantaneous" plug/unplug operation, by issuing an alternating * sequence of TCQ_PLUG_BUFFER & TCQ_PLUG_RELEASE_INDEFINITE commands. * * 2. For network output buffering (a.k.a output commit) functionality. * Output commit property is commonly used by applications using checkpoint * based fault-tolerance to ensure that the checkpoint from which a system * is being restored is consistent w.r.t outside world. * * Consider for e.g. Remus - a Virtual Machine checkpointing system, * wherein a VM is checkpointed, say every 50ms. The checkpoint is replicated * asynchronously to the backup host, while the VM continues executing the * next epoch speculatively. * * The following is a typical sequence of output buffer operations: * 1.At epoch i, start_buffer(i) * 2. At end of epoch i (i.e. after 50ms): * 2.1 Stop VM and take checkpoint(i). * 2.2 start_buffer(i+1) and Resume VM * 3. While speculatively executing epoch(i+1), asynchronously replicate * checkpoint(i) to backup host. * 4. When checkpoint_ack(i) is received from backup, release_buffer(i) * Thus, this Qdisc would receive the following sequence of commands: * TCQ_PLUG_BUFFER (epoch i) * .. TCQ_PLUG_BUFFER (epoch i+1) * ....TCQ_PLUG_RELEASE_ONE (epoch i) * ......TCQ_PLUG_BUFFER (epoch i+2) * ........ * * * State of the queue, when used for network output buffering: * * plug(i+1) plug(i) head * ------------------+--------------------+----------------> * | | * | | * pkts_current_epoch| pkts_last_epoch |pkts_to_release * ----------------->|<--------+--------->|+---------------> * v v * * * @{ */ #include #include #include #include #include #include static int plug_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_plug *plug = data; struct tc_plug_qopt opts; if (!plug) return -NLE_INVAL; opts.action = plug->action; opts.limit = plug->limit; return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD); } /** * @name Attribute Modification * @{ */ /** * Insert a plug into the qdisc and buffer any incoming * network traffic. * @arg qdisc PLUG qdisc to be modified. */ int rtnl_qdisc_plug_buffer(struct rtnl_qdisc *qdisc) { struct rtnl_plug *plug; if (!(plug = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; plug->action = TCQ_PLUG_BUFFER; return 0; } /** * Unplug the qdisc, releasing packets from queue head * to the last complete buffer, while new traffic * continues to be buffered. * @arg qdisc PLUG qdisc to be modified. */ int rtnl_qdisc_plug_release_one(struct rtnl_qdisc *qdisc) { struct rtnl_plug *plug; if (!(plug = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; plug->action = TCQ_PLUG_RELEASE_ONE; return 0; } /** * Indefinitely unplug the qdisc, releasing all packets. * Network traffic will not be buffered until the next * buffer command is issued. * @arg qdisc PLUG qdisc to be modified. */ int rtnl_qdisc_plug_release_indefinite(struct rtnl_qdisc *qdisc) { struct rtnl_plug *plug; if (!(plug = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; plug->action = TCQ_PLUG_RELEASE_INDEFINITE; return 0; } /** * Set limit of PLUG qdisc. * @arg qdisc PLUG qdisc to be modified. * @arg limit New limit. * @return 0 on success or a negative error code. */ int rtnl_qdisc_plug_set_limit(struct rtnl_qdisc *qdisc, int limit) { struct rtnl_plug *plug; if (!(plug = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; plug->action = TCQ_PLUG_LIMIT; plug->limit = limit; return 0; } /** @} */ static struct rtnl_tc_ops plug_ops = { .to_kind = "plug", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_plug), .to_msg_fill = plug_msg_fill, }; static void __init plug_init(void) { rtnl_tc_register(&plug_ops); } static void __exit plug_exit(void) { rtnl_tc_unregister(&plug_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/prio.c0000644000175000017500000001506713023014600013752 00000000000000/* * lib/route/qdisc/prio.c PRIO Qdisc/Class * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @defgroup qdisc_prio (Fast) Prio * @brief * * @par 1) Typical PRIO configuration * @code * // Specify the maximal number of bands to be used for this PRIO qdisc. * rtnl_qdisc_prio_set_bands(qdisc, QDISC_PRIO_DEFAULT_BANDS); * * // Provide a map assigning each priority to a band number. * uint8_t map[] = QDISC_PRIO_DEFAULT_PRIOMAP; * rtnl_qdisc_prio_set_priomap(qdisc, map, sizeof(map)); * @endcode * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_PRIO_ATTR_BANDS 1 #define SCH_PRIO_ATTR_PRIOMAP 2 /** @endcond */ static int prio_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_prio *prio = data; struct tc_prio_qopt *opt; if (tc->tc_opts->d_size < sizeof(*opt)) return -NLE_INVAL; opt = (struct tc_prio_qopt *) tc->tc_opts->d_data; prio->qp_bands = opt->bands; memcpy(prio->qp_priomap, opt->priomap, sizeof(prio->qp_priomap)); prio->qp_mask = (SCH_PRIO_ATTR_BANDS | SCH_PRIO_ATTR_PRIOMAP); return 0; } static void prio_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_prio *prio = data; if (prio) nl_dump(p, " bands %u", prio->qp_bands); } static void prio_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_prio *prio = data; int i, hp; if (!prio) return; nl_dump(p, "priomap ["); for (i = 0; i <= TC_PRIO_MAX; i++) nl_dump(p, "%u%s", prio->qp_priomap[i], i < TC_PRIO_MAX ? " " : ""); nl_dump(p, "]\n"); nl_new_line(p); hp = (((TC_PRIO_MAX/2) + 1) & ~1); for (i = 0; i < hp; i++) { char a[32]; nl_dump(p, " %18s => %u", rtnl_prio2str(i, a, sizeof(a)), prio->qp_priomap[i]); if (hp+i <= TC_PRIO_MAX) { nl_dump(p, " %18s => %u", rtnl_prio2str(hp+i, a, sizeof(a)), prio->qp_priomap[hp+i]); if (i < (hp - 1)) { nl_dump(p, "\n"); nl_new_line(p); } } } } static int prio_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_prio *prio = data; struct tc_prio_qopt opts; if (!prio || !(prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP)) BUG(); opts.bands = prio->qp_bands; memcpy(opts.priomap, prio->qp_priomap, sizeof(opts.priomap)); return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD); } /** * @name Attribute Modification * @{ */ /** * Set number of bands of PRIO qdisc. * @arg qdisc PRIO qdisc to be modified. * @arg bands New number of bands. * @return 0 on success or a negative error code. */ void rtnl_qdisc_prio_set_bands(struct rtnl_qdisc *qdisc, int bands) { struct rtnl_prio *prio; if (!(prio = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); prio->qp_bands = bands; prio->qp_mask |= SCH_PRIO_ATTR_BANDS; } /** * Get number of bands of PRIO qdisc. * @arg qdisc PRIO qdisc. * @return Number of bands or a negative error code. */ int rtnl_qdisc_prio_get_bands(struct rtnl_qdisc *qdisc) { struct rtnl_prio *prio; if (!(prio = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (prio->qp_mask & SCH_PRIO_ATTR_BANDS) return prio->qp_bands; else return -NLE_NOMEM; } /** * Set priomap of the PRIO qdisc. * @arg qdisc PRIO qdisc to be modified. * @arg priomap New priority mapping. * @arg len Length of priomap (# of elements). * @return 0 on success or a negative error code. */ int rtnl_qdisc_prio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[], int len) { struct rtnl_prio *prio; int i; if (!(prio = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (!(prio->qp_mask & SCH_PRIO_ATTR_BANDS)) return -NLE_MISSING_ATTR; if ((len / sizeof(uint8_t)) > (TC_PRIO_MAX+1)) return -NLE_RANGE; for (i = 0; i <= TC_PRIO_MAX; i++) { if (priomap[i] > prio->qp_bands) return -NLE_RANGE; } memcpy(prio->qp_priomap, priomap, len); prio->qp_mask |= SCH_PRIO_ATTR_PRIOMAP; return 0; } /** * Get priomap of a PRIO qdisc. * @arg qdisc PRIO qdisc. * @return Priority mapping as array of size TC_PRIO_MAX+1 * or NULL if an error occured. */ uint8_t *rtnl_qdisc_prio_get_priomap(struct rtnl_qdisc *qdisc) { struct rtnl_prio *prio; if (!(prio = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP) return prio->qp_priomap; else return NULL; } /** @} */ /** * @name Priority Band Translations * @{ */ static const struct trans_tbl prios[] = { __ADD(TC_PRIO_BESTEFFORT,besteffort), __ADD(TC_PRIO_FILLER,filler), __ADD(TC_PRIO_BULK,bulk), __ADD(TC_PRIO_INTERACTIVE_BULK,interactive_bulk), __ADD(TC_PRIO_INTERACTIVE,interactive), __ADD(TC_PRIO_CONTROL,control), }; /** * Convert priority to character string. * @arg prio Priority. * @arg buf Destination buffer * @arg size Size of destination buffer. * * Converts a priority to a character string and stores the result in * the specified destination buffer. * * @return Name of priority as character string. */ char * rtnl_prio2str(int prio, char *buf, size_t size) { return __type2str(prio, buf, size, prios, ARRAY_SIZE(prios)); } /** * Convert character string to priority. * @arg name Name of priority. * * Converts the provided character string specifying a priority * to the corresponding numeric value. * * @return Numeric priority or a negative value if no match was found. */ int rtnl_str2prio(const char *name) { return __str2type(name, prios, ARRAY_SIZE(prios)); } /** @} */ static struct rtnl_tc_ops prio_ops = { .to_kind = "prio", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_prio), .to_msg_parser = prio_msg_parser, .to_dump = { [NL_DUMP_LINE] = prio_dump_line, [NL_DUMP_DETAILS] = prio_dump_details, }, .to_msg_fill = prio_msg_fill, }; static struct rtnl_tc_ops pfifo_fast_ops = { .to_kind = "pfifo_fast", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_prio), .to_msg_parser = prio_msg_parser, .to_dump = { [NL_DUMP_LINE] = prio_dump_line, [NL_DUMP_DETAILS] = prio_dump_details, }, .to_msg_fill = prio_msg_fill, }; static void __init prio_init(void) { rtnl_tc_register(&prio_ops); rtnl_tc_register(&pfifo_fast_ops); } static void __exit prio_exit(void) { rtnl_tc_unregister(&prio_ops); rtnl_tc_unregister(&pfifo_fast_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/cbq.c0000644000175000017500000001300313023014600013532 00000000000000/* * lib/route/qdisc/cbq.c Class Based Queueing * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ #include #include #include #include #include #include #include #include #include #include /** * @ingroup qdisc * @ingroup class * @defgroup qdisc_cbq Class Based Queueing (CBQ) * @{ */ static const struct trans_tbl ovl_strategies[] = { __ADD(TC_CBQ_OVL_CLASSIC,classic), __ADD(TC_CBQ_OVL_DELAY,delay), __ADD(TC_CBQ_OVL_LOWPRIO,lowprio), __ADD(TC_CBQ_OVL_DROP,drop), __ADD(TC_CBQ_OVL_RCLASSIC,rclassic), }; /** * Convert a CBQ OVL strategy to a character string * @arg type CBQ OVL strategy * @arg buf destination buffer * @arg len length of destination buffer * * Converts a CBQ OVL strategy to a character string and stores in the * provided buffer. Returns the destination buffer or the type * encoded in hex if no match was found. */ char *nl_ovl_strategy2str(int type, char *buf, size_t len) { return __type2str(type, buf, len, ovl_strategies, ARRAY_SIZE(ovl_strategies)); } /** * Convert a string to a CBQ OVL strategy * @arg name CBQ OVL stragegy name * * Converts a CBQ OVL stragegy name to it's corresponding CBQ OVL strategy * type. Returns the type or -1 if none was found. */ int nl_str2ovl_strategy(const char *name) { return __str2type(name, ovl_strategies, ARRAY_SIZE(ovl_strategies)); } static struct nla_policy cbq_policy[TCA_CBQ_MAX+1] = { [TCA_CBQ_LSSOPT] = { .minlen = sizeof(struct tc_cbq_lssopt) }, [TCA_CBQ_RATE] = { .minlen = sizeof(struct tc_ratespec) }, [TCA_CBQ_WRROPT] = { .minlen = sizeof(struct tc_cbq_wrropt) }, [TCA_CBQ_OVL_STRATEGY] = { .minlen = sizeof(struct tc_cbq_ovl) }, [TCA_CBQ_FOPT] = { .minlen = sizeof(struct tc_cbq_fopt) }, [TCA_CBQ_POLICE] = { .minlen = sizeof(struct tc_cbq_police) }, }; static int cbq_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_CBQ_MAX + 1]; struct rtnl_cbq *cbq = data; int err; err = tca_parse(tb, TCA_CBQ_MAX, tc, cbq_policy); if (err < 0) return err; nla_memcpy(&cbq->cbq_lss, tb[TCA_CBQ_LSSOPT], sizeof(cbq->cbq_lss)); nla_memcpy(&cbq->cbq_rate, tb[TCA_CBQ_RATE], sizeof(cbq->cbq_rate)); nla_memcpy(&cbq->cbq_wrr, tb[TCA_CBQ_WRROPT], sizeof(cbq->cbq_wrr)); nla_memcpy(&cbq->cbq_fopt, tb[TCA_CBQ_FOPT], sizeof(cbq->cbq_fopt)); nla_memcpy(&cbq->cbq_ovl, tb[TCA_CBQ_OVL_STRATEGY], sizeof(cbq->cbq_ovl)); nla_memcpy(&cbq->cbq_police, tb[TCA_CBQ_POLICE], sizeof(cbq->cbq_police)); return 0; } static void cbq_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_cbq *cbq = data; double r, rbit; char *ru, *rubit; if (!cbq) return; r = nl_cancel_down_bytes(cbq->cbq_rate.rate, &ru); rbit = nl_cancel_down_bits(cbq->cbq_rate.rate * 8, &rubit); nl_dump(p, " rate %.2f%s/s (%.0f%s) prio %u", r, ru, rbit, rubit, cbq->cbq_wrr.priority); } static void cbq_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_cbq *cbq = data; char *unit, buf[32]; double w; uint32_t el; if (!cbq) return; w = nl_cancel_down_bits(cbq->cbq_wrr.weight * 8, &unit); nl_dump(p, "avgpkt %u mpu %u cell %u allot %u weight %.0f%s\n", cbq->cbq_lss.avpkt, cbq->cbq_rate.mpu, 1 << cbq->cbq_rate.cell_log, cbq->cbq_wrr.allot, w, unit); el = cbq->cbq_lss.ewma_log; nl_dump_line(p, " minidle %uus maxidle %uus offtime " "%uus level %u ewma_log %u\n", nl_ticks2us(cbq->cbq_lss.minidle >> el), nl_ticks2us(cbq->cbq_lss.maxidle >> el), nl_ticks2us(cbq->cbq_lss.offtime >> el), cbq->cbq_lss.level, cbq->cbq_lss.ewma_log); nl_dump_line(p, " penalty %uus strategy %s ", nl_ticks2us(cbq->cbq_ovl.penalty), nl_ovl_strategy2str(cbq->cbq_ovl.strategy, buf, sizeof(buf))); nl_dump(p, "split %s defmap 0x%08x ", rtnl_tc_handle2str(cbq->cbq_fopt.split, buf, sizeof(buf)), cbq->cbq_fopt.defmap); nl_dump(p, "police %s", nl_police2str(cbq->cbq_police.police, buf, sizeof(buf))); } static void cbq_dump_stats(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct tc_cbq_xstats *x; if (!(x = tca_xstats(tc))) return; nl_dump_line(p, " borrows overact " " avgidle undertime\n"); nl_dump_line(p, " %10u %10u %10u %10u\n", x->borrows, x->overactions, x->avgidle, x->undertime); } static struct rtnl_tc_ops cbq_qdisc_ops = { .to_kind = "cbq", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_cbq), .to_msg_parser = cbq_msg_parser, .to_dump = { [NL_DUMP_LINE] = cbq_dump_line, [NL_DUMP_DETAILS] = cbq_dump_details, [NL_DUMP_STATS] = cbq_dump_stats, }, }; static struct rtnl_tc_ops cbq_class_ops = { .to_kind = "cbq", .to_type = RTNL_TC_TYPE_CLASS, .to_size = sizeof(struct rtnl_cbq), .to_msg_parser = cbq_msg_parser, .to_dump = { [NL_DUMP_LINE] = cbq_dump_line, [NL_DUMP_DETAILS] = cbq_dump_details, [NL_DUMP_STATS] = cbq_dump_stats, }, }; static void __init cbq_init(void) { rtnl_tc_register(&cbq_qdisc_ops); rtnl_tc_register(&cbq_class_ops); } static void __exit cbq_exit(void) { rtnl_tc_unregister(&cbq_qdisc_ops); rtnl_tc_unregister(&cbq_class_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/tbf.c0000644000175000017500000002474013023014600013552 00000000000000/* * lib/route/qdisc/tbf.c TBF Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @defgroup qdisc_tbf Token Bucket Filter (TBF) * @{ */ #include #include #include #include #include #include #include #include #include #include /** @cond SKIP */ #define TBF_ATTR_LIMIT 0x01 #define TBF_ATTR_RATE 0x02 #define TBF_ATTR_PEAKRATE 0x10 /** @endcond */ static struct nla_policy tbf_policy[TCA_TBF_MAX+1] = { [TCA_TBF_PARMS] = { .minlen = sizeof(struct tc_tbf_qopt) }, }; static int tbf_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_TBF_MAX + 1]; struct rtnl_tbf *tbf = data; int err; if ((err = tca_parse(tb, TCA_TBF_MAX, tc, tbf_policy)) < 0) return err; if (tb[TCA_TBF_PARMS]) { struct tc_tbf_qopt opts; int bufsize; nla_memcpy(&opts, tb[TCA_TBF_PARMS], sizeof(opts)); tbf->qt_limit = opts.limit; rtnl_copy_ratespec(&tbf->qt_rate, &opts.rate); tbf->qt_rate_txtime = opts.buffer; bufsize = rtnl_tc_calc_bufsize(nl_ticks2us(opts.buffer), opts.rate.rate); tbf->qt_rate_bucket = bufsize; rtnl_copy_ratespec(&tbf->qt_peakrate, &opts.peakrate); tbf->qt_peakrate_txtime = opts.mtu; bufsize = rtnl_tc_calc_bufsize(nl_ticks2us(opts.mtu), opts.peakrate.rate); tbf->qt_peakrate_bucket = bufsize; rtnl_tc_set_mpu(tc, tbf->qt_rate.rs_mpu); rtnl_tc_set_overhead(tc, tbf->qt_rate.rs_overhead); tbf->qt_mask = (TBF_ATTR_LIMIT | TBF_ATTR_RATE | TBF_ATTR_PEAKRATE); } return 0; } static void tbf_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { double r, rbit, lim; char *ru, *rubit, *limu; struct rtnl_tbf *tbf = data; if (!tbf) return; r = nl_cancel_down_bytes(tbf->qt_rate.rs_rate, &ru); rbit = nl_cancel_down_bits(tbf->qt_rate.rs_rate*8, &rubit); lim = nl_cancel_down_bytes(tbf->qt_limit, &limu); nl_dump(p, " rate %.2f%s/s (%.0f%s) limit %.2f%s", r, ru, rbit, rubit, lim, limu); } static void tbf_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_tbf *tbf = data; if (!tbf) return; if (1) { char *bu, *cu; double bs = nl_cancel_down_bytes(tbf->qt_rate_bucket, &bu); double cl = nl_cancel_down_bytes(1 << tbf->qt_rate.rs_cell_log, &cu); nl_dump(p, "rate-bucket-size %1.f%s " "rate-cell-size %.1f%s\n", bs, bu, cl, cu); } if (tbf->qt_mask & TBF_ATTR_PEAKRATE) { char *pru, *prbu, *bsu, *clu; double pr, prb, bs, cl; pr = nl_cancel_down_bytes(tbf->qt_peakrate.rs_rate, &pru); prb = nl_cancel_down_bits(tbf->qt_peakrate.rs_rate * 8, &prbu); bs = nl_cancel_down_bits(tbf->qt_peakrate_bucket, &bsu); cl = nl_cancel_down_bits(1 << tbf->qt_peakrate.rs_cell_log, &clu); nl_dump_line(p, " peak-rate %.2f%s/s (%.0f%s) " "bucket-size %.1f%s cell-size %.1f%s" "latency %.1f%s", pr, pru, prb, prbu, bs, bsu, cl, clu); } } static int tbf_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { uint32_t rtab[RTNL_TC_RTABLE_SIZE], ptab[RTNL_TC_RTABLE_SIZE]; struct tc_tbf_qopt opts; struct rtnl_tbf *tbf = data; int required = TBF_ATTR_RATE | TBF_ATTR_LIMIT; if ((tbf->qt_mask & required) != required) return -NLE_MISSING_ATTR; memset(&opts, 0, sizeof(opts)); opts.limit = tbf->qt_limit; opts.buffer = tbf->qt_rate_txtime; rtnl_tc_build_rate_table(tc, &tbf->qt_rate, rtab); rtnl_rcopy_ratespec(&opts.rate, &tbf->qt_rate); if (tbf->qt_mask & TBF_ATTR_PEAKRATE) { opts.mtu = tbf->qt_peakrate_txtime; rtnl_tc_build_rate_table(tc, &tbf->qt_peakrate, ptab); rtnl_rcopy_ratespec(&opts.peakrate, &tbf->qt_peakrate); } NLA_PUT(msg, TCA_TBF_PARMS, sizeof(opts), &opts); NLA_PUT(msg, TCA_TBF_RTAB, sizeof(rtab), rtab); if (tbf->qt_mask & TBF_ATTR_PEAKRATE) NLA_PUT(msg, TCA_TBF_PTAB, sizeof(ptab), ptab); return 0; nla_put_failure: return -NLE_MSGSIZE; } /** * @name Attribute Access * @{ */ /** * Set limit of TBF qdisc. * @arg qdisc TBF qdisc to be modified. * @arg limit New limit in bytes. * @return 0 on success or a negative error code. */ void rtnl_qdisc_tbf_set_limit(struct rtnl_qdisc *qdisc, int limit) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); tbf->qt_limit = limit; tbf->qt_mask |= TBF_ATTR_LIMIT; } static inline double calc_limit(struct rtnl_ratespec *spec, int latency, int bucket) { double limit; limit = (double) spec->rs_rate * ((double) latency / 1000000.); limit += bucket; return limit; } /** * Set limit of TBF qdisc by latency. * @arg qdisc TBF qdisc to be modified. * @arg latency Latency in micro seconds. * * Calculates and sets the limit based on the desired latency and the * configured rate and peak rate. In order for this operation to succeed, * the rate and if required the peak rate must have been set in advance. * * @f[ * limit_n = \frac{{rate_n} \times {latency}}{10^6}+{bucketsize}_n * @f] * @f[ * limit = min(limit_{rate},limit_{peak}) * @f] * * @return 0 on success or a negative error code. */ int rtnl_qdisc_tbf_set_limit_by_latency(struct rtnl_qdisc *qdisc, int latency) { struct rtnl_tbf *tbf; double limit, limit2; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (!(tbf->qt_mask & TBF_ATTR_RATE)) return -NLE_MISSING_ATTR; limit = calc_limit(&tbf->qt_rate, latency, tbf->qt_rate_bucket); if (tbf->qt_mask & TBF_ATTR_PEAKRATE) { limit2 = calc_limit(&tbf->qt_peakrate, latency, tbf->qt_peakrate_bucket); if (limit2 < limit) limit = limit2; } rtnl_qdisc_tbf_set_limit(qdisc, (int) limit); return 0; } /** * Get limit of TBF qdisc. * @arg qdisc TBF qdisc. * @return Limit in bytes or a negative error code. */ int rtnl_qdisc_tbf_get_limit(struct rtnl_qdisc *qdisc) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (tbf->qt_mask & TBF_ATTR_LIMIT) return tbf->qt_limit; else return -NLE_NOATTR; } static inline int calc_cell_log(int cell, int bucket) { cell = rtnl_tc_calc_cell_log(cell); return cell; } /** * Set rate of TBF qdisc. * @arg qdisc TBF qdisc to be modified. * @arg rate New rate in bytes per second. * @arg bucket Size of bucket in bytes. * @arg cell Size of a rate cell or 0 to get default value. * @return 0 on success or a negative error code. */ void rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *qdisc, int rate, int bucket, int cell) { struct rtnl_tbf *tbf; int cell_log; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (!cell) cell_log = UINT8_MAX; else cell_log = rtnl_tc_calc_cell_log(cell); tbf->qt_rate.rs_rate = rate; tbf->qt_rate_bucket = bucket; tbf->qt_rate.rs_cell_log = cell_log; tbf->qt_rate_txtime = nl_us2ticks(rtnl_tc_calc_txtime(bucket, rate)); tbf->qt_mask |= TBF_ATTR_RATE; } /** * Get rate of TBF qdisc. * @arg qdisc TBF qdisc. * @return Rate in bytes per seconds or a negative error code. */ int rtnl_qdisc_tbf_get_rate(struct rtnl_qdisc *qdisc) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (tbf->qt_mask & TBF_ATTR_RATE) return tbf->qt_rate.rs_rate; else return -1; } /** * Get rate bucket size of TBF qdisc. * @arg qdisc TBF qdisc. * @return Size of rate bucket or a negative error code. */ int rtnl_qdisc_tbf_get_rate_bucket(struct rtnl_qdisc *qdisc) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (tbf->qt_mask & TBF_ATTR_RATE) return tbf->qt_rate_bucket; else return -1; } /** * Get rate cell size of TBF qdisc. * @arg qdisc TBF qdisc. * @return Size of rate cell in bytes or a negative error code. */ int rtnl_qdisc_tbf_get_rate_cell(struct rtnl_qdisc *qdisc) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (tbf->qt_mask & TBF_ATTR_RATE) return (1 << tbf->qt_rate.rs_cell_log); else return -1; } /** * Set peak rate of TBF qdisc. * @arg qdisc TBF qdisc to be modified. * @arg rate New peak rate in bytes per second. * @arg bucket Size of peakrate bucket. * @arg cell Size of a peakrate cell or 0 to get default value. * @return 0 on success or a negative error code. */ int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *qdisc, int rate, int bucket, int cell) { struct rtnl_tbf *tbf; int cell_log; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); cell_log = calc_cell_log(cell, bucket); if (cell_log < 0) return cell_log; tbf->qt_peakrate.rs_rate = rate; tbf->qt_peakrate_bucket = bucket; tbf->qt_peakrate.rs_cell_log = cell_log; tbf->qt_peakrate_txtime = nl_us2ticks(rtnl_tc_calc_txtime(bucket, rate)); tbf->qt_mask |= TBF_ATTR_PEAKRATE; return 0; } /** * Get peak rate of TBF qdisc. * @arg qdisc TBF qdisc. * @return Peak rate in bytes per seconds or a negative error code. */ int rtnl_qdisc_tbf_get_peakrate(struct rtnl_qdisc *qdisc) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (tbf->qt_mask & TBF_ATTR_PEAKRATE) return tbf->qt_peakrate.rs_rate; else return -1; } /** * Get peak rate bucket size of TBF qdisc. * @arg qdisc TBF qdisc. * @return Size of peak rate bucket or a negative error code. */ int rtnl_qdisc_tbf_get_peakrate_bucket(struct rtnl_qdisc *qdisc) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (tbf->qt_mask & TBF_ATTR_PEAKRATE) return tbf->qt_peakrate_bucket; else return -1; } /** * Get peak rate cell size of TBF qdisc. * @arg qdisc TBF qdisc. * @return Size of peak rate cell in bytes or a negative error code. */ int rtnl_qdisc_tbf_get_peakrate_cell(struct rtnl_qdisc *qdisc) { struct rtnl_tbf *tbf; if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (tbf->qt_mask & TBF_ATTR_PEAKRATE) return (1 << tbf->qt_peakrate.rs_cell_log); else return -1; } /** @} */ static struct rtnl_tc_ops tbf_tc_ops = { .to_kind = "tbf", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_tbf), .to_msg_parser = tbf_msg_parser, .to_dump = { [NL_DUMP_LINE] = tbf_dump_line, [NL_DUMP_DETAILS] = tbf_dump_details, }, .to_msg_fill = tbf_msg_fill, }; static void __init tbf_init(void) { rtnl_tc_register(&tbf_tc_ops); } static void __exit tbf_exit(void) { rtnl_tc_unregister(&tbf_tc_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/fifo.c0000644000175000017500000000746313023014600013725 00000000000000/* * lib/route/qdisc/fifo.c (p|b)fifo * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @defgroup qdisc_fifo Packet/Bytes FIFO (pfifo/bfifo) * @brief * * The FIFO qdisc comes in two flavours: * @par bfifo (Byte FIFO) * Allows enqueuing until the currently queued volume in bytes exceeds * the configured limit.backlog contains currently enqueued volume in bytes. * * @par pfifo (Packet FIFO) * Allows enquueing until the currently queued number of packets * exceeds the configured limit. * * The configuration is exactly the same, the decision which of * the two variations is going to be used is made based on the * kind of the qdisc (rtnl_tc_set_kind()). * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_FIFO_ATTR_LIMIT 1 /** @endcond */ static int fifo_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_fifo *fifo = data; struct tc_fifo_qopt *opt; if (tc->tc_opts->d_size < sizeof(struct tc_fifo_qopt)) return -NLE_INVAL; opt = (struct tc_fifo_qopt *) tc->tc_opts->d_data; fifo->qf_limit = opt->limit; fifo->qf_mask = SCH_FIFO_ATTR_LIMIT; return 0; } static void pfifo_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_fifo *fifo = data; if (fifo) nl_dump(p, " limit %u packets", fifo->qf_limit); } static void bfifo_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_fifo *fifo = data; char *unit; double r; if (!fifo) return; r = nl_cancel_down_bytes(fifo->qf_limit, &unit); nl_dump(p, " limit %.1f%s", r, unit); } static int fifo_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_fifo *fifo = data; struct tc_fifo_qopt opts = {0}; if (!fifo || !(fifo->qf_mask & SCH_FIFO_ATTR_LIMIT)) return -NLE_INVAL; opts.limit = fifo->qf_limit; return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD); } /** * @name Attribute Modification * @{ */ /** * Set limit of FIFO qdisc. * @arg qdisc FIFO qdisc to be modified. * @arg limit New limit. * @return 0 on success or a negative error code. */ int rtnl_qdisc_fifo_set_limit(struct rtnl_qdisc *qdisc, int limit) { struct rtnl_fifo *fifo; if (!(fifo = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; fifo->qf_limit = limit; fifo->qf_mask |= SCH_FIFO_ATTR_LIMIT; return 0; } /** * Get limit of a FIFO qdisc. * @arg qdisc FIFO qdisc. * @return Numeric limit or a negative error code. */ int rtnl_qdisc_fifo_get_limit(struct rtnl_qdisc *qdisc) { struct rtnl_fifo *fifo; if (!(fifo = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (fifo->qf_mask & SCH_FIFO_ATTR_LIMIT) return fifo->qf_limit; else return -NLE_NOATTR; } /** @} */ static struct rtnl_tc_ops pfifo_ops = { .to_kind = "pfifo", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_fifo), .to_msg_parser = fifo_msg_parser, .to_dump[NL_DUMP_LINE] = pfifo_dump_line, .to_msg_fill = fifo_msg_fill, }; static struct rtnl_tc_ops bfifo_ops = { .to_kind = "bfifo", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_fifo), .to_msg_parser = fifo_msg_parser, .to_dump[NL_DUMP_LINE] = bfifo_dump_line, .to_msg_fill = fifo_msg_fill, }; static void __init fifo_init(void) { rtnl_tc_register(&pfifo_ops); rtnl_tc_register(&bfifo_ops); } static void __exit fifo_exit(void) { rtnl_tc_unregister(&pfifo_ops); rtnl_tc_unregister(&bfifo_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/red.c0000644000175000017500000000752113023014600013547 00000000000000/* * lib/route/qdisc/red.c RED Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @defgroup qdisc_red Random Early Detection (RED) * @brief * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define RED_ATTR_LIMIT 0x01 #define RED_ATTR_QTH_MIN 0x02 #define RED_ATTR_QTH_MAX 0x04 #define RED_ATTR_FLAGS 0x08 #define RED_ATTR_WLOG 0x10 #define RED_ATTR_PLOG 0x20 #define RED_ATTR_SCELL_LOG 0x40 /** @endcond */ static struct nla_policy red_policy[TCA_RED_MAX+1] = { [TCA_RED_PARMS] = { .minlen = sizeof(struct tc_red_qopt) }, }; static int red_msg_parser(struct rtnl_tc *tc, void *data) { struct nlattr *tb[TCA_RED_MAX+1]; struct rtnl_red *red = data; struct tc_red_qopt *opts; int err; if (!(tc->ce_mask & TCA_ATTR_OPTS)) return 0; err = tca_parse(tb, TCA_RED_MAX, tc, red_policy); if (err < 0) return err; if (!tb[TCA_RED_PARMS]) return -NLE_MISSING_ATTR; opts = nla_data(tb[TCA_RED_PARMS]); red->qr_limit = opts->limit; red->qr_qth_min = opts->qth_min; red->qr_qth_max = opts->qth_max; red->qr_flags = opts->flags; red->qr_wlog = opts->Wlog; red->qr_plog = opts->Plog; red->qr_scell_log = opts->Scell_log; red->qr_mask = (RED_ATTR_LIMIT | RED_ATTR_QTH_MIN | RED_ATTR_QTH_MAX | RED_ATTR_FLAGS | RED_ATTR_WLOG | RED_ATTR_PLOG | RED_ATTR_SCELL_LOG); return 0; } static void red_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_red *red = data; if (red) { /* XXX: limit, min, max, flags */ } } static void red_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_red *red = data; if (red) { /* XXX: wlog, plog, scell_log */ } } static void red_dump_stats(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_red *red = data; if (red) { /* XXX: xstats */ } } static int red_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_red *red = data; if (!red) BUG(); #if 0 memset(&opts, 0, sizeof(opts)); opts.quantum = sfq->qs_quantum; opts.perturb_period = sfq->qs_perturb; opts.limit = sfq->qs_limit; if (nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD) < 0) goto errout; #endif return -NLE_OPNOTSUPP; } /** * @name Attribute Access * @{ */ /** * Set limit of RED qdisc. * @arg qdisc RED qdisc to be modified. * @arg limit New limit in number of packets. * @return 0 on success or a negative error code. */ void rtnl_red_set_limit(struct rtnl_qdisc *qdisc, int limit) { struct rtnl_red *red; if (!(red = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); red->qr_limit = limit; red->qr_mask |= RED_ATTR_LIMIT; } /** * Get limit of RED qdisc. * @arg qdisc RED qdisc. * @return Limit or a negative error code. */ int rtnl_red_get_limit(struct rtnl_qdisc *qdisc) { struct rtnl_red *red; if (!(red = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (red->qr_mask & RED_ATTR_LIMIT) return red->qr_limit; else return -NLE_NOATTR; } /** @} */ static struct rtnl_tc_ops red_ops = { .to_kind = "red", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_red), .to_msg_parser = red_msg_parser, .to_dump = { [NL_DUMP_LINE] = red_dump_line, [NL_DUMP_DETAILS] = red_dump_details, [NL_DUMP_STATS] = red_dump_stats, }, .to_msg_fill = red_msg_fill, }; static void __init red_init(void) { rtnl_tc_register(&red_ops); } static void __exit red_exit(void) { rtnl_tc_unregister(&red_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/ingress.c0000644000175000017500000000244013023014600014442 00000000000000/* * lib/route/qdisc/ingress.c ingress * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ /** * @ingroup qdisc * @defgroup qdisc_ingress Ingress qdisc * * @{ */ #include #include #include #include #include #include struct dumb { uint32_t foo; }; static int dumb_msg_parser(struct rtnl_tc *tc, void *data) { return 0; } static void dumb_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { } static int dumb_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { return 0; } static struct rtnl_tc_ops ingress_ops = { .to_kind = "ingress", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct dumb), .to_msg_parser = dumb_msg_parser, .to_dump[NL_DUMP_LINE] = dumb_dump_line, .to_msg_fill = dumb_msg_fill, }; static void __init ingress_init(void) { rtnl_tc_register(&ingress_ops); } static void __exit ingress_exit(void) { rtnl_tc_unregister(&ingress_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/sfq.c0000644000175000017500000001310013023014600013554 00000000000000/* * lib/route/qdisc/sfq.c SFQ Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @defgroup qdisc_sfq Stochastic Fairness Queueing (SFQ) * @brief * * @par Parameter Description * - \b Quantum: Number of bytes to send out per slot and round. * - \b Perturbation: Timer period between changing the hash function. * - \b Limit: Upper limit of queue in number of packets before SFQ starts * dropping packets. * - \b Divisor: Hash table divisor, i.e. size of hash table. * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_SFQ_ATTR_QUANTUM 0x01 #define SCH_SFQ_ATTR_PERTURB 0x02 #define SCH_SFQ_ATTR_LIMIT 0x04 #define SCH_SFQ_ATTR_DIVISOR 0x08 #define SCH_SFQ_ATTR_FLOWS 0x10 /** @endcond */ static int sfq_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_sfq *sfq = data; struct tc_sfq_qopt *opts; if (!(tc->ce_mask & TCA_ATTR_OPTS)) return 0; if (tc->tc_opts->d_size < sizeof(*opts)) return -NLE_INVAL; opts = (struct tc_sfq_qopt *) tc->tc_opts->d_data; sfq->qs_quantum = opts->quantum; sfq->qs_perturb = opts->perturb_period; sfq->qs_limit = opts->limit; sfq->qs_divisor = opts->divisor; sfq->qs_flows = opts->flows; sfq->qs_mask = (SCH_SFQ_ATTR_QUANTUM | SCH_SFQ_ATTR_PERTURB | SCH_SFQ_ATTR_LIMIT | SCH_SFQ_ATTR_DIVISOR | SCH_SFQ_ATTR_FLOWS); return 0; } static void sfq_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_sfq *sfq = data; if (sfq) nl_dump(p, " quantum %u perturb %us", sfq->qs_quantum, sfq->qs_perturb); } static void sfq_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_sfq *sfq = data; if (sfq) nl_dump(p, "limit %u divisor %u", sfq->qs_limit, sfq->qs_divisor); } static int sfq_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_sfq *sfq = data; struct tc_sfq_qopt opts = {0}; if (!sfq) BUG(); opts.quantum = sfq->qs_quantum; opts.perturb_period = sfq->qs_perturb; opts.limit = sfq->qs_limit; return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD); } /** * @name Attribute Access * @{ */ /** * Set quantum of SFQ qdisc. * @arg qdisc SFQ qdisc to be modified. * @arg quantum New quantum in bytes. * @return 0 on success or a negative error code. */ void rtnl_sfq_set_quantum(struct rtnl_qdisc *qdisc, int quantum) { struct rtnl_sfq *sfq; if (!(sfq = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); sfq->qs_quantum = quantum; sfq->qs_mask |= SCH_SFQ_ATTR_QUANTUM; } /** * Get quantum of SFQ qdisc. * @arg qdisc SFQ qdisc. * @return Quantum in bytes or a negative error code. */ int rtnl_sfq_get_quantum(struct rtnl_qdisc *qdisc) { struct rtnl_sfq *sfq; if (!(sfq = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (sfq->qs_mask & SCH_SFQ_ATTR_QUANTUM) return sfq->qs_quantum; else return -NLE_NOATTR; } /** * Set limit of SFQ qdisc. * @arg qdisc SFQ qdisc to be modified. * @arg limit New limit in number of packets. * @return 0 on success or a negative error code. */ void rtnl_sfq_set_limit(struct rtnl_qdisc *qdisc, int limit) { struct rtnl_sfq *sfq; if (!(sfq = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); sfq->qs_limit = limit; sfq->qs_mask |= SCH_SFQ_ATTR_LIMIT; } /** * Get limit of SFQ qdisc. * @arg qdisc SFQ qdisc. * @return Limit or a negative error code. */ int rtnl_sfq_get_limit(struct rtnl_qdisc *qdisc) { struct rtnl_sfq *sfq; if (!(sfq = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (sfq->qs_mask & SCH_SFQ_ATTR_LIMIT) return sfq->qs_limit; else return -NLE_NOATTR; } /** * Set perturbation interval of SFQ qdisc. * @arg qdisc SFQ qdisc to be modified. * @arg perturb New perturbation interval in seconds. * @note A value of 0 disables perturbation altogether. * @return 0 on success or a negative error code. */ void rtnl_sfq_set_perturb(struct rtnl_qdisc *qdisc, int perturb) { struct rtnl_sfq *sfq; if (!(sfq = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); sfq->qs_perturb = perturb; sfq->qs_mask |= SCH_SFQ_ATTR_PERTURB; } /** * Get perturbation interval of SFQ qdisc. * @arg qdisc SFQ qdisc. * @return Perturbation interval in seconds or a negative error code. */ int rtnl_sfq_get_perturb(struct rtnl_qdisc *qdisc) { struct rtnl_sfq *sfq; if (!(sfq = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (sfq->qs_mask & SCH_SFQ_ATTR_PERTURB) return sfq->qs_perturb; else return -NLE_NOATTR; } /** * Get divisor of SFQ qdisc. * @arg qdisc SFQ qdisc. * @return Divisor in number of entries or a negative error code. */ int rtnl_sfq_get_divisor(struct rtnl_qdisc *qdisc) { struct rtnl_sfq *sfq; if (!(sfq = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (sfq->qs_mask & SCH_SFQ_ATTR_DIVISOR) return sfq->qs_divisor; else return -NLE_NOATTR; } /** @} */ static struct rtnl_tc_ops sfq_ops = { .to_kind = "sfq", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_sfq), .to_msg_parser = sfq_msg_parser, .to_dump = { [NL_DUMP_LINE] = sfq_dump_line, [NL_DUMP_DETAILS] = sfq_dump_details, }, .to_msg_fill = sfq_msg_fill, }; static void __init sfq_init(void) { rtnl_tc_register(&sfq_ops); } static void __exit sfq_exit(void) { rtnl_tc_unregister(&sfq_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/netem.c0000644000175000017500000005725013023014600014111 00000000000000/* * lib/route/qdisc/netem.c Network Emulator Qdisc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @defgroup qdisc_netem Network Emulator * @brief * * For further documentation see http://linux-net.osdl.org/index.php/Netem * @{ */ #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_NETEM_ATTR_LATENCY 0x0001 #define SCH_NETEM_ATTR_LIMIT 0x0002 #define SCH_NETEM_ATTR_LOSS 0x0004 #define SCH_NETEM_ATTR_GAP 0x0008 #define SCH_NETEM_ATTR_DUPLICATE 0x0010 #define SCH_NETEM_ATTR_JITTER 0x0020 #define SCH_NETEM_ATTR_DELAY_CORR 0x0040 #define SCH_NETEM_ATTR_LOSS_CORR 0x0080 #define SCH_NETEM_ATTR_DUP_CORR 0x0100 #define SCH_NETEM_ATTR_RO_PROB 0x0200 #define SCH_NETEM_ATTR_RO_CORR 0x0400 #define SCH_NETEM_ATTR_CORRUPT_PROB 0x0800 #define SCH_NETEM_ATTR_CORRUPT_CORR 0x1000 #define SCH_NETEM_ATTR_DIST 0x2000 /** @endcond */ static struct nla_policy netem_policy[TCA_NETEM_MAX+1] = { [TCA_NETEM_CORR] = { .minlen = sizeof(struct tc_netem_corr) }, [TCA_NETEM_REORDER] = { .minlen = sizeof(struct tc_netem_reorder) }, [TCA_NETEM_CORRUPT] = { .minlen = sizeof(struct tc_netem_corrupt) }, }; static int netem_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_netem *netem = data; struct tc_netem_qopt *opts; int len, err = 0; if (tc->tc_opts->d_size < sizeof(*opts)) return -NLE_INVAL; opts = (struct tc_netem_qopt *) tc->tc_opts->d_data; netem->qnm_latency = opts->latency; netem->qnm_limit = opts->limit; netem->qnm_loss = opts->loss; netem->qnm_gap = opts->gap; netem->qnm_duplicate = opts->duplicate; netem->qnm_jitter = opts->jitter; netem->qnm_mask = (SCH_NETEM_ATTR_LATENCY | SCH_NETEM_ATTR_LIMIT | SCH_NETEM_ATTR_LOSS | SCH_NETEM_ATTR_GAP | SCH_NETEM_ATTR_DUPLICATE | SCH_NETEM_ATTR_JITTER); len = tc->tc_opts->d_size - sizeof(*opts); if (len > 0) { struct nlattr *tb[TCA_NETEM_MAX+1]; err = nla_parse(tb, TCA_NETEM_MAX, (struct nlattr *) (tc->tc_opts->d_data + sizeof(*opts)), len, netem_policy); if (err < 0) { free(netem); return err; } if (tb[TCA_NETEM_CORR]) { struct tc_netem_corr cor; nla_memcpy(&cor, tb[TCA_NETEM_CORR], sizeof(cor)); netem->qnm_corr.nmc_delay = cor.delay_corr; netem->qnm_corr.nmc_loss = cor.loss_corr; netem->qnm_corr.nmc_duplicate = cor.dup_corr; netem->qnm_mask |= (SCH_NETEM_ATTR_DELAY_CORR | SCH_NETEM_ATTR_LOSS_CORR | SCH_NETEM_ATTR_DUP_CORR); } if (tb[TCA_NETEM_REORDER]) { struct tc_netem_reorder ro; nla_memcpy(&ro, tb[TCA_NETEM_REORDER], sizeof(ro)); netem->qnm_ro.nmro_probability = ro.probability; netem->qnm_ro.nmro_correlation = ro.correlation; netem->qnm_mask |= (SCH_NETEM_ATTR_RO_PROB | SCH_NETEM_ATTR_RO_CORR); } if (tb[TCA_NETEM_CORRUPT]) { struct tc_netem_corrupt corrupt; nla_memcpy(&corrupt, tb[TCA_NETEM_CORRUPT], sizeof(corrupt)); netem->qnm_crpt.nmcr_probability = corrupt.probability; netem->qnm_crpt.nmcr_correlation = corrupt.correlation; netem->qnm_mask |= (SCH_NETEM_ATTR_CORRUPT_PROB | SCH_NETEM_ATTR_CORRUPT_CORR); } /* sch_netem does not currently dump TCA_NETEM_DELAY_DIST */ netem->qnm_dist.dist_data = NULL; netem->qnm_dist.dist_size = 0; } return 0; } static void netem_free_data(struct rtnl_tc *tc, void *data) { struct rtnl_netem *netem = data; if (!netem) return; free(netem->qnm_dist.dist_data); } static void netem_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_netem *netem = data; if (netem) { if (netem->qnm_mask & SCH_NETEM_ATTR_LIMIT && netem->qnm_limit > 0) nl_dump(p, " limit %dpkts", netem->qnm_limit); else nl_dump(p, " no limit"); } } static void netem_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_netem *netem = data; char buf[32]; if (netem) { if (netem->qnm_mask & SCH_NETEM_ATTR_LATENCY && netem->qnm_latency > 0) { nl_msec2str(nl_ticks2us(netem->qnm_latency) / 1000, buf, sizeof(buf)); nl_dump(p, " latency %s", buf); if (netem->qnm_mask & SCH_NETEM_ATTR_JITTER && netem->qnm_jitter > 0) { nl_msec2str(nl_ticks2us(netem->qnm_jitter) / 1000, buf, sizeof(buf)); nl_dump(p, " jitter %s", buf); if (netem->qnm_mask & SCH_NETEM_ATTR_DELAY_CORR && netem->qnm_corr.nmc_delay > 0) nl_dump(p, " %d%", netem->qnm_corr.nmc_delay); } } if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS && netem->qnm_loss > 0) { nl_dump(p, " loss %d%", netem->qnm_loss); if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS_CORR && netem->qnm_corr.nmc_loss > 0) nl_dump(p, " %d%", netem->qnm_corr.nmc_loss); } if (netem->qnm_mask & SCH_NETEM_ATTR_DUPLICATE && netem->qnm_duplicate > 0) { nl_dump(p, " duplicate %d%", netem->qnm_duplicate); if (netem->qnm_mask & SCH_NETEM_ATTR_DUP_CORR && netem->qnm_corr.nmc_duplicate > 0) nl_dump(p, " %d%", netem->qnm_corr.nmc_duplicate); } if (netem->qnm_mask & SCH_NETEM_ATTR_RO_PROB && netem->qnm_ro.nmro_probability > 0) { nl_dump(p, " reorder %d%", netem->qnm_ro.nmro_probability); if (netem->qnm_mask & SCH_NETEM_ATTR_RO_CORR && netem->qnm_ro.nmro_correlation > 0) nl_dump(p, " %d%", netem->qnm_ro.nmro_correlation); if (netem->qnm_mask & SCH_NETEM_ATTR_GAP && netem->qnm_gap > 0) nl_dump(p, " gap %d", netem->qnm_gap); } if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_PROB && netem->qnm_crpt.nmcr_probability > 0) { nl_dump(p, " reorder %d%", netem->qnm_crpt.nmcr_probability); if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_CORR && netem->qnm_crpt.nmcr_correlation > 0) nl_dump(p, " %d%", netem->qnm_crpt.nmcr_correlation); } } } static int netem_msg_fill_raw(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { int err = 0; struct tc_netem_qopt opts; struct tc_netem_corr cor; struct tc_netem_reorder reorder; struct tc_netem_corrupt corrupt; struct rtnl_netem *netem = data; unsigned char set_correlation = 0, set_reorder = 0, set_corrupt = 0, set_dist = 0; if (!netem) BUG(); memset(&opts, 0, sizeof(opts)); memset(&cor, 0, sizeof(cor)); memset(&reorder, 0, sizeof(reorder)); memset(&corrupt, 0, sizeof(corrupt)); msg->nm_nlh->nlmsg_flags |= NLM_F_REQUEST; if ( netem->qnm_ro.nmro_probability != 0 ) { if (netem->qnm_latency == 0) { return -NLE_MISSING_ATTR; } if (netem->qnm_gap == 0) netem->qnm_gap = 1; } else if ( netem->qnm_gap ) { return -NLE_MISSING_ATTR; } if ( netem->qnm_corr.nmc_delay != 0 ) { if ( netem->qnm_latency == 0 || netem->qnm_jitter == 0) { return -NLE_MISSING_ATTR; } set_correlation = 1; } if ( netem->qnm_corr.nmc_loss != 0 ) { if ( netem->qnm_loss == 0 ) { return -NLE_MISSING_ATTR; } set_correlation = 1; } if ( netem->qnm_corr.nmc_duplicate != 0 ) { if ( netem->qnm_duplicate == 0 ) { return -NLE_MISSING_ATTR; } set_correlation = 1; } if ( netem->qnm_ro.nmro_probability != 0 ) set_reorder = 1; else if ( netem->qnm_ro.nmro_correlation != 0 ) { return -NLE_MISSING_ATTR; } if ( netem->qnm_crpt.nmcr_probability != 0 ) set_corrupt = 1; else if ( netem->qnm_crpt.nmcr_correlation != 0 ) { return -NLE_MISSING_ATTR; } if ( netem->qnm_dist.dist_data && netem->qnm_dist.dist_size ) { if (netem->qnm_latency == 0 || netem->qnm_jitter == 0) { return -NLE_MISSING_ATTR; } else { /* Resize to accomodate the large distribution table */ int new_msg_len = msg->nm_size + netem->qnm_dist.dist_size * sizeof(netem->qnm_dist.dist_data[0]); msg->nm_nlh = (struct nlmsghdr *) realloc(msg->nm_nlh, new_msg_len); if ( msg->nm_nlh == NULL ) return -NLE_NOMEM; msg->nm_size = new_msg_len; set_dist = 1; } } opts.latency = netem->qnm_latency; opts.limit = netem->qnm_limit ? netem->qnm_limit : 1000; opts.loss = netem->qnm_loss; opts.gap = netem->qnm_gap; opts.duplicate = netem->qnm_duplicate; opts.jitter = netem->qnm_jitter; NLA_PUT(msg, TCA_OPTIONS, sizeof(opts), &opts); if ( set_correlation ) { cor.delay_corr = netem->qnm_corr.nmc_delay; cor.loss_corr = netem->qnm_corr.nmc_loss; cor.dup_corr = netem->qnm_corr.nmc_duplicate; NLA_PUT(msg, TCA_NETEM_CORR, sizeof(cor), &cor); } if ( set_reorder ) { reorder.probability = netem->qnm_ro.nmro_probability; reorder.correlation = netem->qnm_ro.nmro_correlation; NLA_PUT(msg, TCA_NETEM_REORDER, sizeof(reorder), &reorder); } if ( set_corrupt ) { corrupt.probability = netem->qnm_crpt.nmcr_probability; corrupt.correlation = netem->qnm_crpt.nmcr_correlation; NLA_PUT(msg, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt); } if ( set_dist ) { NLA_PUT(msg, TCA_NETEM_DELAY_DIST, netem->qnm_dist.dist_size * sizeof(netem->qnm_dist.dist_data[0]), netem->qnm_dist.dist_data); } /* Length specified in the TCA_OPTIONS section must span the entire * remainder of the message. That's just the way that sch_netem expects it. * Maybe there's a more succinct way to do this at a higher level. */ struct nlattr* head = (struct nlattr *)(NLMSG_DATA(msg->nm_nlh) + NLMSG_LENGTH(sizeof(struct tcmsg)) - NLMSG_ALIGNTO); struct nlattr* tail = (struct nlattr *)(((void *) (msg->nm_nlh)) + NLMSG_ALIGN(msg->nm_nlh->nlmsg_len)); int old_len = head->nla_len; head->nla_len = (void *)tail - (void *)head; msg->nm_nlh->nlmsg_len += (head->nla_len - old_len); return err; nla_put_failure: return -NLE_MSGSIZE; } /** * @name Queue Limit * @{ */ /** * Set limit of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg limit New limit in bytes. * @return 0 on success or a negative error code. */ void rtnl_netem_set_limit(struct rtnl_qdisc *qdisc, int limit) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_limit = limit; netem->qnm_mask |= SCH_NETEM_ATTR_LIMIT; } /** * Get limit of netem qdisc. * @arg qdisc Netem qdisc. * @return Limit in bytes or a negative error code. */ int rtnl_netem_get_limit(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (netem->qnm_mask & SCH_NETEM_ATTR_LIMIT) return netem->qnm_limit; else return -NLE_NOATTR; } /** @} */ /** * @name Packet Re-ordering * @{ */ /** * Set re-ordering gap of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg gap New gap in number of packets. * @return 0 on success or a negative error code. */ void rtnl_netem_set_gap(struct rtnl_qdisc *qdisc, int gap) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_gap = gap; netem->qnm_mask |= SCH_NETEM_ATTR_GAP; } /** * Get re-ordering gap of netem qdisc. * @arg qdisc Netem qdisc. * @return Re-ordering gap in packets or a negative error code. */ int rtnl_netem_get_gap(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (netem->qnm_mask & SCH_NETEM_ATTR_GAP) return netem->qnm_gap; else return -NLE_NOATTR; } /** * Set re-ordering probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New re-ordering probability. * @return 0 on success or a negative error code. */ void rtnl_netem_set_reorder_probability(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_ro.nmro_probability = prob; netem->qnm_mask |= SCH_NETEM_ATTR_RO_PROB; } /** * Get re-ordering probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Re-ordering probability or a negative error code. */ int rtnl_netem_get_reorder_probability(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (netem->qnm_mask & SCH_NETEM_ATTR_RO_PROB) return netem->qnm_ro.nmro_probability; else return -NLE_NOATTR; } /** * Set re-order correlation probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New re-ordering correlation probability. * @return 0 on success or a negative error code. */ void rtnl_netem_set_reorder_correlation(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_ro.nmro_correlation = prob; netem->qnm_mask |= SCH_NETEM_ATTR_RO_CORR; } /** * Get re-ordering correlation probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Re-ordering correlation probability or a negative error code. */ int rtnl_netem_get_reorder_correlation(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (netem->qnm_mask & SCH_NETEM_ATTR_RO_CORR) return netem->qnm_ro.nmro_correlation; else return -NLE_NOATTR; } /** @} */ /** * @name Corruption * @{ */ /** * Set corruption probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New corruption probability. * @return 0 on success or a negative error code. */ void rtnl_netem_set_corruption_probability(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_crpt.nmcr_probability = prob; netem->qnm_mask |= SCH_NETEM_ATTR_CORRUPT_PROB; } /** * Get corruption probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Corruption probability or a negative error code. */ int rtnl_netem_get_corruption_probability(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_PROB) return netem->qnm_crpt.nmcr_probability; else return -NLE_NOATTR; } /** * Set corruption correlation probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New corruption correlation probability. * @return 0 on success or a negative error code. */ void rtnl_netem_set_corruption_correlation(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_crpt.nmcr_correlation = prob; netem->qnm_mask |= SCH_NETEM_ATTR_CORRUPT_CORR; } /** * Get corruption correlation probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Corruption correlation probability or a negative error code. */ int rtnl_netem_get_corruption_correlation(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_CORR) return netem->qnm_crpt.nmcr_correlation; else return -NLE_NOATTR; } /** @} */ /** * @name Packet Loss * @{ */ /** * Set packet loss probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New packet loss probability. * @return 0 on success or a negative error code. */ void rtnl_netem_set_loss(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_loss = prob; netem->qnm_mask |= SCH_NETEM_ATTR_LOSS; } /** * Get packet loss probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Packet loss probability or a negative error code. */ int rtnl_netem_get_loss(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS) return netem->qnm_loss; else return -NLE_NOATTR; } /** * Set packet loss correlation probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New packet loss correlation. * @return 0 on success or a negative error code. */ void rtnl_netem_set_loss_correlation(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_corr.nmc_loss = prob; netem->qnm_mask |= SCH_NETEM_ATTR_LOSS_CORR; } /** * Get packet loss correlation probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Packet loss correlation probability or a negative error code. */ int rtnl_netem_get_loss_correlation(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS_CORR) return netem->qnm_corr.nmc_loss; else return -NLE_NOATTR; } /** @} */ /** * @name Packet Duplication * @{ */ /** * Set packet duplication probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New packet duplication probability. * @return 0 on success or a negative error code. */ void rtnl_netem_set_duplicate(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_duplicate = prob; netem->qnm_mask |= SCH_NETEM_ATTR_DUPLICATE; } /** * Get packet duplication probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Packet duplication probability or a negative error code. */ int rtnl_netem_get_duplicate(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_DUPLICATE) return netem->qnm_duplicate; else return -NLE_NOATTR; } /** * Set packet duplication correlation probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New packet duplication correlation probability. * @return 0 on sucess or a negative error code. */ void rtnl_netem_set_duplicate_correlation(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_corr.nmc_duplicate = prob; netem->qnm_mask |= SCH_NETEM_ATTR_DUP_CORR; } /** * Get packet duplication correlation probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Packet duplication correlation probability or a negative error code. */ int rtnl_netem_get_duplicate_correlation(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_DUP_CORR) return netem->qnm_corr.nmc_duplicate; else return -NLE_NOATTR; } /** @} */ /** * @name Packet Delay * @{ */ /** * Set packet delay of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg delay New packet delay in micro seconds. * @return 0 on success or a negative error code. */ void rtnl_netem_set_delay(struct rtnl_qdisc *qdisc, int delay) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_latency = nl_us2ticks(delay); netem->qnm_mask |= SCH_NETEM_ATTR_LATENCY; } /** * Get packet delay of netem qdisc. * @arg qdisc Netem qdisc. * @return Packet delay in micro seconds or a negative error code. */ int rtnl_netem_get_delay(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_LATENCY) return nl_ticks2us(netem->qnm_latency); else return -NLE_NOATTR; } /** * Set packet delay jitter of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg jitter New packet delay jitter in micro seconds. * @return 0 on success or a negative error code. */ void rtnl_netem_set_jitter(struct rtnl_qdisc *qdisc, int jitter) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_jitter = nl_us2ticks(jitter); netem->qnm_mask |= SCH_NETEM_ATTR_JITTER; } /** * Get packet delay jitter of netem qdisc. * @arg qdisc Netem qdisc. * @return Packet delay jitter in micro seconds or a negative error code. */ int rtnl_netem_get_jitter(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_JITTER) return nl_ticks2us(netem->qnm_jitter); else return -NLE_NOATTR; } /** * Set packet delay correlation probability of netem qdisc. * @arg qdisc Netem qdisc to be modified. * @arg prob New packet delay correlation probability. */ void rtnl_netem_set_delay_correlation(struct rtnl_qdisc *qdisc, int prob) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); netem->qnm_corr.nmc_delay = prob; netem->qnm_mask |= SCH_NETEM_ATTR_DELAY_CORR; } /** * Get packet delay correlation probability of netem qdisc. * @arg qdisc Netem qdisc. * @return Packet delay correlation probability or a negative error code. */ int rtnl_netem_get_delay_correlation(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_DELAY_CORR) return netem->qnm_corr.nmc_delay; else return -NLE_NOATTR; } /** * Get the size of the distribution table. * @arg qdisc Netem qdisc. * @return Distribution table size or a negative error code. */ int rtnl_netem_get_delay_distribution_size(struct rtnl_qdisc *qdisc) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_DIST) return netem->qnm_dist.dist_size; else return -NLE_NOATTR; } /** * Get a pointer to the distribution table. * @arg qdisc Netem qdisc. * @arg dist_ptr The pointer to set. * @return Negative error code on failure or 0 on success. */ int rtnl_netem_get_delay_distribution(struct rtnl_qdisc *qdisc, int16_t **dist_ptr) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); if (netem->qnm_mask & SCH_NETEM_ATTR_DIST) { *dist_ptr = netem->qnm_dist.dist_data; return 0; } else return -NLE_NOATTR; } /** * Set the delay distribution. Latency/jitter must be set before applying. * @arg qdisc Netem qdisc. * @arg dist_type The name of the distribution (type, file, path/file). * @return 0 on success, error code on failure. */ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist_type) { struct rtnl_netem *netem; if (!(netem = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); FILE *f; int n = 0; size_t i; size_t len = 2048; char *line; char name[NAME_MAX]; char dist_suffix[] = ".dist"; /* If the given filename already ends in .dist, don't append it later */ char *test_suffix = strstr(dist_type, dist_suffix); if (test_suffix != NULL && strlen(test_suffix) == 5) strcpy(dist_suffix, ""); /* Check several locations for the dist file */ char *test_path[] = { "", "./", "/usr/lib/tc/", "/usr/local/lib/tc/" }; for (i = 0; i < ARRAY_SIZE(test_path); i++) { snprintf(name, NAME_MAX, "%s%s%s", test_path[i], dist_type, dist_suffix); if ((f = fopen(name, "r"))) break; } if ( f == NULL ) return -nl_syserr2nlerr(errno); netem->qnm_dist.dist_data = (int16_t *) calloc (MAXDIST, sizeof(int16_t)); line = (char *) calloc (sizeof(char), len + 1); while (getline(&line, &len, f) != -1) { char *p, *endp; if (*line == '\n' || *line == '#') continue; for (p = line; ; p = endp) { long x = strtol(p, &endp, 0); if (endp == p) break; if (n >= MAXDIST) { free(line); fclose(f); return -NLE_INVAL; } netem->qnm_dist.dist_data[n++] = x; } } free(line); netem->qnm_dist.dist_size = n; netem->qnm_mask |= SCH_NETEM_ATTR_DIST; fclose(f); return 0; } /** @} */ static struct rtnl_tc_ops netem_ops = { .to_kind = "netem", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_netem), .to_msg_parser = netem_msg_parser, .to_free_data = netem_free_data, .to_dump[NL_DUMP_LINE] = netem_dump_line, .to_dump[NL_DUMP_DETAILS] = netem_dump_details, .to_msg_fill_raw = netem_msg_fill_raw, }; static void __init netem_init(void) { rtnl_tc_register(&netem_ops); } static void __exit netem_exit(void) { rtnl_tc_unregister(&netem_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc/dsmark.c0000644000175000017500000002303713023014600014256 00000000000000/* * lib/route/qdisc/dsmark.c DSMARK * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup qdisc * @ingroup class * @defgroup qdisc_dsmark Differentiated Services Marker (DSMARK) * @{ */ #include #include #include #include #include #include #include #include /** @cond SKIP */ #define SCH_DSMARK_ATTR_INDICES 0x1 #define SCH_DSMARK_ATTR_DEFAULT_INDEX 0x2 #define SCH_DSMARK_ATTR_SET_TC_INDEX 0x4 #define SCH_DSMARK_ATTR_MASK 0x1 #define SCH_DSMARK_ATTR_VALUE 0x2 /** @endcond */ static struct nla_policy dsmark_policy[TCA_DSMARK_MAX+1] = { [TCA_DSMARK_INDICES] = { .type = NLA_U16 }, [TCA_DSMARK_DEFAULT_INDEX] = { .type = NLA_U16 }, [TCA_DSMARK_SET_TC_INDEX] = { .type = NLA_FLAG }, [TCA_DSMARK_VALUE] = { .type = NLA_U8 }, [TCA_DSMARK_MASK] = { .type = NLA_U8 }, }; static int dsmark_qdisc_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_dsmark_qdisc *dsmark = data; struct nlattr *tb[TCA_DSMARK_MAX + 1]; int err; err = tca_parse(tb, TCA_DSMARK_MAX, tc, dsmark_policy); if (err < 0) return err; if (tb[TCA_DSMARK_INDICES]) { dsmark->qdm_indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); dsmark->qdm_mask |= SCH_DSMARK_ATTR_INDICES; } if (tb[TCA_DSMARK_DEFAULT_INDEX]) { dsmark->qdm_default_index = nla_get_u16(tb[TCA_DSMARK_DEFAULT_INDEX]); dsmark->qdm_mask |= SCH_DSMARK_ATTR_DEFAULT_INDEX; } if (tb[TCA_DSMARK_SET_TC_INDEX]) { dsmark->qdm_set_tc_index = 1; dsmark->qdm_mask |= SCH_DSMARK_ATTR_SET_TC_INDEX; } return 0; } static int dsmark_class_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_dsmark_class *dsmark = data; struct nlattr *tb[TCA_DSMARK_MAX + 1]; int err; err = tca_parse(tb, TCA_DSMARK_MAX, tc, dsmark_policy); if (err < 0) return err; if (tb[TCA_DSMARK_MASK]) { dsmark->cdm_bmask = nla_get_u8(tb[TCA_DSMARK_MASK]); dsmark->cdm_mask |= SCH_DSMARK_ATTR_MASK; } if (tb[TCA_DSMARK_VALUE]) { dsmark->cdm_value = nla_get_u8(tb[TCA_DSMARK_VALUE]); dsmark->cdm_mask |= SCH_DSMARK_ATTR_VALUE; } return 0; } static void dsmark_qdisc_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_dsmark_qdisc *dsmark = data; if (dsmark && (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES)) nl_dump(p, " indices 0x%04x", dsmark->qdm_indices); } static void dsmark_qdisc_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_dsmark_qdisc *dsmark = data; if (!dsmark) return; if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX) nl_dump(p, " default index 0x%04x", dsmark->qdm_default_index); if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX) nl_dump(p, " set-tc-index"); } static void dsmark_class_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_dsmark_class *dsmark = data; if (!dsmark) return; if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE) nl_dump(p, " value 0x%02x", dsmark->cdm_value); if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK) nl_dump(p, " mask 0x%02x", dsmark->cdm_bmask); } static int dsmark_qdisc_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_dsmark_qdisc *dsmark = data; if (!dsmark) return 0; if (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES) NLA_PUT_U16(msg, TCA_DSMARK_INDICES, dsmark->qdm_indices); if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX) NLA_PUT_U16(msg, TCA_DSMARK_DEFAULT_INDEX, dsmark->qdm_default_index); if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX) NLA_PUT_FLAG(msg, TCA_DSMARK_SET_TC_INDEX); return 0; nla_put_failure: return -NLE_MSGSIZE; } static int dsmark_class_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_dsmark_class *dsmark = data; if (!dsmark) return 0; if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK) NLA_PUT_U8(msg, TCA_DSMARK_MASK, dsmark->cdm_bmask); if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE) NLA_PUT_U8(msg, TCA_DSMARK_VALUE, dsmark->cdm_value); return 0; nla_put_failure: return -NLE_MSGSIZE; } /** * @name Class Attribute Access * @{ */ /** * Set bitmask of DSMARK class. * @arg class DSMARK class to be modified. * @arg mask New bitmask. * @return 0 on success or a negative error code. */ int rtnl_class_dsmark_set_bitmask(struct rtnl_class *class, uint8_t mask) { struct rtnl_dsmark_class *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) return -NLE_NOMEM; dsmark->cdm_bmask = mask; dsmark->cdm_mask |= SCH_DSMARK_ATTR_MASK; return 0; } /** * Get bitmask of DSMARK class. * @arg class DSMARK class. * @return Bitmask or a negative error code. */ int rtnl_class_dsmark_get_bitmask(struct rtnl_class *class) { struct rtnl_dsmark_class *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) return -NLE_NOMEM; if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK) return dsmark->cdm_bmask; else return -NLE_NOATTR; } /** * Set value of DSMARK class. * @arg class DSMARK class to be modified. * @arg value New value. * @return 0 on success or a negative errror code. */ int rtnl_class_dsmark_set_value(struct rtnl_class *class, uint8_t value) { struct rtnl_dsmark_class *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) return -NLE_NOMEM; dsmark->cdm_value = value; dsmark->cdm_mask |= SCH_DSMARK_ATTR_VALUE; return 0; } /** * Get value of DSMARK class. * @arg class DSMARK class. * @return Value or a negative error code. */ int rtnl_class_dsmark_get_value(struct rtnl_class *class) { struct rtnl_dsmark_class *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) return -NLE_NOMEM; if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE) return dsmark->cdm_value; else return -NLE_NOATTR; } /** @} */ /** * @name Qdisc Attribute Access * @{ */ /** * Set indices of DSMARK qdisc. * @arg qdisc DSMARK qdisc to be modified. * @arg indices New indices. */ int rtnl_qdisc_dsmark_set_indices(struct rtnl_qdisc *qdisc, uint16_t indices) { struct rtnl_dsmark_qdisc *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; dsmark->qdm_indices = indices; dsmark->qdm_mask |= SCH_DSMARK_ATTR_INDICES; return 0; } /** * Get indices of DSMARK qdisc. * @arg qdisc DSMARK qdisc. * @return Indices or a negative error code. */ int rtnl_qdisc_dsmark_get_indices(struct rtnl_qdisc *qdisc) { struct rtnl_dsmark_qdisc *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES) return dsmark->qdm_indices; else return -NLE_NOATTR; } /** * Set default index of DSMARK qdisc. * @arg qdisc DSMARK qdisc to be modified. * @arg default_index New default index. * @return 0 on success or a negative error code. */ int rtnl_qdisc_dsmark_set_default_index(struct rtnl_qdisc *qdisc, uint16_t default_index) { struct rtnl_dsmark_qdisc *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; dsmark->qdm_default_index = default_index; dsmark->qdm_mask |= SCH_DSMARK_ATTR_DEFAULT_INDEX; return 0; } /** * Get default index of DSMARK qdisc. * @arg qdisc DSMARK qdisc. * @return Default index or a negative error code. */ int rtnl_qdisc_dsmark_get_default_index(struct rtnl_qdisc *qdisc) { struct rtnl_dsmark_qdisc *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX) return dsmark->qdm_default_index; else return -NLE_NOATTR; } /** * Set set-tc-index flag of DSMARK qdisc. * @arg qdisc DSMARK qdisc to be modified. * @arg flag Flag indicating whether to enable or disable. * @return 0 on success or a negative error code. */ int rtnl_qdisc_dsmark_set_set_tc_index(struct rtnl_qdisc *qdisc, int flag) { struct rtnl_dsmark_qdisc *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; dsmark->qdm_set_tc_index = !!flag; dsmark->qdm_mask |= SCH_DSMARK_ATTR_SET_TC_INDEX; return 0; } /** * Get set-tc-index flag of DSMARK qdisc. * @arg qdisc DSMARK qdisc to be modified. * @return 1 or 0 to indicate wehther the flag is enabled or a negative * error code. */ int rtnl_qdisc_dsmark_get_set_tc_index(struct rtnl_qdisc *qdisc) { struct rtnl_dsmark_qdisc *dsmark; if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) return -NLE_NOMEM; if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX) return dsmark->qdm_set_tc_index; else return -NLE_NOATTR; } /** @} */ static struct rtnl_tc_ops dsmark_qdisc_ops = { .to_kind = "dsmark", .to_type = RTNL_TC_TYPE_QDISC, .to_size = sizeof(struct rtnl_dsmark_qdisc), .to_msg_parser = dsmark_qdisc_msg_parser, .to_dump = { [NL_DUMP_LINE] = dsmark_qdisc_dump_line, [NL_DUMP_DETAILS] = dsmark_qdisc_dump_details, }, .to_msg_fill = dsmark_qdisc_msg_fill, }; static struct rtnl_tc_ops dsmark_class_ops = { .to_kind = "dsmark", .to_type = RTNL_TC_TYPE_CLASS, .to_size = sizeof(struct rtnl_dsmark_class), .to_msg_parser = dsmark_class_msg_parser, .to_dump[NL_DUMP_LINE] = dsmark_class_dump_line, .to_msg_fill = dsmark_class_msg_fill, }; static void __init dsmark_init(void) { rtnl_tc_register(&dsmark_qdisc_ops); rtnl_tc_register(&dsmark_class_ops); } static void __exit dsmark_exit(void) { rtnl_tc_unregister(&dsmark_qdisc_ops); rtnl_tc_unregister(&dsmark_class_ops); } /** @} */ libnl-3.2.29/lib/route/class.c0000644000175000017500000003035513023014600013000 00000000000000/* * lib/route/class.c Traffic Classes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2013 Thomas Graf */ /** * @ingroup tc * @defgroup class Traffic Classes * @{ */ #include #include #include #include #include #include #include #include static struct nl_cache_ops rtnl_class_ops; static struct nl_object_ops class_obj_ops; static void class_dump_details(struct rtnl_tc *tc, struct nl_dump_params *p) { struct rtnl_class *class = (struct rtnl_class *) tc; char buf[32]; if (class->c_info) nl_dump(p, "child-qdisc %s ", rtnl_tc_handle2str(class->c_info, buf, sizeof(buf))); } static int class_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct rtnl_class *class; int err; if (!(class = rtnl_class_alloc())) return -NLE_NOMEM; if ((err = rtnl_tc_msg_parse(nlh, TC_CAST(class))) < 0) goto errout; err = pp->pp_cb(OBJ_CAST(class), pp); errout: rtnl_class_put(class); return err; } static int class_request_update(struct nl_cache *cache, struct nl_sock *sk) { struct tcmsg tchdr = { .tcm_family = AF_UNSPEC, .tcm_ifindex = cache->c_iarg1, }; return nl_send_simple(sk, RTM_GETTCLASS, NLM_F_DUMP, &tchdr, sizeof(tchdr)); } /** * @name Allocation/Freeing * @{ */ struct rtnl_class *rtnl_class_alloc(void) { struct rtnl_tc *tc; tc = TC_CAST(nl_object_alloc(&class_obj_ops)); if (tc) tc->tc_type = RTNL_TC_TYPE_CLASS; return (struct rtnl_class *) tc; } void rtnl_class_put(struct rtnl_class *class) { nl_object_put((struct nl_object *) class); } /** @} */ /** * @name Addition/Modification/Deletion * @{ */ static int class_build(struct rtnl_class *class, int type, int flags, struct nl_msg **result) { uint32_t needed = TCA_ATTR_PARENT | TCA_ATTR_HANDLE; if ((class->ce_mask & needed) == needed && TC_H_MAJ(class->c_parent) && TC_H_MAJ(class->c_handle) && TC_H_MAJ(class->c_parent) != TC_H_MAJ(class->c_handle)) { APPBUG("TC_H_MAJ(parent) must match TC_H_MAJ(handle)"); return -NLE_INVAL; } return rtnl_tc_msg_build(TC_CAST(class), type, flags, result); } /** * Build a netlink message requesting the addition of a traffic class * @arg class Traffic class to add * @arg flags Additional netlink message flags * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_class_add() with * the exception that it will not send the message but return it int the * provided return pointer instead. * * @see rtnl_class_add() * * @return 0 on success or a negative error code. */ int rtnl_class_build_add_request(struct rtnl_class *class, int flags, struct nl_msg **result) { return class_build(class, RTM_NEWTCLASS, flags, result); } /** * Add/Update traffic class * @arg sk Netlink socket * @arg class Traffic class to add * @arg flags Additional netlink message flags * * Builds a \c RTM_NEWTCLASS netlink message requesting the addition * of a new traffic class and sends the message to the kernel. The * configuration of the traffic class is derived from the attributes * of the specified traffic class. * * The following flags may be specified: * - \c NLM_F_CREATE: Create traffic class if it does not exist, * otherwise -NLE_OBJ_NOTFOUND is returned. * - \c NLM_F_EXCL: Return -NLE_EXISTS if a traffic class with * matching handle exists already. * * Existing traffic classes with matching handles will be updated, * unless the flag \c NLM_F_EXCL is specified. If no matching traffic * class exists, it will be created if the flag \c NLM_F_CREATE is set, * otherwise the error -NLE_OBJ_NOTFOUND is returned. * * If the parent qdisc does not support classes, the error * \c NLE_OPNOTSUPP is returned. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_class_add(struct nl_sock *sk, struct rtnl_class *class, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_class_build_add_request(class, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** * Build netlink message requesting the deletion of a traffic class * @arg class Traffic class to delete * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_class_delete() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_class_delete() * * @return 0 on success or a negative error code. */ int rtnl_class_build_delete_request(struct rtnl_class *class, struct nl_msg **result) { struct nl_msg *msg; struct tcmsg tchdr; uint32_t required = TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE; if ((class->ce_mask & required) != required) { APPBUG("ifindex and handle must be specified"); return -NLE_MISSING_ATTR; } if (!(msg = nlmsg_alloc_simple(RTM_DELTCLASS, 0))) return -NLE_NOMEM; memset(&tchdr, 0, sizeof(tchdr)); tchdr.tcm_family = AF_UNSPEC; tchdr.tcm_ifindex = class->c_ifindex; tchdr.tcm_handle = class->c_handle; if (class->ce_mask & TCA_ATTR_PARENT) tchdr.tcm_parent = class->c_parent; if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0) { nlmsg_free(msg); return -NLE_MSGSIZE; } *result = msg; return 0; } /** * Delete traffic class * @arg sk Netlink socket * @arg class Traffic class to delete * * Builds a \c RTM_DELTCLASS netlink message requesting the deletion * of a traffic class and sends the message to the kernel. * * The message is constructed out of the following attributes: * - \c ifindex and \c handle (required) * - \c parent (optional, must match if provided) * * All other class attributes including all class type specific * attributes are ignored. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_class_delete(struct nl_sock *sk, struct rtnl_class *class) { struct nl_msg *msg; int err; if ((err = rtnl_class_build_delete_request(class, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** @} */ /** * @name Leaf Qdisc * @{ */ /** * Lookup the leaf qdisc of a traffic class * @arg class the parent traffic class * @arg cache a qdisc cache allocated using rtnl_qdisc_alloc_cache() * * @return Matching Qdisc or NULL if the traffic class has no leaf qdisc */ struct rtnl_qdisc *rtnl_class_leaf_qdisc(struct rtnl_class *class, struct nl_cache *cache) { struct rtnl_qdisc *leaf; if (!class->c_info) return NULL; leaf = rtnl_qdisc_get_by_parent(cache, class->c_ifindex, class->c_handle); if (!leaf || leaf->q_handle != class->c_info) return NULL; return leaf; } /** @} */ /** * @name Cache Related Functions * @{ */ /** * Allocate a cache and fill it with all configured traffic classes * @arg sk Netlink socket * @arg ifindex Interface index of the network device * @arg result Pointer to store the created cache * * Allocates a new traffic class cache and fills it with a list of all * configured traffic classes on a specific network device. Release the * cache with nl_cache_free(). * * @return 0 on success or a negative error code. */ int rtnl_class_alloc_cache(struct nl_sock *sk, int ifindex, struct nl_cache **result) { struct nl_cache * cache; int err; if (!ifindex) { APPBUG("ifindex must be specified"); return -NLE_INVAL; } if (!(cache = nl_cache_alloc(&rtnl_class_ops))) return -NLE_NOMEM; cache->c_iarg1 = ifindex; if (sk && (err = nl_cache_refill(sk, cache)) < 0) { nl_cache_free(cache); return err; } *result = cache; return 0; } /** * Search traffic class by interface index and handle * @arg cache Traffic class cache * @arg ifindex Interface index * @arg handle ID of traffic class * * Searches a traffic class cache previously allocated with * rtnl_class_alloc_cache() and searches for a traffi class matching * the interface index and handle. * * The reference counter is incremented before returning the traffic * class, therefore the reference must be given back with rtnl_class_put() * after usage. * * @return Traffic class or NULL if no match was found. */ struct rtnl_class *rtnl_class_get(struct nl_cache *cache, int ifindex, uint32_t handle) { struct rtnl_class *class; if (cache->c_ops != &rtnl_class_ops) return NULL; nl_list_for_each_entry(class, &cache->c_items, ce_list) { if (class->c_handle == handle && class->c_ifindex == ifindex) { nl_object_get((struct nl_object *) class); return class; } } return NULL; } /** @} */ /** * @name Deprecated Functions * @{ */ /** * Call a callback for each child of a class * * @deprecated Use of this function is deprecated, it does not allow * to handle the out of memory situation that can occur. */ void rtnl_class_foreach_child(struct rtnl_class *class, struct nl_cache *cache, void (*cb)(struct nl_object *, void *), void *arg) { struct rtnl_class *filter; filter = rtnl_class_alloc(); if (!filter) return; rtnl_tc_set_parent(TC_CAST(filter), class->c_handle); rtnl_tc_set_ifindex(TC_CAST(filter), class->c_ifindex); rtnl_tc_set_kind(TC_CAST(filter), class->c_kind); nl_cache_foreach_filter(cache, OBJ_CAST(filter), cb, arg); rtnl_class_put(filter); } /** * Call a callback for each classifier attached to the class * * @deprecated Use of this function is deprecated, it does not allow * to handle the out of memory situation that can occur. */ void rtnl_class_foreach_cls(struct rtnl_class *class, struct nl_cache *cache, void (*cb)(struct nl_object *, void *), void *arg) { struct rtnl_cls *filter; filter = rtnl_cls_alloc(); if (!filter) return; rtnl_tc_set_ifindex((struct rtnl_tc *) filter, class->c_ifindex); rtnl_tc_set_parent((struct rtnl_tc *) filter, class->c_parent); nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg); rtnl_cls_put(filter); } /** @} */ static struct rtnl_tc_type_ops class_ops = { .tt_type = RTNL_TC_TYPE_CLASS, .tt_dump_prefix = "class", .tt_dump = { [NL_DUMP_DETAILS] = class_dump_details, }, }; static struct nl_object_ops class_obj_ops = { .oo_name = "route/class", .oo_size = sizeof(struct rtnl_class), .oo_free_data = rtnl_tc_free_data, .oo_clone = rtnl_tc_clone, .oo_dump = { [NL_DUMP_LINE] = rtnl_tc_dump_line, [NL_DUMP_DETAILS] = rtnl_tc_dump_details, [NL_DUMP_STATS] = rtnl_tc_dump_stats, }, .oo_compare = rtnl_tc_compare, .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), }; static struct nl_cache_ops rtnl_class_ops = { .co_name = "route/class", .co_hdrsize = sizeof(struct tcmsg), .co_msgtypes = { { RTM_NEWTCLASS, NL_ACT_NEW, "new" }, { RTM_DELTCLASS, NL_ACT_DEL, "del" }, { RTM_GETTCLASS, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_groups = tc_groups, .co_request_update = &class_request_update, .co_msg_parser = &class_msg_parser, .co_obj_ops = &class_obj_ops, }; static void __init class_init(void) { rtnl_tc_type_register(&class_ops); nl_cache_mngt_register(&rtnl_class_ops); } static void __exit class_exit(void) { nl_cache_mngt_unregister(&rtnl_class_ops); rtnl_tc_type_unregister(&class_ops); } /** @} */ libnl-3.2.29/lib/route/tc.c0000644000175000017500000006605613023014600012310 00000000000000/* * lib/route/tc.c Traffic Control * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup rtnl * @defgroup tc Traffic Control * @{ */ #include #include #include #include #include #include #include #include /** @cond SKIP */ static struct nl_list_head tc_ops_list[__RTNL_TC_TYPE_MAX]; static struct rtnl_tc_type_ops *tc_type_ops[__RTNL_TC_TYPE_MAX]; static struct nla_policy tc_policy[TCA_MAX+1] = { [TCA_KIND] = { .type = NLA_STRING, .maxlen = TCKINDSIZ }, [TCA_STATS] = { .minlen = sizeof(struct tc_stats) }, [TCA_STATS2] = { .type = NLA_NESTED }, }; int tca_parse(struct nlattr **tb, int maxattr, struct rtnl_tc *g, struct nla_policy *policy) { if (g->ce_mask & TCA_ATTR_OPTS) return nla_parse(tb, maxattr, (struct nlattr *) g->tc_opts->d_data, g->tc_opts->d_size, policy); else { /* Ugly but tb[] must be in a defined state even if no * attributes can be found. */ memset(tb, 0, sizeof(struct nlattr *) * (maxattr + 1)); return 0; } } static struct nla_policy tc_stats2_policy[TCA_STATS_MAX+1] = { [TCA_STATS_BASIC] = { .minlen = sizeof(struct gnet_stats_basic) }, [TCA_STATS_RATE_EST] = { .minlen = sizeof(struct gnet_stats_rate_est) }, [TCA_STATS_QUEUE] = { .minlen = sizeof(struct gnet_stats_queue) }, }; int rtnl_tc_msg_parse(struct nlmsghdr *n, struct rtnl_tc *tc) { struct nl_cache *link_cache; struct rtnl_tc_ops *ops; struct nlattr *tb[TCA_MAX + 1]; char kind[TCKINDSIZ]; struct tcmsg *tm; int err; tc->ce_msgtype = n->nlmsg_type; err = nlmsg_parse(n, sizeof(*tm), tb, TCA_MAX, tc_policy); if (err < 0) return err; if (tb[TCA_KIND] == NULL) return -NLE_MISSING_ATTR; nla_strlcpy(kind, tb[TCA_KIND], sizeof(kind)); rtnl_tc_set_kind(tc, kind); tm = nlmsg_data(n); tc->tc_family = tm->tcm_family; tc->tc_ifindex = tm->tcm_ifindex; tc->tc_handle = tm->tcm_handle; tc->tc_parent = tm->tcm_parent; tc->tc_info = tm->tcm_info; tc->ce_mask |= (TCA_ATTR_FAMILY | TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE| TCA_ATTR_PARENT | TCA_ATTR_INFO); if (tb[TCA_OPTIONS]) { tc->tc_opts = nl_data_alloc_attr(tb[TCA_OPTIONS]); if (!tc->tc_opts) return -NLE_NOMEM; tc->ce_mask |= TCA_ATTR_OPTS; } if (tb[TCA_STATS2]) { struct nlattr *tbs[TCA_STATS_MAX + 1]; err = nla_parse_nested(tbs, TCA_STATS_MAX, tb[TCA_STATS2], tc_stats2_policy); if (err < 0) return err; if (tbs[TCA_STATS_BASIC]) { struct gnet_stats_basic *bs; bs = nla_data(tbs[TCA_STATS_BASIC]); tc->tc_stats[RTNL_TC_BYTES] = bs->bytes; tc->tc_stats[RTNL_TC_PACKETS] = bs->packets; } if (tbs[TCA_STATS_RATE_EST]) { struct gnet_stats_rate_est *re; re = nla_data(tbs[TCA_STATS_RATE_EST]); tc->tc_stats[RTNL_TC_RATE_BPS] = re->bps; tc->tc_stats[RTNL_TC_RATE_PPS] = re->pps; } if (tbs[TCA_STATS_QUEUE]) { struct gnet_stats_queue *q; q = nla_data(tbs[TCA_STATS_QUEUE]); tc->tc_stats[RTNL_TC_QLEN] = q->qlen; tc->tc_stats[RTNL_TC_BACKLOG] = q->backlog; tc->tc_stats[RTNL_TC_DROPS] = q->drops; tc->tc_stats[RTNL_TC_REQUEUES] = q->requeues; tc->tc_stats[RTNL_TC_OVERLIMITS] = q->overlimits; } tc->ce_mask |= TCA_ATTR_STATS; if (tbs[TCA_STATS_APP]) { tc->tc_xstats = nl_data_alloc_attr(tbs[TCA_STATS_APP]); if (tc->tc_xstats == NULL) return -NLE_NOMEM; tc->ce_mask |= TCA_ATTR_XSTATS; } else goto compat_xstats; } else { if (tb[TCA_STATS]) { struct tc_stats *st = nla_data(tb[TCA_STATS]); tc->tc_stats[RTNL_TC_BYTES] = st->bytes; tc->tc_stats[RTNL_TC_PACKETS] = st->packets; tc->tc_stats[RTNL_TC_RATE_BPS] = st->bps; tc->tc_stats[RTNL_TC_RATE_PPS] = st->pps; tc->tc_stats[RTNL_TC_QLEN] = st->qlen; tc->tc_stats[RTNL_TC_BACKLOG] = st->backlog; tc->tc_stats[RTNL_TC_DROPS] = st->drops; tc->tc_stats[RTNL_TC_OVERLIMITS]= st->overlimits; tc->ce_mask |= TCA_ATTR_STATS; } compat_xstats: if (tb[TCA_XSTATS]) { tc->tc_xstats = nl_data_alloc_attr(tb[TCA_XSTATS]); if (tc->tc_xstats == NULL) return -NLE_NOMEM; tc->ce_mask |= TCA_ATTR_XSTATS; } } ops = rtnl_tc_get_ops(tc); if (ops && ops->to_msg_parser) { void *data = rtnl_tc_data(tc); if (!data) return -NLE_NOMEM; err = ops->to_msg_parser(tc, data); if (err < 0) return err; } if ((link_cache = __nl_cache_mngt_require("route/link"))) { struct rtnl_link *link; if ((link = rtnl_link_get(link_cache, tc->tc_ifindex))) { rtnl_tc_set_link(tc, link); /* rtnl_tc_set_link incs refcnt */ rtnl_link_put(link); } } return 0; } int rtnl_tc_msg_build(struct rtnl_tc *tc, int type, int flags, struct nl_msg **result) { struct nl_msg *msg; struct rtnl_tc_ops *ops; struct tcmsg tchdr = { .tcm_family = AF_UNSPEC, .tcm_ifindex = tc->tc_ifindex, .tcm_handle = tc->tc_handle, .tcm_parent = tc->tc_parent, }; int err = -NLE_MSGSIZE; msg = nlmsg_alloc_simple(type, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (tc->ce_mask & TCA_ATTR_KIND) NLA_PUT_STRING(msg, TCA_KIND, tc->tc_kind); ops = rtnl_tc_get_ops(tc); if (ops && (ops->to_msg_fill || ops->to_msg_fill_raw)) { struct nlattr *opts; void *data = rtnl_tc_data(tc); if (ops->to_msg_fill) { if (!(opts = nla_nest_start(msg, TCA_OPTIONS))) goto nla_put_failure; if ((err = ops->to_msg_fill(tc, data, msg)) < 0) goto nla_put_failure; nla_nest_end(msg, opts); } else if ((err = ops->to_msg_fill_raw(tc, data, msg)) < 0) goto nla_put_failure; } *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return err; } void tca_set_kind(struct rtnl_tc *t, const char *kind) { strncpy(t->tc_kind, kind, sizeof(t->tc_kind) - 1); t->ce_mask |= TCA_ATTR_KIND; } /** @endcond */ /** * @name Attributes * @{ */ /** * Set interface index of traffic control object * @arg tc traffic control object * @arg ifindex interface index. * * Sets the interface index of a traffic control object. The interface * index defines the network device which this tc object is attached to. * This function will overwrite any network device assigned with previous * calls to rtnl_tc_set_ifindex() or rtnl_tc_set_link(). */ void rtnl_tc_set_ifindex(struct rtnl_tc *tc, int ifindex) { /* Obsolete possible old link reference */ rtnl_link_put(tc->tc_link); tc->tc_link = NULL; tc->ce_mask &= ~TCA_ATTR_LINK; tc->tc_ifindex = ifindex; tc->ce_mask |= TCA_ATTR_IFINDEX; } /** * Return interface index of traffic control object * @arg tc traffic control object */ int rtnl_tc_get_ifindex(struct rtnl_tc *tc) { return tc->tc_ifindex; } /** * Set link of traffic control object * @arg tc traffic control object * @arg link link object * * Sets the link of a traffic control object. This function serves * the same purpose as rtnl_tc_set_ifindex() but due to the continued * allowed access to the link object it gives it the possibility to * retrieve sane default values for the the MTU and the linktype. * Always prefer this function over rtnl_tc_set_ifindex() if you can * spare to have an additional link object around. */ void rtnl_tc_set_link(struct rtnl_tc *tc, struct rtnl_link *link) { rtnl_link_put(tc->tc_link); if (!link) return; if (!link->l_index) BUG(); nl_object_get(OBJ_CAST(link)); tc->tc_link = link; tc->tc_ifindex = link->l_index; tc->ce_mask |= TCA_ATTR_LINK | TCA_ATTR_IFINDEX; } /** * Get link of traffic control object * @arg tc traffic control object * * Returns the link of a traffic control object. The link is only * returned if it has been set before via rtnl_tc_set_link() or * if a link cache was available while parsing the tc object. This * function may still return NULL even if an ifindex is assigned to * the tc object. It will _not_ look up the link by itself. * * @note The returned link will have its reference counter incremented. * It is in the responsibility of the caller to return the * reference. * * @return link object or NULL if not set. */ struct rtnl_link *rtnl_tc_get_link(struct rtnl_tc *tc) { if (tc->tc_link) { nl_object_get(OBJ_CAST(tc->tc_link)); return tc->tc_link; } return NULL; } /** * Set the Maximum Transmission Unit (MTU) of traffic control object * @arg tc traffic control object * @arg mtu largest packet size expected * * Sets the MTU of a traffic control object. Not all traffic control * objects will make use of this but it helps while calculating rate * tables. This value is typically derived directly from the link * the tc object is attached to if the link has been assigned via * rtnl_tc_set_link(). It is usually not necessary to set the MTU * manually, this function is provided to allow overwriting the derived * value. */ void rtnl_tc_set_mtu(struct rtnl_tc *tc, uint32_t mtu) { tc->tc_mtu = mtu; tc->ce_mask |= TCA_ATTR_MTU; } /** * Return the MTU of traffic control object * @arg tc traffic control object * * Returns the MTU of a traffic control object which has been set via: * -# User specified value set via rtnl_tc_set_mtu() * -# Dervied from link set via rtnl_tc_set_link() * -# Fall back to default: ethernet = 1500 */ uint32_t rtnl_tc_get_mtu(struct rtnl_tc *tc) { if (tc->ce_mask & TCA_ATTR_MTU) return tc->tc_mtu; else if (tc->ce_mask & TCA_ATTR_LINK) return tc->tc_link->l_mtu; else return 1500; /* default to ethernet */ } /** * Set the Minimum Packet Unit (MPU) of a traffic control object * @arg tc traffic control object * @arg mpu minimum packet size expected * * Sets the MPU of a traffic contorl object. It specifies the minimum * packet size to ever hit this traffic control object. Not all traffic * control objects will make use of this but it helps while calculating * rate tables. */ void rtnl_tc_set_mpu(struct rtnl_tc *tc, uint32_t mpu) { tc->tc_mpu = mpu; tc->ce_mask |= TCA_ATTR_MPU; } /** * Return the Minimum Packet Unit (MPU) of a traffic control object * @arg tc traffic control object * * @return The MPU previously set via rtnl_tc_set_mpu() or 0. */ uint32_t rtnl_tc_get_mpu(struct rtnl_tc *tc) { return tc->tc_mpu; } /** * Set per packet overhead of a traffic control object * @arg tc traffic control object * @arg overhead overhead per packet in bytes * * Sets the per packet overhead in bytes occuring on the link not seen * by the kernel. This value can be used to correct size calculations * if the packet size on the wire does not match the packet sizes seen * in the network stack. Not all traffic control objects will make use * this but it helps while calculating accurate packet sizes in the * kernel. */ void rtnl_tc_set_overhead(struct rtnl_tc *tc, uint32_t overhead) { tc->tc_overhead = overhead; tc->ce_mask |= TCA_ATTR_OVERHEAD; } /** * Return per packet overhead of a traffic control object * @arg tc traffic control object * * @return The overhead previously set by rtnl_tc_set_overhead() or 0. */ uint32_t rtnl_tc_get_overhead(struct rtnl_tc *tc) { return tc->tc_overhead; } /** * Set the linktype of a traffic control object * @arg tc traffic control object * @arg type type of link (e.g. ARPHRD_ATM, ARPHRD_ETHER) * * Overwrites the type of link this traffic control object is attached to. * This value is typically derived from the link this tc object is attached * if the link has been assigned via rtnl_tc_set_link(). It is usually not * necessary to set the linktype manually. This function is provided to * allow overwriting the linktype. */ void rtnl_tc_set_linktype(struct rtnl_tc *tc, uint32_t type) { tc->tc_linktype = type; tc->ce_mask |= TCA_ATTR_LINKTYPE; } /** * Return the linktype of a traffic control object * @arg tc traffic control object * * Returns the linktype of the link the traffic control object is attached to: * -# User specified value via rtnl_tc_set_linktype() * -# Value derived from link set via rtnl_tc_set_link() * -# Default fall-back: ARPHRD_ETHER */ uint32_t rtnl_tc_get_linktype(struct rtnl_tc *tc) { if (tc->ce_mask & TCA_ATTR_LINKTYPE) return tc->tc_linktype; else if (tc->ce_mask & TCA_ATTR_LINK) return tc->tc_link->l_arptype; else return ARPHRD_ETHER; /* default to ethernet */ } /** * Set identifier of traffic control object * @arg tc traffic control object * @arg id unique identifier */ void rtnl_tc_set_handle(struct rtnl_tc *tc, uint32_t id) { tc->tc_handle = id; tc->ce_mask |= TCA_ATTR_HANDLE; } /** * Return identifier of a traffic control object * @arg tc traffic control object */ uint32_t rtnl_tc_get_handle(struct rtnl_tc *tc) { return tc->tc_handle; } /** * Set the parent identifier of a traffic control object * @arg tc traffic control object * @arg parent identifier of parent traffif control object * */ void rtnl_tc_set_parent(struct rtnl_tc *tc, uint32_t parent) { tc->tc_parent = parent; tc->ce_mask |= TCA_ATTR_PARENT; } /** * Return parent identifier of a traffic control object * @arg tc traffic control object */ uint32_t rtnl_tc_get_parent(struct rtnl_tc *tc) { return tc->tc_parent; } /** * Define the type of traffic control object * @arg tc traffic control object * @arg kind name of the tc object type * * @return 0 on success or a negative error code */ int rtnl_tc_set_kind(struct rtnl_tc *tc, const char *kind) { if (tc->ce_mask & TCA_ATTR_KIND) return -NLE_EXIST; strncpy(tc->tc_kind, kind, sizeof(tc->tc_kind) - 1); tc->ce_mask |= TCA_ATTR_KIND; /* Force allocation of data */ rtnl_tc_data(tc); return 0; } /** * Return kind of traffic control object * @arg tc traffic control object * * @return Kind of traffic control object or NULL if not set. */ char *rtnl_tc_get_kind(struct rtnl_tc *tc) { if (tc->ce_mask & TCA_ATTR_KIND) return tc->tc_kind; else return NULL; } /** * Return value of a statistical counter of a traffic control object * @arg tc traffic control object * @arg id identifier of statistical counter * * @return Value of requested statistic counter or 0. */ uint64_t rtnl_tc_get_stat(struct rtnl_tc *tc, enum rtnl_tc_stat id) { if ((unsigned int) id > RTNL_TC_STATS_MAX) return 0; return tc->tc_stats[id]; } /** @} */ /** * @name Utilities * @{ */ static const struct trans_tbl tc_stats[] = { __ADD(RTNL_TC_PACKETS, packets), __ADD(RTNL_TC_BYTES, bytes), __ADD(RTNL_TC_RATE_BPS, rate_bps), __ADD(RTNL_TC_RATE_PPS, rate_pps), __ADD(RTNL_TC_QLEN, qlen), __ADD(RTNL_TC_BACKLOG, backlog), __ADD(RTNL_TC_DROPS, drops), __ADD(RTNL_TC_REQUEUES, requeues), __ADD(RTNL_TC_OVERLIMITS, overlimits), }; char *rtnl_tc_stat2str(enum rtnl_tc_stat st, char *buf, size_t len) { return __type2str(st, buf, len, tc_stats, ARRAY_SIZE(tc_stats)); } int rtnl_tc_str2stat(const char *name) { return __str2type(name, tc_stats, ARRAY_SIZE(tc_stats)); } /** * Calculate time required to transmit buffer at a specific rate * @arg bufsize Size of buffer to be transmited in bytes. * @arg rate Transmit rate in bytes per second. * * Calculates the number of micro seconds required to transmit a * specific buffer at a specific transmit rate. * * @f[ * txtime=\frac{bufsize}{rate}10^6 * @f] * * @return Required transmit time in micro seconds. */ int rtnl_tc_calc_txtime(int bufsize, int rate) { double tx_time_secs; tx_time_secs = (double) bufsize / (double) rate; return tx_time_secs * 1000000.; } /** * Calculate buffer size able to transmit in a specific time and rate. * @arg txtime Available transmit time in micro seconds. * @arg rate Transmit rate in bytes per second. * * Calculates the size of the buffer that can be transmitted in a * specific time period at a specific transmit rate. * * @f[ * bufsize=\frac{{txtime} \times {rate}}{10^6} * @f] * * @return Size of buffer in bytes. */ int rtnl_tc_calc_bufsize(int txtime, int rate) { double bufsize; bufsize = (double) txtime * (double) rate; return bufsize / 1000000.; } /** * Calculate the binary logarithm for a specific cell size * @arg cell_size Size of cell, must be a power of two. * @return Binary logirhtm of cell size or a negative error code. */ int rtnl_tc_calc_cell_log(int cell_size) { int i; for (i = 0; i < 32; i++) if ((1 << i) == cell_size) return i; return -NLE_INVAL; } /** @} */ /** * @name Rate Tables * @{ */ /* * COPYRIGHT NOTE: * align_to_atm() and adjust_size() derived/coped from iproute2 source. */ /* * The align to ATM cells is used for determining the (ATM) SAR * alignment overhead at the ATM layer. (SAR = Segmentation And * Reassembly). This is for example needed when scheduling packet on * an ADSL connection. Note that the extra ATM-AAL overhead is _not_ * included in this calculation. This overhead is added in the kernel * before doing the rate table lookup, as this gives better precision * (as the table will always be aligned for 48 bytes). * --Hawk, d.7/11-2004. */ static unsigned int align_to_atm(unsigned int size) { int linksize, cells; cells = size / ATM_CELL_PAYLOAD; if ((size % ATM_CELL_PAYLOAD) > 0) cells++; linksize = cells * ATM_CELL_SIZE; /* Use full cell size to add ATM tax */ return linksize; } static unsigned int adjust_size(unsigned int size, unsigned int mpu, uint32_t linktype) { if (size < mpu) size = mpu; switch (linktype) { case ARPHRD_ATM: return align_to_atm(size); case ARPHRD_ETHER: default: return size; } } /** * Compute a transmission time lookup table * @arg tc traffic control object * @arg spec Rate specification * @arg dst Destination buffer of RTNL_TC_RTABLE_SIZE uint32_t[]. * * Computes a table of RTNL_TC_RTABLE_SIZE entries specyfing the * transmission times for various packet sizes, e.g. the transmission * time for a packet of size \c pktsize could be looked up: * @code * txtime = table[pktsize >> log2(mtu)]; * @endcode */ int rtnl_tc_build_rate_table(struct rtnl_tc *tc, struct rtnl_ratespec *spec, uint32_t *dst) { uint32_t mtu = rtnl_tc_get_mtu(tc); uint32_t linktype = rtnl_tc_get_linktype(tc); uint8_t cell_log = spec->rs_cell_log; unsigned int size, i; spec->rs_mpu = rtnl_tc_get_mpu(tc); spec->rs_overhead = rtnl_tc_get_overhead(tc); if (mtu == 0) mtu = 2047; if (cell_log == UINT8_MAX) { /* * cell_log not specified, calculate it. It has to specify the * minimum number of rshifts required to break the MTU to below * RTNL_TC_RTABLE_SIZE. */ cell_log = 0; while ((mtu >> cell_log) >= RTNL_TC_RTABLE_SIZE) cell_log++; } for (i = 0; i < RTNL_TC_RTABLE_SIZE; i++) { size = adjust_size((i + 1) << cell_log, spec->rs_mpu, linktype); dst[i] = nl_us2ticks(rtnl_tc_calc_txtime(size, spec->rs_rate)); } spec->rs_cell_align = -1; spec->rs_cell_log = cell_log; return 0; } /** @} */ /** * @name TC implementation of cache functions */ void rtnl_tc_free_data(struct nl_object *obj) { struct rtnl_tc *tc = TC_CAST(obj); struct rtnl_tc_ops *ops; rtnl_link_put(tc->tc_link); nl_data_free(tc->tc_opts); nl_data_free(tc->tc_xstats); if (tc->tc_subdata) { ops = rtnl_tc_get_ops(tc); if (ops && ops->to_free_data) ops->to_free_data(tc, nl_data_get(tc->tc_subdata)); nl_data_free(tc->tc_subdata); } } int rtnl_tc_clone(struct nl_object *dstobj, struct nl_object *srcobj) { struct rtnl_tc *dst = TC_CAST(dstobj); struct rtnl_tc *src = TC_CAST(srcobj); struct rtnl_tc_ops *ops; if (src->tc_link) { nl_object_get(OBJ_CAST(src->tc_link)); dst->tc_link = src->tc_link; } dst->tc_opts = NULL; dst->tc_xstats = NULL; dst->tc_subdata = NULL; dst->ce_mask &= ~(TCA_ATTR_OPTS | TCA_ATTR_XSTATS); if (src->tc_opts) { dst->tc_opts = nl_data_clone(src->tc_opts); if (!dst->tc_opts) return -NLE_NOMEM; dst->ce_mask |= TCA_ATTR_OPTS; } if (src->tc_xstats) { dst->tc_xstats = nl_data_clone(src->tc_xstats); if (!dst->tc_xstats) return -NLE_NOMEM; dst->ce_mask |= TCA_ATTR_XSTATS; } if (src->tc_subdata) { if (!(dst->tc_subdata = nl_data_clone(src->tc_subdata))) { return -NLE_NOMEM; } } ops = rtnl_tc_get_ops(src); if (ops && ops->to_clone) { void *a = rtnl_tc_data(dst), *b = rtnl_tc_data(src); if (!a) return 0; else if (!b) return -NLE_NOMEM; return ops->to_clone(a, b); } return 0; } static int tc_dump(struct rtnl_tc *tc, enum nl_dump_type type, struct nl_dump_params *p) { struct rtnl_tc_type_ops *type_ops; struct rtnl_tc_ops *ops; void *data = rtnl_tc_data(tc); type_ops = tc_type_ops[tc->tc_type]; if (type_ops && type_ops->tt_dump[type]) type_ops->tt_dump[type](tc, p); ops = rtnl_tc_get_ops(tc); if (ops && ops->to_dump[type]) { ops->to_dump[type](tc, data, p); return 1; } return 0; } void rtnl_tc_dump_line(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_tc_type_ops *type_ops; struct rtnl_tc *tc = TC_CAST(obj); struct nl_cache *link_cache; char buf[32]; nl_new_line(p); type_ops = tc_type_ops[tc->tc_type]; if (type_ops && type_ops->tt_dump_prefix) nl_dump(p, "%s ", type_ops->tt_dump_prefix); nl_dump(p, "%s ", tc->tc_kind); if ((link_cache = nl_cache_mngt_require_safe("route/link"))) { nl_dump(p, "dev %s ", rtnl_link_i2name(link_cache, tc->tc_ifindex, buf, sizeof(buf))); } else nl_dump(p, "dev %u ", tc->tc_ifindex); nl_dump(p, "id %s ", rtnl_tc_handle2str(tc->tc_handle, buf, sizeof(buf))); nl_dump(p, "parent %s", rtnl_tc_handle2str(tc->tc_parent, buf, sizeof(buf))); tc_dump(tc, NL_DUMP_LINE, p); nl_dump(p, "\n"); if (link_cache) nl_cache_put(link_cache); } void rtnl_tc_dump_details(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_tc *tc = TC_CAST(obj); rtnl_tc_dump_line(OBJ_CAST(tc), p); nl_dump_line(p, " "); if (tc->ce_mask & TCA_ATTR_MTU) nl_dump(p, " mtu %u", tc->tc_mtu); if (tc->ce_mask & TCA_ATTR_MPU) nl_dump(p, " mpu %u", tc->tc_mpu); if (tc->ce_mask & TCA_ATTR_OVERHEAD) nl_dump(p, " overhead %u", tc->tc_overhead); if (!tc_dump(tc, NL_DUMP_DETAILS, p)) nl_dump(p, "no options"); nl_dump(p, "\n"); } void rtnl_tc_dump_stats(struct nl_object *obj, struct nl_dump_params *p) { struct rtnl_tc *tc = TC_CAST(obj); char *unit; float res; rtnl_tc_dump_details(OBJ_CAST(tc), p); nl_dump_line(p, " stats: %-14s %-10s %-10s %-10s %-10s %-10s\n", "bytes", "packets", "drops", "overlimits", "qlen", "backlog"); res = nl_cancel_down_bytes(tc->tc_stats[RTNL_TC_BYTES], &unit); nl_dump_line(p, " %10.2f %3s %10u %-10u %-10u %-10u %-10u\n", res, unit, tc->tc_stats[RTNL_TC_PACKETS], tc->tc_stats[RTNL_TC_DROPS], tc->tc_stats[RTNL_TC_OVERLIMITS], tc->tc_stats[RTNL_TC_QLEN], tc->tc_stats[RTNL_TC_BACKLOG]); res = nl_cancel_down_bytes(tc->tc_stats[RTNL_TC_RATE_BPS], &unit); nl_dump_line(p, " %10.2f %3s/s %10u/s\n", res, unit, tc->tc_stats[RTNL_TC_RATE_PPS]); } uint64_t rtnl_tc_compare(struct nl_object *aobj, struct nl_object *bobj, uint64_t attrs, int flags) { struct rtnl_tc *a = TC_CAST(aobj); struct rtnl_tc *b = TC_CAST(bobj); uint64_t diff = 0; #define TC_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, TCA_ATTR_##ATTR, a, b, EXPR) diff |= TC_DIFF(HANDLE, a->tc_handle != b->tc_handle); diff |= TC_DIFF(PARENT, a->tc_parent != b->tc_parent); diff |= TC_DIFF(IFINDEX, a->tc_ifindex != b->tc_ifindex); diff |= TC_DIFF(KIND, strcmp(a->tc_kind, b->tc_kind)); #undef TC_DIFF return diff; } /** @} */ /** * @name Modules API */ struct rtnl_tc_ops *rtnl_tc_lookup_ops(enum rtnl_tc_type type, const char *kind) { struct rtnl_tc_ops *ops; nl_list_for_each_entry(ops, &tc_ops_list[type], to_list) if (!strcmp(kind, ops->to_kind)) return ops; return NULL; } struct rtnl_tc_ops *rtnl_tc_get_ops(struct rtnl_tc *tc) { if (!tc->tc_ops) tc->tc_ops = rtnl_tc_lookup_ops(tc->tc_type, tc->tc_kind); return tc->tc_ops; } /** * Register a traffic control module * @arg ops traffic control module operations */ int rtnl_tc_register(struct rtnl_tc_ops *ops) { static int init = 0; /* * Initialiation hack, make sure list is initialized when * the first tc module registers. Putting this in a * separate __init would required correct ordering of init * functions */ if (!init) { int i; for (i = 0; i < __RTNL_TC_TYPE_MAX; i++) nl_init_list_head(&tc_ops_list[i]); init = 1; } if (!ops->to_kind || ops->to_type > RTNL_TC_TYPE_MAX) BUG(); if (rtnl_tc_lookup_ops(ops->to_type, ops->to_kind)) return -NLE_EXIST; nl_list_add_tail(&ops->to_list, &tc_ops_list[ops->to_type]); return 0; } /** * Unregister a traffic control module * @arg ops traffic control module operations */ void rtnl_tc_unregister(struct rtnl_tc_ops *ops) { nl_list_del(&ops->to_list); } /** * Returns the private data of the traffic control object. * Contrary to rtnl_tc_data(), this returns NULL if the data is * not yet allocated * @arg tc traffic control object * * @return pointer to the private data or NULL if not allocated. */ void *rtnl_tc_data_peek(struct rtnl_tc *tc) { return tc->tc_subdata ? nl_data_get(tc->tc_subdata) : NULL; } /** * Return pointer to private data of traffic control object * @arg tc traffic control object * * Allocates the private traffic control object data section * as necessary and returns it. * * @return Pointer to private tc data or NULL if allocation failed. */ void *rtnl_tc_data(struct rtnl_tc *tc) { if (!tc->tc_subdata) { size_t size; if (!tc->tc_ops) { if (!rtnl_tc_get_ops(tc)) return NULL; } if (!(size = tc->tc_ops->to_size)) BUG(); if (!(tc->tc_subdata = nl_data_alloc(NULL, size))) return NULL; } return nl_data_get(tc->tc_subdata); } /** * Check traffic control object type and return private data section * @arg tc traffic control object * @arg ops expected traffic control object operations * @arg err the place where saves the error code if fails * * Checks whether the traffic control object matches the type * specified with the traffic control object operations. If the * type matches, the private tc object data is returned. If type * mismatches, APPBUG() will print a application bug warning. * * @see rtnl_tc_data() * * @return Pointer to private tc data or NULL if type mismatches. */ void *rtnl_tc_data_check(struct rtnl_tc *tc, struct rtnl_tc_ops *ops, int *err) { void *ret; if (tc->tc_ops != ops) { char buf[64]; snprintf(buf, sizeof(buf), "tc object %p used in %s context but is of type %s", tc, ops->to_kind, tc->tc_ops->to_kind); APPBUG(buf); if (err) *err = -NLE_OPNOTSUPP; return NULL; } ret = rtnl_tc_data(tc); if (ret == NULL) { if (err) *err = -NLE_NOMEM; } return ret; } struct nl_af_group tc_groups[] = { { AF_UNSPEC, RTNLGRP_TC }, { END_OF_GROUP_LIST }, }; void rtnl_tc_type_register(struct rtnl_tc_type_ops *ops) { if (ops->tt_type > RTNL_TC_TYPE_MAX) BUG(); tc_type_ops[ops->tt_type] = ops; } void rtnl_tc_type_unregister(struct rtnl_tc_type_ops *ops) { if (ops->tt_type > RTNL_TC_TYPE_MAX) BUG(); tc_type_ops[ops->tt_type] = NULL; } /** @} */ /** @} */ libnl-3.2.29/lib/route/classid.c0000644000175000017500000002121213023014600013305 00000000000000/* * lib/route/classid.c ClassID Management * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2010-2013 Thomas Graf */ /** * @ingroup tc * @defgroup classid ClassID Management * @{ */ #include #include #include #include #include struct classid_map { uint32_t classid; char * name; struct nl_list_head name_list; }; #define CLASSID_NAME_HT_SIZ 256 static struct nl_list_head tbl_name[CLASSID_NAME_HT_SIZ]; static void *id_root = NULL; static int compare_id(const void *pa, const void *pb) { const struct classid_map *ma = pa; const struct classid_map *mb = pb; if (ma->classid < mb->classid) return -1; if (ma->classid > mb->classid) return 1; return 0; } /* djb2 */ static unsigned int classid_tbl_hash(const char *str) { unsigned long hash = 5381; int c; while ((c = *str++)) hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ return hash % CLASSID_NAME_HT_SIZ; } static int classid_lookup(const char *name, uint32_t *result) { struct classid_map *map; int n = classid_tbl_hash(name); nl_list_for_each_entry(map, &tbl_name[n], name_list) { if (!strcasecmp(map->name, name)) { *result = map->classid; return 0; } } return -NLE_OBJ_NOTFOUND; } static char *name_lookup(const uint32_t classid) { void *res; struct classid_map cm = { .classid = classid, .name = "search entry", }; if ((res = tfind(&cm, &id_root, &compare_id))) return (*(struct classid_map **) res)->name; return NULL; } /** * @name Traffic Control Handle Translations * @{ */ /** * Convert a traffic control handle to a character string (Reentrant). * @arg handle traffic control handle * @arg buf destination buffer * @arg len buffer length * * Converts a tarffic control handle to a character string in the * form of \c MAJ:MIN and stores it in the specified destination buffer. * * @return The destination buffer or the type encoded in hexidecimal * form if no match was found. */ char *rtnl_tc_handle2str(uint32_t handle, char *buf, size_t len) { if (TC_H_ROOT == handle) snprintf(buf, len, "root"); else if (TC_H_UNSPEC == handle) snprintf(buf, len, "none"); else if (TC_H_INGRESS == handle) snprintf(buf, len, "ingress"); else { char *name; if ((name = name_lookup(handle))) snprintf(buf, len, "%s", name); else if (0 == TC_H_MAJ(handle)) snprintf(buf, len, ":%x", TC_H_MIN(handle)); else if (0 == TC_H_MIN(handle)) snprintf(buf, len, "%x:", TC_H_MAJ(handle) >> 16); else snprintf(buf, len, "%x:%x", TC_H_MAJ(handle) >> 16, TC_H_MIN(handle)); } return buf; } /** * Convert a charactering strint to a traffic control handle * @arg str traffic control handle as character string * @arg res destination buffer * * Converts the provided character string specifying a traffic * control handle to the corresponding numeric value. * * The handle must be provided in one of the following formats: * - NAME * - root * - none * - MAJ: * - :MIN * - NAME:MIN * - MAJ:MIN * - MAJMIN * * @return 0 on success or a negative error code */ int rtnl_tc_str2handle(const char *str, uint32_t *res) { char *colon, *end; uint32_t h; int err; if (!strcasecmp(str, "root")) { *res = TC_H_ROOT; return 0; } if (!strcasecmp(str, "none")) { *res = TC_H_UNSPEC; return 0; } if (!strcasecmp(str, "ingress")) { *res = TC_H_INGRESS; return 0; } h = strtoul(str, &colon, 16); /* MAJ is not a number */ if (colon == str) { not_a_number: if (*colon == ':') { /* :YYYY */ h = 0; } else { size_t len; char name[64] = { 0 }; if (!(colon = strpbrk(str, ":"))) { /* NAME */ return classid_lookup(str, res); } else { /* NAME:YYYY */ len = colon - str; if (len >= sizeof(name)) return -NLE_INVAL; memcpy(name, str, len); if ((err = classid_lookup(name, &h)) < 0) return err; /* Name must point to a qdisc alias */ if (TC_H_MIN(h)) return -NLE_INVAL; /* NAME: is not allowed */ if (colon[1] == '\0') return -NLE_INVAL; goto update; } } } if (':' == *colon) { /* check if we would lose bits */ if (TC_H_MAJ(h)) return -NLE_RANGE; h <<= 16; if ('\0' == colon[1]) { /* XXXX: */ *res = h; } else { /* XXXX:YYYY */ uint32_t l; update: l = strtoul(colon+1, &end, 16); /* check if we overlap with major part */ if (TC_H_MAJ(l)) return -NLE_RANGE; if ('\0' != *end) return -NLE_INVAL; *res = (h | l); } } else if ('\0' == *colon) { /* XXXXYYYY */ *res = h; } else goto not_a_number; return 0; } static void free_nothing(void *arg) { } static void classid_map_free(struct classid_map *map) { if (!map) return; free(map->name); free(map); } static void clear_hashtable(void) { int i; for (i = 0; i < CLASSID_NAME_HT_SIZ; i++) { struct classid_map *map, *n; nl_list_for_each_entry_safe(map, n, &tbl_name[i], name_list) classid_map_free(map); nl_init_list_head(&tbl_name[i]); } if (id_root) { tdestroy(&id_root, &free_nothing); id_root = NULL; } } static int classid_map_add(uint32_t classid, const char *name) { struct classid_map *map; int n; if (!(map = calloc(1, sizeof(*map)))) return -NLE_NOMEM; map->classid = classid; map->name = strdup(name); n = classid_tbl_hash(map->name); nl_list_add_tail(&map->name_list, &tbl_name[n]); if (!tsearch((void *) map, &id_root, &compare_id)) { classid_map_free(map); return -NLE_NOMEM; } return 0; } /** * (Re-)read classid file * * Rereads the contents of the classid file (typically found at the location * /etc/libnl/classid) and refreshes the classid maps. * * @return 0 on success or a negative error code. */ int rtnl_tc_read_classid_file(void) { static time_t last_read; struct stat st; char buf[256], *path; FILE *fd; int err; if (build_sysconf_path(&path, "classid") < 0) return -NLE_NOMEM; /* if stat fails, just (re-)read the file */ if (stat(path, &st) == 0) { /* Don't re-read file if file is unchanged */ if (last_read == st.st_mtime) { err = 0; goto errout; } } if (!(fd = fopen(path, "r"))) { err = -nl_syserr2nlerr(errno); goto errout; } clear_hashtable(); while (fgets(buf, sizeof(buf), fd)) { uint32_t classid; char *ptr, *tok; /* ignore comments and empty lines */ if (*buf == '#' || *buf == '\n' || *buf == '\r') continue; /* token 1 */ if (!(tok = strtok_r(buf, " \t", &ptr))) { err = -NLE_INVAL; goto errout_close; } if ((err = rtnl_tc_str2handle(tok, &classid)) < 0) goto errout_close; if (!(tok = strtok_r(NULL, " \t\n\r#", &ptr))) { err = -NLE_INVAL; goto errout_close; } if ((err = classid_map_add(classid, tok)) < 0) goto errout_close; } err = 0; last_read = st.st_mtime; errout_close: fclose(fd); errout: free(path); return err; } int rtnl_classid_generate(const char *name, uint32_t *result, uint32_t parent) { static uint32_t base = 0x4000 << 16; uint32_t classid; char *path; FILE *fd; int err = 0; if (parent == TC_H_ROOT || parent == TC_H_INGRESS) { do { base += (1 << 16); if (base == TC_H_MAJ(TC_H_ROOT)) base = 0x4000 << 16; } while (name_lookup(base)); classid = base; } else { classid = TC_H_MAJ(parent); do { if (TC_H_MIN(++classid) == TC_H_MIN(TC_H_ROOT)) return -NLE_RANGE; } while (name_lookup(classid)); } NL_DBG(2, "Generated new classid %#x\n", classid); if (build_sysconf_path(&path, "classid") < 0) return -NLE_NOMEM; if (!(fd = fopen(path, "a"))) { err = -nl_syserr2nlerr(errno); goto errout; } fprintf(fd, "%x:", TC_H_MAJ(classid) >> 16); if (TC_H_MIN(classid)) fprintf(fd, "%x", TC_H_MIN(classid)); fprintf(fd, "\t\t\t%s\n", name); fclose(fd); if ((err = classid_map_add(classid, name)) < 0) { /* * Error adding classid map, re-read classid file is best * option here. It is likely to fail as well but better * than nothing, entry was added to the file already anyway. */ rtnl_tc_read_classid_file(); } *result = classid; err = 0; errout: free(path); return err; } /** @} */ static void __init classid_init(void) { int err, i; for (i = 0; i < CLASSID_NAME_HT_SIZ; i++) nl_init_list_head(&tbl_name[i]); if ((err = rtnl_tc_read_classid_file()) < 0) NL_DBG(1, "Failed to read classid file: %s\n", nl_geterror(err)); } static void free_map(void *map) { free(((struct classid_map *)map)->name); free(map); }; static void __exit classid_exit(void) { tdestroy(id_root, free_map); } /** @} */ libnl-3.2.29/lib/route/act/0000755000175000017500000000000013031473756012374 500000000000000libnl-3.2.29/lib/route/act/skbedit.c0000644000175000017500000001412313023014600014062 00000000000000/* * lib/route/act/skbedit.c skbedit action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2015 Cong Wang */ /** * @ingroup act * @defgroup act_skbedit SKB Editing * * @{ */ #include #include #include #include #include #include #include static struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = { [TCA_SKBEDIT_PARMS] = { .minlen = sizeof(struct tc_skbedit) }, [TCA_SKBEDIT_PRIORITY] = { .type = NLA_U32 }, [TCA_SKBEDIT_QUEUE_MAPPING] = { .type = NLA_U16 }, [TCA_SKBEDIT_MARK] = { .type = NLA_U32 }, }; static int skbedit_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_skbedit *u = data; struct nlattr *tb[TCA_SKBEDIT_MAX + 1]; int err; err = tca_parse(tb, TCA_SKBEDIT_MAX, tc, skbedit_policy); if (err < 0) return err; if (!tb[TCA_SKBEDIT_PARMS]) return -NLE_MISSING_ATTR; u->s_flags = 0; if (tb[TCA_SKBEDIT_PRIORITY] != NULL) { u->s_flags |= SKBEDIT_F_PRIORITY; u->s_prio = nla_get_u32(tb[TCA_SKBEDIT_PRIORITY]); } if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) { u->s_flags |= SKBEDIT_F_QUEUE_MAPPING; u->s_queue_mapping = nla_get_u16(tb[TCA_SKBEDIT_QUEUE_MAPPING]); } if (tb[TCA_SKBEDIT_MARK] != NULL) { u->s_flags |= SKBEDIT_F_MARK; u->s_mark = nla_get_u32(tb[TCA_SKBEDIT_MARK]); } return 0; } static void skbedit_free_data(struct rtnl_tc *tc, void *data) { } static int skbedit_clone(void *_dst, void *_src) { struct rtnl_skbedit *dst = _dst, *src = _src; memcpy(dst, src, sizeof(*src)); return 0; } static void skbedit_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_skbedit *u = data; if (!u) return; if (u->s_flags & SKBEDIT_F_PRIORITY) nl_dump(p, " priority %u", u->s_prio); if (u->s_flags & SKBEDIT_F_MARK) nl_dump(p, " mark %u", u->s_mark); if (u->s_flags & SKBEDIT_F_QUEUE_MAPPING) nl_dump(p, " queue_mapping %u", u->s_queue_mapping); switch(u->s_parm.action){ case TC_ACT_UNSPEC: nl_dump(p, " unspecified"); break; case TC_ACT_PIPE: nl_dump(p, " pipe"); break; case TC_ACT_STOLEN: nl_dump(p, " stolen"); break; case TC_ACT_SHOT: nl_dump(p, " shot"); break; case TC_ACT_QUEUED: nl_dump(p, " queued"); break; case TC_ACT_REPEAT: nl_dump(p, " repeat"); break; } } static void skbedit_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { } static void skbedit_dump_stats(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_skbedit *u = data; if (!u) return; /* TODO */ } static int skbedit_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_skbedit *u = data; if (!u) return 0; NLA_PUT(msg, TCA_SKBEDIT_PARMS, sizeof(u->s_parm), &u->s_parm); if (u->s_flags & SKBEDIT_F_MARK) NLA_PUT_U32(msg, TCA_SKBEDIT_MARK, u->s_mark); if (u->s_flags & SKBEDIT_F_PRIORITY) NLA_PUT_U32(msg, TCA_SKBEDIT_PRIORITY, u->s_prio); if (u->s_flags & SKBEDIT_F_QUEUE_MAPPING) NLA_PUT_U32(msg, TCA_SKBEDIT_QUEUE_MAPPING, u->s_queue_mapping); return 0; nla_put_failure: return -NLE_NOMEM; } /** * @name Attribute Modifications * @{ */ int rtnl_skbedit_set_action(struct rtnl_act *act, int action) { struct rtnl_skbedit *u; if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; if (action > TC_ACT_REPEAT || action < TC_ACT_UNSPEC) return -NLE_INVAL; u->s_parm.action = action; return 0; } int rtnl_skbedit_get_action(struct rtnl_act *act) { struct rtnl_skbedit *u; if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; return u->s_parm.action; } int rtnl_skbedit_set_queue_mapping(struct rtnl_act *act, uint16_t index) { struct rtnl_skbedit *u; if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; u->s_queue_mapping = index; u->s_flags |= SKBEDIT_F_QUEUE_MAPPING; return 0; } int rtnl_skbedit_get_queue_mapping(struct rtnl_act *act, uint16_t *index) { struct rtnl_skbedit *u; u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)); if (!u) return -NLE_NOMEM; if (!(u->s_flags & SKBEDIT_F_QUEUE_MAPPING)) return -NLE_NOATTR; *index = u->s_queue_mapping; return 0; } int rtnl_skbedit_set_mark(struct rtnl_act *act, uint32_t mark) { struct rtnl_skbedit *u; if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; u->s_mark = mark; u->s_flags |= SKBEDIT_F_MARK; return 0; } int rtnl_skbedit_get_mark(struct rtnl_act *act, uint32_t *mark) { struct rtnl_skbedit *u; u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)); if (!u) return -NLE_NOMEM; if (!(u->s_flags & SKBEDIT_F_MARK)) return -NLE_NOATTR; *mark = u->s_mark; return 0; } int rtnl_skbedit_set_priority(struct rtnl_act *act, uint32_t prio) { struct rtnl_skbedit *u; if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; u->s_prio = prio; u->s_flags |= SKBEDIT_F_PRIORITY; return 0; } int rtnl_skbedit_get_priority(struct rtnl_act *act, uint32_t *prio) { struct rtnl_skbedit *u; u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act)); if (!u) return -NLE_NOMEM; if (!(u->s_flags & SKBEDIT_F_PRIORITY)) return -NLE_NOATTR; *prio = u->s_prio; return 0; } /** @} */ static struct rtnl_tc_ops skbedit_ops = { .to_kind = "skbedit", .to_type = RTNL_TC_TYPE_ACT, .to_size = sizeof(struct rtnl_skbedit), .to_msg_parser = skbedit_msg_parser, .to_free_data = skbedit_free_data, .to_clone = skbedit_clone, .to_msg_fill = skbedit_msg_fill, .to_dump = { [NL_DUMP_LINE] = skbedit_dump_line, [NL_DUMP_DETAILS] = skbedit_dump_details, [NL_DUMP_STATS] = skbedit_dump_stats, }, }; static void __init skbedit_init(void) { rtnl_tc_register(&skbedit_ops); } static void __exit skbedit_exit(void) { rtnl_tc_unregister(&skbedit_ops); } /** @} */ libnl-3.2.29/lib/route/act/gact.c0000644000175000017500000000662513023014600013363 00000000000000/* * lib/route/act/gact.c gact action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2016 Sushma Sitaram */ /** * @ingroup act * @defgroup act_gact GACT Editing * * @{ */ #include #include #include #include #include #include #include static struct nla_policy gact_policy[TCA_GACT_MAX + 1] = { [TCA_GACT_PARMS] = { .minlen = sizeof(struct tc_gact) }, }; static int gact_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_gact *u = data; struct nlattr *tb[TCA_GACT_MAX + 1]; int err; err = tca_parse(tb, TCA_GACT_MAX, tc, gact_policy); if (err < 0) return err; if (!tb[TCA_GACT_PARMS]) return -NLE_MISSING_ATTR; nla_memcpy(&u->g_parm, tb[TCA_GACT_PARMS], sizeof(u->g_parm)); return 0; } static void gact_free_data(struct rtnl_tc *tc, void *data) { } static int gact_clone(void *_dst, void *_src) { struct rtnl_gact *dst = _dst, *src = _src; memcpy(&dst->g_parm, &src->g_parm, sizeof(src->g_parm)); return 0; } static void gact_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_gact *u = data; if (!u) return; switch(u->g_parm.action){ case TC_ACT_UNSPEC: nl_dump(p, " continue"); break; case TC_ACT_SHOT: nl_dump(p, " drop"); break; case TC_ACT_RECLASSIFY: nl_dump(p, " reclassify"); break; case TC_ACT_OK: nl_dump(p, " pass"); break; } } static void gact_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { } static void gact_dump_stats(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_gact *u = data; if (!u) return; /* TODO */ } static int gact_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_gact *u = data; if (!u) return 0; NLA_PUT(msg, TCA_GACT_PARMS, sizeof(u->g_parm), &u->g_parm); return 0; nla_put_failure: return -NLE_NOMEM; } /** * @name Attribute Modifications * @{ */ int rtnl_gact_set_action(struct rtnl_act *act, int action) { struct rtnl_gact *u; if (!(u = (struct rtnl_gact *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; if (action > TC_ACT_SHOT || action < TC_ACT_UNSPEC) return -NLE_INVAL; switch (action) { case TC_ACT_UNSPEC: case TC_ACT_SHOT: u->g_parm.action = action; break; case TC_ACT_OK: case TC_ACT_RECLASSIFY: default: return NLE_OPNOTSUPP; } return 0; } int rtnl_gact_get_action(struct rtnl_act *act) { struct rtnl_gact *u; if (!(u = (struct rtnl_gact *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; return u->g_parm.action; } /** @} */ static struct rtnl_tc_ops gact_ops = { .to_kind = "gact", .to_type = RTNL_TC_TYPE_ACT, .to_size = sizeof(struct rtnl_gact), .to_msg_parser = gact_msg_parser, .to_free_data = gact_free_data, .to_clone = gact_clone, .to_msg_fill = gact_msg_fill, .to_dump = { [NL_DUMP_LINE] = gact_dump_line, [NL_DUMP_DETAILS] = gact_dump_details, [NL_DUMP_STATS] = gact_dump_stats, }, }; static void __init gact_init(void) { rtnl_tc_register(&gact_ops); } static void __exit gact_exit(void) { rtnl_tc_unregister(&gact_ops); } /** @} */ libnl-3.2.29/lib/route/act/mirred.c0000644000175000017500000001154713023014600013726 00000000000000/* * lib/route/act/mirred.c mirred action * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2013 Cong Wang */ /** * @ingroup act * @defgroup act_mirred Mirror and Redirect * * @{ */ #include #include #include #include #include #include #include static struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = { [TCA_MIRRED_PARMS] = { .minlen = sizeof(struct tc_mirred) }, }; static int mirred_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_mirred *u = data; struct nlattr *tb[TCA_MIRRED_MAX + 1]; int err; err = tca_parse(tb, TCA_MIRRED_MAX, tc, mirred_policy); if (err < 0) return err; if (!tb[TCA_MIRRED_PARMS]) return -NLE_MISSING_ATTR; nla_memcpy(&u->m_parm, tb[TCA_MIRRED_PARMS], sizeof(u->m_parm)); return 0; } static void mirred_free_data(struct rtnl_tc *tc, void *data) { } static int mirred_clone(void *_dst, void *_src) { struct rtnl_mirred *dst = _dst, *src = _src; memcpy(&dst->m_parm, &src->m_parm, sizeof(src->m_parm)); return 0; } static void mirred_dump_line(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_mirred *u = data; if (!u) return; nl_dump(p, " index %u", u->m_parm.ifindex); if (u->m_parm.eaction == TCA_EGRESS_MIRROR) nl_dump(p, " egress mirror"); else if (u->m_parm.eaction == TCA_EGRESS_REDIR) nl_dump(p, " egress redirect"); switch(u->m_parm.action) { case TC_ACT_UNSPEC: nl_dump(p, " unspecified"); break; case TC_ACT_PIPE: nl_dump(p, " pipe"); break; case TC_ACT_STOLEN: nl_dump(p, " stolen"); break; case TC_ACT_SHOT: nl_dump(p, " shot"); break; case TC_ACT_QUEUED: nl_dump(p, " queued"); break; case TC_ACT_REPEAT: nl_dump(p, " repeat"); break; } } static void mirred_dump_details(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { } static void mirred_dump_stats(struct rtnl_tc *tc, void *data, struct nl_dump_params *p) { struct rtnl_mirred *u = data; if (!u) return; /* TODO */ } static int mirred_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) { struct rtnl_mirred *u = data; if (!u) return 0; NLA_PUT(msg, TCA_MIRRED_PARMS, sizeof(u->m_parm), &u->m_parm); return 0; nla_put_failure: return -NLE_NOMEM; } /** * @name Attribute Modifications * @{ */ int rtnl_mirred_set_action(struct rtnl_act *act, int action) { struct rtnl_mirred *u; if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; if (action > TCA_INGRESS_MIRROR || action < TCA_EGRESS_REDIR) return -NLE_INVAL; switch (action) { case TCA_EGRESS_MIRROR: case TCA_EGRESS_REDIR: u->m_parm.eaction = action; break; case TCA_INGRESS_REDIR: case TCA_INGRESS_MIRROR: default: return NLE_OPNOTSUPP; } return 0; } int rtnl_mirred_get_action(struct rtnl_act *act) { struct rtnl_mirred *u; if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; return u->m_parm.eaction; } int rtnl_mirred_set_ifindex(struct rtnl_act *act, uint32_t ifindex) { struct rtnl_mirred *u; if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; u->m_parm.ifindex = ifindex; return 0; } uint32_t rtnl_mirred_get_ifindex(struct rtnl_act *act) { struct rtnl_mirred *u; if ((u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act)))) return u->m_parm.ifindex; return 0; } int rtnl_mirred_set_policy(struct rtnl_act *act, int policy) { struct rtnl_mirred *u; if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; if (policy > TC_ACT_REPEAT || policy < TC_ACT_OK) return -NLE_INVAL; switch (u->m_parm.eaction) { case TCA_EGRESS_MIRROR: case TCA_EGRESS_REDIR: u->m_parm.action = policy; break; case TCA_INGRESS_REDIR: case TCA_INGRESS_MIRROR: default: return NLE_OPNOTSUPP; } return 0; } int rtnl_mirred_get_policy(struct rtnl_act *act) { struct rtnl_mirred *u; if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act)))) return -NLE_NOMEM; return u->m_parm.action; } /** @} */ static struct rtnl_tc_ops mirred_ops = { .to_kind = "mirred", .to_type = RTNL_TC_TYPE_ACT, .to_size = sizeof(struct rtnl_mirred), .to_msg_parser = mirred_msg_parser, .to_free_data = mirred_free_data, .to_clone = mirred_clone, .to_msg_fill = mirred_msg_fill, .to_dump = { [NL_DUMP_LINE] = mirred_dump_line, [NL_DUMP_DETAILS] = mirred_dump_details, [NL_DUMP_STATS] = mirred_dump_stats, }, }; static void __init mirred_init(void) { rtnl_tc_register(&mirred_ops); } static void __exit mirred_exit(void) { rtnl_tc_unregister(&mirred_ops); } /** @} */ libnl-3.2.29/lib/route/qdisc.c0000644000175000017500000003746513023014600013007 00000000000000/* * lib/route/qdisc.c Queueing Disciplines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2011 Thomas Graf */ /** * @ingroup tc * @defgroup qdisc Queueing Disciplines * @{ */ #include #include #include #include #include #include #include #include #include static struct nl_cache_ops rtnl_qdisc_ops; static struct nl_object_ops qdisc_obj_ops; static int qdisc_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct rtnl_qdisc *qdisc; int err; if (!(qdisc = rtnl_qdisc_alloc())) return -NLE_NOMEM; if ((err = rtnl_tc_msg_parse(n, TC_CAST(qdisc))) < 0) goto errout; err = pp->pp_cb(OBJ_CAST(qdisc), pp); errout: rtnl_qdisc_put(qdisc); return err; } static int qdisc_request_update(struct nl_cache *c, struct nl_sock *sk) { struct tcmsg tchdr = { .tcm_family = AF_UNSPEC, .tcm_ifindex = c->c_iarg1, }; return nl_send_simple(sk, RTM_GETQDISC, NLM_F_DUMP, &tchdr, sizeof(tchdr)); } /** * @name Allocation/Freeing * @{ */ struct rtnl_qdisc *rtnl_qdisc_alloc(void) { struct rtnl_tc *tc; tc = TC_CAST(nl_object_alloc(&qdisc_obj_ops)); if (tc) tc->tc_type = RTNL_TC_TYPE_QDISC; return (struct rtnl_qdisc *) tc; } void rtnl_qdisc_put(struct rtnl_qdisc *qdisc) { nl_object_put((struct nl_object *) qdisc); } /** @} */ /** * @name Addition / Modification / Deletion * @{ */ static int build_qdisc_msg(struct rtnl_qdisc *qdisc, int type, int flags, struct nl_msg **result) { if (!(qdisc->ce_mask & TCA_ATTR_IFINDEX)) { APPBUG("ifindex must be specified"); return -NLE_MISSING_ATTR; } return rtnl_tc_msg_build(TC_CAST(qdisc), type, flags, result); } /** * Build a netlink message requesting the addition of a qdisc * @arg qdisc Qdisc to add * @arg flags Additional netlink message flags * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_qdisc_add() with * the exception that it will not send the message but return it int the * provided return pointer instead. * * @see rtnl_qdisc_add() * * @return 0 on success or a negative error code. */ int rtnl_qdisc_build_add_request(struct rtnl_qdisc *qdisc, int flags, struct nl_msg **result) { if (!(qdisc->ce_mask & (TCA_ATTR_HANDLE | TCA_ATTR_PARENT))) { APPBUG("handle or parent must be specified"); return -NLE_MISSING_ATTR; } return build_qdisc_msg(qdisc, RTM_NEWQDISC, flags, result); } /** * Add qdisc * @arg sk Netlink socket * @arg qdisc Qdisc to add * @arg flags Additional netlink message flags * * Builds a \c RTM_NEWQDISC netlink message requesting the addition * of a new qdisc and sends the message to the kernel. The configuration * of the qdisc is derived from the attributes of the specified qdisc. * * The following flags may be specified: * - \c NLM_F_CREATE: Create qdisc if it does not exist, otherwise * -NLE_OBJ_NOTFOUND is returned. * - \c NLM_F_REPLACE: If another qdisc is already attached to the * parent, replace it even if the handles mismatch. * - \c NLM_F_EXCL: Return -NLE_EXISTS if a qdisc with matching * handle exists already. * * Existing qdiscs with matching handles will be updated, unless the * flag \c NLM_F_EXCL is specified. If their handles do not match, the * error -NLE_EXISTS is returned unless the flag \c NLM_F_REPLACE is * specified in which case the existing qdisc is replaced with the new * one. If no matching qdisc exists, it will be created if the flag * \c NLM_F_CREATE is set, otherwise the error -NLE_OBJ_NOTFOUND is * returned. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_qdisc_add(struct nl_sock *sk, struct rtnl_qdisc *qdisc, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_qdisc_build_add_request(qdisc, flags, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** * Build netlink message requesting the update of a qdisc * @arg qdisc Qdisc to update * @arg new Qdisc with updated attributes * @arg flags Additional netlink message flags * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_qdisc_update() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_qdisc_update() * * @return 0 on success or a negative error code. */ int rtnl_qdisc_build_update_request(struct rtnl_qdisc *qdisc, struct rtnl_qdisc *new, int flags, struct nl_msg **result) { if (flags & (NLM_F_CREATE | NLM_F_EXCL)) { APPBUG("NLM_F_CREATE and NLM_F_EXCL may not be used here, " "use rtnl_qdisc_add()"); return -NLE_INVAL; } if (!(qdisc->ce_mask & TCA_ATTR_IFINDEX)) { APPBUG("ifindex must be specified"); return -NLE_MISSING_ATTR; } if (!(qdisc->ce_mask & (TCA_ATTR_HANDLE | TCA_ATTR_PARENT))) { APPBUG("handle or parent must be specified"); return -NLE_MISSING_ATTR; } rtnl_tc_set_ifindex(TC_CAST(new), qdisc->q_ifindex); if (qdisc->ce_mask & TCA_ATTR_HANDLE) rtnl_tc_set_handle(TC_CAST(new), qdisc->q_handle); if (qdisc->ce_mask & TCA_ATTR_PARENT) rtnl_tc_set_parent(TC_CAST(new), qdisc->q_parent); return build_qdisc_msg(new, RTM_NEWQDISC, flags, result); } /** * Update qdisc * @arg sk Netlink socket * @arg qdisc Qdisc to update * @arg new Qdisc with updated attributes * @arg flags Additional netlink message flags * * Builds a \c RTM_NEWQDISC netlink message requesting the update * of an existing qdisc and sends the message to the kernel. * * This function is a varation of rtnl_qdisc_add() to update qdiscs * if the qdisc to be updated is available as qdisc object. The * behaviour is identical to the one of rtnl_qdisc_add except that * before constructing the message, it copies the \c ifindex, * \c handle, and \c parent from the original \p qdisc to the \p new * qdisc. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_qdisc_update(struct nl_sock *sk, struct rtnl_qdisc *qdisc, struct rtnl_qdisc *new, int flags) { struct nl_msg *msg; int err; err = rtnl_qdisc_build_update_request(qdisc, new, flags, &msg); if (err < 0) return err; return nl_send_sync(sk, msg); } /** * Build netlink message requesting the deletion of a qdisc * @arg qdisc Qdisc to delete * @arg result Pointer to store resulting netlink message * * The behaviour of this function is identical to rtnl_qdisc_delete() with * the exception that it will not send the message but return it in the * provided return pointer instead. * * @see rtnl_qdisc_delete() * * @return 0 on success or a negative error code. */ int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *qdisc, struct nl_msg **result) { struct nl_msg *msg; struct tcmsg tchdr; uint32_t required = TCA_ATTR_IFINDEX | TCA_ATTR_PARENT; if ((qdisc->ce_mask & required) != required) { APPBUG("ifindex and parent must be specified"); return -NLE_MISSING_ATTR; } if (!(msg = nlmsg_alloc_simple(RTM_DELQDISC, 0))) return -NLE_NOMEM; memset(&tchdr, 0, sizeof(tchdr)); tchdr.tcm_family = AF_UNSPEC; tchdr.tcm_ifindex = qdisc->q_ifindex; tchdr.tcm_parent = qdisc->q_parent; if (qdisc->ce_mask & TCA_ATTR_HANDLE) tchdr.tcm_handle = qdisc->q_handle; if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0) goto nla_put_failure; if (qdisc->ce_mask & TCA_ATTR_KIND) NLA_PUT_STRING(msg, TCA_KIND, qdisc->q_kind); *result = msg; return 0; nla_put_failure: nlmsg_free(msg); return -NLE_MSGSIZE; } /** * Delete qdisc * @arg sk Netlink socket * @arg qdisc Qdisc to add * * Builds a \c RTM_NEWQDISC netlink message requesting the deletion * of a qdisc and sends the message to the kernel. * * The message is constructed out of the following attributes: * - \c ifindex and \c parent * - \c handle (optional, must match if provided) * - \c kind (optional, must match if provided) * * All other qdisc attributes including all qdisc type specific * attributes are ignored. * * After sending, the function will wait for the ACK or an eventual * error message to be received and will therefore block until the * operation has been completed. * * @note It is not possible to delete default qdiscs. * * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause * this function to return immediately after sending. In this case, * it is the responsibility of the caller to handle any error * messages returned. * * @return 0 on success or a negative error code. */ int rtnl_qdisc_delete(struct nl_sock *sk, struct rtnl_qdisc *qdisc) { struct nl_msg *msg; int err; if ((err = rtnl_qdisc_build_delete_request(qdisc, &msg)) < 0) return err; return nl_send_sync(sk, msg); } /** @} */ /** * @name Cache Related Functions * @{ */ /** * Allocate a cache and fill it with all configured qdiscs * @arg sk Netlink socket * @arg result Pointer to store the created cache * * Allocates a new qdisc cache and fills it with a list of all configured * qdiscs on all network devices. Release the cache with nl_cache_free(). * * @return 0 on success or a negative error code. */ int rtnl_qdisc_alloc_cache(struct nl_sock *sk, struct nl_cache **result) { return nl_cache_alloc_and_fill(&rtnl_qdisc_ops, sk, result); } /** * Search qdisc by interface index and parent * @arg cache Qdisc cache * @arg ifindex Interface index * @arg parent Handle of parent qdisc * * Searches a qdisc cache previously allocated with rtnl_qdisc_alloc_cache() * and searches for a qdisc matching the interface index and parent qdisc. * * The reference counter is incremented before returning the qdisc, therefore * the reference must be given back with rtnl_qdisc_put() after usage. * * @return pointer to qdisc inside the cache or NULL if no match was found. */ struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *cache, int ifindex, uint32_t parent) { struct rtnl_qdisc *q; if (cache->c_ops != &rtnl_qdisc_ops) return NULL; nl_list_for_each_entry(q, &cache->c_items, ce_list) { if (q->q_parent == parent && q->q_ifindex == ifindex) { nl_object_get((struct nl_object *) q); return q; } } return NULL; } /** * Search qdisc by interface index and handle * @arg cache Qdisc cache * @arg ifindex Interface index * @arg handle Handle * * Searches a qdisc cache previously allocated with rtnl_qdisc_alloc_cache() * and searches for a qdisc matching the interface index and handle. * * The reference counter is incremented before returning the qdisc, therefore * the reference must be given back with rtnl_qdisc_put() after usage. * * @return Qdisc or NULL if no match was found. */ struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *cache, int ifindex, uint32_t handle) { struct rtnl_qdisc *q; if (cache->c_ops != &rtnl_qdisc_ops) return NULL; nl_list_for_each_entry(q, &cache->c_items, ce_list) { if (q->q_handle == handle && q->q_ifindex == ifindex) { nl_object_get((struct nl_object *) q); return q; } } return NULL; } /** @} */ /** * @name Deprecated Functions * @{ */ /** * Call a callback for each child class of a qdisc (deprecated) * * @deprecated Use of this function is deprecated, it does not allow * to handle the out of memory situation that can occur. */ void rtnl_qdisc_foreach_child(struct rtnl_qdisc *qdisc, struct nl_cache *cache, void (*cb)(struct nl_object *, void *), void *arg) { struct rtnl_class *filter; filter = rtnl_class_alloc(); if (!filter) return; rtnl_tc_set_parent(TC_CAST(filter), qdisc->q_handle); rtnl_tc_set_ifindex(TC_CAST(filter), qdisc->q_ifindex); rtnl_tc_set_kind(TC_CAST(filter), qdisc->q_kind); nl_cache_foreach_filter(cache, OBJ_CAST(filter), cb, arg); rtnl_class_put(filter); } /** * Call a callback for each filter attached to the qdisc (deprecated) * * @deprecated Use of this function is deprecated, it does not allow * to handle the out of memory situation that can occur. */ void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *qdisc, struct nl_cache *cache, void (*cb)(struct nl_object *, void *), void *arg) { struct rtnl_cls *filter; if (!(filter = rtnl_cls_alloc())) return; rtnl_tc_set_ifindex(TC_CAST(filter), qdisc->q_ifindex); rtnl_tc_set_parent(TC_CAST(filter), qdisc->q_parent); nl_cache_foreach_filter(cache, OBJ_CAST(filter), cb, arg); rtnl_cls_put(filter); } /** * Build a netlink message requesting the update of a qdisc * * @deprecated Use of this function is deprecated in favour of * rtnl_qdisc_build_update_request() due to the missing * possibility of specifying additional flags. */ int rtnl_qdisc_build_change_request(struct rtnl_qdisc *qdisc, struct rtnl_qdisc *new, struct nl_msg **result) { return rtnl_qdisc_build_update_request(qdisc, new, NLM_F_REPLACE, result); } /** * Change attributes of a qdisc * * @deprecated Use of this function is deprecated in favour of * rtnl_qdisc_update() due to the missing possibility of * specifying additional flags. */ int rtnl_qdisc_change(struct nl_sock *sk, struct rtnl_qdisc *qdisc, struct rtnl_qdisc *new) { return rtnl_qdisc_update(sk, qdisc, new, NLM_F_REPLACE); } /** @} */ static void qdisc_dump_details(struct rtnl_tc *tc, struct nl_dump_params *p) { struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; nl_dump(p, "refcnt %u", qdisc->q_info); } static struct rtnl_tc_type_ops qdisc_ops = { .tt_type = RTNL_TC_TYPE_QDISC, .tt_dump_prefix = "qdisc", .tt_dump = { [NL_DUMP_DETAILS] = qdisc_dump_details, }, }; static struct nl_cache_ops rtnl_qdisc_ops = { .co_name = "route/qdisc", .co_hdrsize = sizeof(struct tcmsg), .co_msgtypes = { { RTM_NEWQDISC, NL_ACT_NEW, "new" }, { RTM_DELQDISC, NL_ACT_DEL, "del" }, { RTM_GETQDISC, NL_ACT_GET, "get" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_ROUTE, .co_groups = tc_groups, .co_request_update = qdisc_request_update, .co_msg_parser = qdisc_msg_parser, .co_obj_ops = &qdisc_obj_ops, }; static struct nl_object_ops qdisc_obj_ops = { .oo_name = "route/qdisc", .oo_size = sizeof(struct rtnl_qdisc), .oo_free_data = rtnl_tc_free_data, .oo_clone = rtnl_tc_clone, .oo_dump = { [NL_DUMP_LINE] = rtnl_tc_dump_line, [NL_DUMP_DETAILS] = rtnl_tc_dump_details, [NL_DUMP_STATS] = rtnl_tc_dump_stats, }, .oo_compare = rtnl_tc_compare, .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), }; static void __init qdisc_init(void) { rtnl_tc_type_register(&qdisc_ops); nl_cache_mngt_register(&rtnl_qdisc_ops); } static void __exit qdisc_exit(void) { nl_cache_mngt_unregister(&rtnl_qdisc_ops); rtnl_tc_type_unregister(&qdisc_ops); } /** @} */ libnl-3.2.29/lib/error.c0000644000175000017500000000701713023014600011665 00000000000000/* * lib/error.c Error Handling * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2008 Thomas Graf */ #include #include static const char *errmsg[NLE_MAX+1] = { [NLE_SUCCESS] = "Success", [NLE_FAILURE] = "Unspecific failure", [NLE_INTR] = "Interrupted system call", [NLE_BAD_SOCK] = "Bad socket", [NLE_AGAIN] = "Try again", [NLE_NOMEM] = "Out of memory", [NLE_EXIST] = "Object exists", [NLE_INVAL] = "Invalid input data or parameter", [NLE_RANGE] = "Input data out of range", [NLE_MSGSIZE] = "Message size not sufficient", [NLE_OPNOTSUPP] = "Operation not supported", [NLE_AF_NOSUPPORT] = "Address family not supported", [NLE_OBJ_NOTFOUND] = "Object not found", [NLE_NOATTR] = "Attribute not available", [NLE_MISSING_ATTR] = "Missing attribute", [NLE_AF_MISMATCH] = "Address family mismatch", [NLE_SEQ_MISMATCH] = "Message sequence number mismatch", [NLE_MSG_OVERFLOW] = "Kernel reported message overflow", [NLE_MSG_TRUNC] = "Kernel reported truncated message", [NLE_NOADDR] = "Invalid address for specified address family", [NLE_SRCRT_NOSUPPORT] = "Source based routing not supported", [NLE_MSG_TOOSHORT] = "Netlink message is too short", [NLE_MSGTYPE_NOSUPPORT] = "Netlink message type is not supported", [NLE_OBJ_MISMATCH] = "Object type does not match cache", [NLE_NOCACHE] = "Unknown or invalid cache type", [NLE_BUSY] = "Object busy", [NLE_PROTO_MISMATCH] = "Protocol mismatch", [NLE_NOACCESS] = "No Access", [NLE_PERM] = "Operation not permitted", [NLE_PKTLOC_FILE] = "Unable to open packet location file", [NLE_PARSE_ERR] = "Unable to parse object", [NLE_NODEV] = "No such device", [NLE_IMMUTABLE] = "Immutable attribute", [NLE_DUMP_INTR] = "Dump inconsistency detected, interrupted", [NLE_ATTRSIZE] = "Attribute max length exceeded", }; /** * Return error message for an error code * @return error message */ const char *nl_geterror(int error) { error = abs(error); if (error > NLE_MAX) error = NLE_FAILURE; return errmsg[error]; } /** * Print a libnl error message * @arg s error message prefix * * Prints the error message of the call that failed last. * * If s is not NULL and *s is not a null byte the argument * string is printed, followed by a colon and a blank. Then * the error message and a new-line. */ void nl_perror(int error, const char *s) { if (s && *s) fprintf(stderr, "%s: %s\n", s, nl_geterror(error)); else fprintf(stderr, "%s\n", nl_geterror(error)); } int nl_syserr2nlerr(int error) { error = abs(error); switch (error) { case EBADF: return NLE_BAD_SOCK; case EADDRINUSE: return NLE_EXIST; case EEXIST: return NLE_EXIST; case EADDRNOTAVAIL: return NLE_NOADDR; case ESRCH: /* fall through */ case ENOENT: return NLE_OBJ_NOTFOUND; case EINTR: return NLE_INTR; case EAGAIN: return NLE_AGAIN; case ENOTSOCK: return NLE_BAD_SOCK; case ENOPROTOOPT: return NLE_INVAL; case EFAULT: return NLE_INVAL; case EACCES: return NLE_NOACCESS; case EINVAL: return NLE_INVAL; case ENOBUFS: return NLE_NOMEM; case ENOMEM: return NLE_NOMEM; case EAFNOSUPPORT: return NLE_AF_NOSUPPORT; case EPROTONOSUPPORT: return NLE_PROTO_MISMATCH; case EOPNOTSUPP: return NLE_OPNOTSUPP; case EPERM: return NLE_PERM; case EBUSY: return NLE_BUSY; case ERANGE: return NLE_RANGE; case ENODEV: return NLE_NODEV; default: return NLE_FAILURE; } } /** @} */ libnl-3.2.29/lib/version.c0000644000175000017500000000130213023014600012210 00000000000000/* * lib/version.c Run-time version information * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * Copyright (c) 2003-2012 Thomas Graf */ /** * @ingroup core * @defgroup utils Utilities * * Run-time version information * * @{ */ /** * @name Run-time version information * @{ */ #include const int nl_ver_num = LIBNL_VER_NUM; const int nl_ver_maj = LIBNL_VER_MAJ; const int nl_ver_min = LIBNL_VER_MIN; const int nl_ver_mic = LIBNL_VER_MIC; /** @} */ /** @} */ libnl-3.2.29/libnl-genl-3.0.pc.in0000644000175000017500000000041513023014600013067 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnl-genl Description: Generic Netlink Library Version: @PACKAGE_VERSION@ Requires: libnl-3.0 Libs: -L${libdir} -lnl-genl-@MAJ_VERSION@ Cflags: -I${includedir}/libnl@MAJ_VERSION@ libnl-3.2.29/build-aux/0000755000175000017500000000000013031473756011613 500000000000000libnl-3.2.29/build-aux/depcomp0000755000175000017500000005601613031473644013114 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnl-3.2.29/build-aux/install-sh0000755000175000017500000003452313031473644013542 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2013-12-25.23; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnl-3.2.29/build-aux/test-driver0000755000175000017500000001104013031473644013721 00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2013-07-13.22; # UTC # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnl-3.2.29/build-aux/config.sub0000755000175000017500000010624613031473644013523 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libnl-3.2.29/build-aux/ltmain.sh0000644000175000017500000117077113031473637013367 00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION=2.4.6 package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname (GNU libtool) 2.4.6 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -stdlib=* select c++ std lib with clang -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: libnl-3.2.29/build-aux/ar-lib0000755000175000017500000001330213031473644012622 00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2012-03-01.08; # UTC # Copyright (C) 2010-2014 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <, 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnl-3.2.29/build-aux/config.guess0000755000175000017500000012367213031473644014062 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libnl-3.2.29/build-aux/compile0000755000175000017500000001624513031473644013115 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: