====== pyroute2 のよるネットワーク処理 ====== アプリケーションを作成していて、下記のような処理をしたくなることも多いと思います。 * ネットワークインターフェース の状態を取得 * ネットワークイベント(インターフェースの UP/DOWN、PPP の接続・切断) の取得 安直に実装する場合、ifconfig, ip コマンドなどを実行して出力をパースする、という実装をしてしまうことも多いですが、\\ [[https://pyroute2.org/|pyroute2]] を利用することで Kernel からの Netlink Event を利用してイベントドリブンで処理をすることができます。 \\ ===== 利用方法 ===== ''pyroute2.IPDB'' モジュールを利用します。 In [1]: import pyroute2 In [2]: ipdb=pyroute2.IPDB() \\ ==== インターフェース一覧の取得 ==== In [14]: interfaces = dir(ipdb.interfaces) In [15]: interfaces Out[15]: ['br0', 'br1', 'docker0', 'enp30s0', 'enp36s0', 'lo', 'lxcbr0', 'lxdbr0', ... 中略 ... 'virbr0', 'wg0', 'wg1'] \\ ==== あるインターフェースの情報取得 ==== ''br0'' の情報を取得してみます。 In [25]: br0 = ipdb.interfaces.br0 In [26]: dir(br0) Out[26]: ['address', 'bond_active_slave', 'bond_ad_actor_sys_prio', 'bond_ad_actor_system', 'bond_ad_info', 'bond_ad_lacp_rate', 'bond_ad_select', 'bond_ad_user_port_key', 'bond_all_slaves_active', 'bond_arp_all_targets', 'bond_arp_interval', 'bond_arp_ip_target', 'bond_arp_validate', 'bond_downdelay', 'bond_fail_over_mac', 'bond_lp_interval', 'bond_miimon', 'bond_min_links', 'bond_mode', 'bond_num_peer_notif', 'bond_packets_per_slave', 'bond_primary', 'bond_primary_reselect', 'bond_resend_igmp', 'bond_tlb_dynamic_lb', 'bond_unspec', 'bond_updelay', 'bond_use_carrier', 'bond_xmit_hash_policy', 'br_ageing_time', 'br_bridge_id', 'br_fdb_flush', 'br_forward_delay', 'br_gc_timer', 'br_group_addr', 'br_group_fwd_mask', 'br_hello_time', 'br_hello_timer', 'br_max_age', 'br_mcast_hash_elasticity', 'br_mcast_hash_max', 'br_mcast_igmp_version', 'br_mcast_last_member_cnt', 'br_mcast_last_member_intvl', 'br_mcast_membership_intvl', 'br_mcast_mld_version', 'br_mcast_querier', 'br_mcast_querier_intvl', 'br_mcast_query_intvl', 'br_mcast_query_response_intvl', 'br_mcast_query_use_ifaddr', 'br_mcast_router', 'br_mcast_snooping', 'br_mcast_startup_query_cnt', 'br_mcast_startup_query_intvl', 'br_mcast_stats_enabled', 'br_nf_call_arptables', 'br_nf_call_ip6tables', 'br_nf_call_iptables', 'br_pad', 'br_priority', 'br_root_id', 'br_root_path_cost', 'br_root_port', 'br_stp_state', 'br_tcn_timer', 'br_topology_change', 'br_topology_change_detected', 'br_topology_change_timer', 'br_unspec', 'br_vlan_default_pvid', 'br_vlan_filtering', 'br_vlan_protocol', 'br_vlan_stats_enabled', 'broadcast', 'brport_bcast_flood', 'brport_bridge_id', 'brport_config_pending', 'brport_cost', 'brport_designated_cost', 'brport_designated_port', 'brport_fast_leave', 'brport_flush', 'brport_forward_delay_timer', 'brport_guard', 'brport_hold_timer', 'brport_id', 'brport_learning', 'brport_learning_sync', 'brport_mcast_flood', 'brport_mcast_to_ucast', 'brport_message_age_timer', 'brport_mode', 'brport_multicast_router', 'brport_no', 'brport_pad', 'brport_priority', 'brport_protect', 'brport_proxyarp', 'brport_proxyarp_wifi', 'brport_root_id', 'brport_state', 'brport_topology_change_ack', 'brport_unicast_flood', 'brport_unspec', 'brport_vlan_tunnel', 'carrier', 'carrier_changes', 'carrier_down_count', 'carrier_up_count', 'cost', 'ext_mask', 'family', 'flags', 'gid', 'gre_collect_metadata', 'gre_encap_dport', 'gre_encap_flags', 'gre_encap_limit', 'gre_encap_sport', 'gre_encap_type', 'gre_flags', 'gre_flowinfo', 'gre_fwmark', 'gre_iflags', 'gre_ignore_df', 'gre_ikey', 'gre_link', 'gre_local', 'gre_oflags', 'gre_okey', 'gre_pmtudisc', 'gre_remote', 'gre_tos', 'gre_ttl', 'gre_unspec', 'group', 'gso_max_segs', 'gso_max_size', 'if_netnsid', 'ifalias', 'ifi_type', 'ifname', 'ifr', 'index', 'ip6gre_encap_dport', 'ip6gre_encap_flags', 'ip6gre_encap_limit', 'ip6gre_encap_sport', 'ip6gre_encap_type', 'ip6gre_flags', 'ip6gre_flowinfo', 'ip6gre_iflags', 'ip6gre_ikey', 'ip6gre_link', 'ip6gre_local', 'ip6gre_oflags', 'ip6gre_okey', 'ip6gre_pmtudisc', 'ip6gre_remote', 'ip6gre_tos', 'ip6gre_ttl', 'ip6gre_unspec', 'ipaddr', 'ipdb_priority', 'ipdb_scope', 'ipvlan_mode', 'ipvlan_unspec', 'kind', 'link', 'link_netnsid', 'linkmode', 'macvlan_flags', 'macvlan_macaddr', 'macvlan_macaddr_count', 'macvlan_macaddr_data', 'macvlan_macaddr_mode', 'macvlan_mode', 'macvlan_unspec', 'macvtap_flags', 'macvtap_macaddr', 'macvtap_macaddr_count', 'macvtap_macaddr_data', 'macvtap_macaddr_mode', 'macvtap_mode', 'macvtap_unspec', 'master', 'mode', 'mtu', 'neighbours', 'net_ns_fd', 'net_ns_pid', 'new_ifindex', 'new_netnsid', 'num_rx_queues', 'num_tx_queues', 'num_vf', 'operstate', 'pad', 'peer', 'phys_port_id', 'phys_port_name', 'phys_switch_id', 'port_self', 'ports', 'priority', 'promiscuity', 'proto_down', 'qdisc', 'state', 'txqlen', 'uid', 'unknown', 'unspec', 'vf_ports', 'vfinfo_list', 'vlan_flags', 'vlan_id', 'vlan_protocol', 'vlans', 'vrf_table', 'vrf_unspec', 'vti_ikey', 'vti_link', 'vti_local', 'vti_okey', 'vti_remote', 'vti_unspec', 'vxlan_ageing', 'vxlan_collect_metadata', 'vxlan_df', 'vxlan_gbp', 'vxlan_gpe', 'vxlan_group', 'vxlan_group6', 'vxlan_id', 'vxlan_l2miss', 'vxlan_l3miss', 'vxlan_label', 'vxlan_learning', 'vxlan_limit', 'vxlan_link', 'vxlan_local', 'vxlan_local6', 'vxlan_port', 'vxlan_port_range', 'vxlan_proxy', 'vxlan_remcsum_nopartial', 'vxlan_remcsum_rx', 'vxlan_remcsum_tx', 'vxlan_rsc', 'vxlan_tos', 'vxlan_ttl', 'vxlan_ttl_inherit', 'vxlan_udp_csum', 'vxlan_udp_zero_csum6_rx', 'vxlan_udp_zero_csum6_tx', 'vxlan_unspec', 'weight', 'wireless', 'xdp'] ''br0'' 関係で取得できる全情報のキーは上記の通りのようです。 たとえば、インターフェースがリンクアップしているかどうかは、''operstate'' で取得できます。 In [27]: br0.operstate Out[27]: 'UP' IP Address は、''ipaddr'' で取得できます。 In [39]: ipdb.interfaces.lo.ipaddr Out[39]: (('127.0.0.1', 8), ('::1', 128)) \\ ==== Netlink Event の処理 ==== ''eventloop()'' によりイベントが発生するたびに処理が可能です。 In [40]: for event in ipdb.eventloop(): ...: print(event) ...: {'family': 2, '__pad': (), 'ifindex': 4, 'state': 4, 'flags': 0, 'ndm_type': 1, 'attrs': [('NDA_DST', '192.168.103.161'), ('NDA_LLADDR', '64:31:50:d2:4d:0a'), ('NDA_PROBES', 1), ('NDA_CACHEINFO', {'ndm_confirmed': 1637, 'ndm_used': 2851, 'ndm_updated': 0, 'ndm_refcnt': 1})], 'header': {'length': 76, 'type': 28, 'flags': 0, 'sequence_number': 0, 'pid': 0, 'error': None, 'stats': Stats(qsize=0, delta=0, delay=0)}, 'event': 'RTM_NEWNEIGH'} {'family': 2, '__pad': (), 'ifindex': 4, 'state': 16, 'flags': 0, 'ndm_type': 1, 'attrs': [('NDA_DST', '192.168.103.191'), ('NDA_LLADDR', '00:e0:4c:68:02:00'), ('NDA_PROBES', 1), ('NDA_CACHEINFO', {'ndm_confirmed': 523, 'ndm_used': 523, 'ndm_updated': 0, 'ndm_refcnt': 2})], 'header': {'length': 76, 'type': 28, 'flags': 0, 'sequence_number': 0, 'pid': 0, 'error': None, 'stats': Stats(qsize=0, delta=0, delay=0)}, 'event': 'RTM_NEWNEIGH'} {'family': 2, '__pad': (), 'ifindex': 4, 'state': 2, 'flags': 0, 'ndm_type': 1, 'attrs': [('NDA_DST', '192.168.103.191'), ('NDA_LLADDR', '00:e0:4c:68:02:00'), ('NDA_PROBES', 1), ('NDA_CACHEINFO', {'ndm_confirmed': 0, 'ndm_used': 523, 'ndm_updated': 0, 'ndm_refcnt': 2})], 'header': {'length': 76, 'type': 28, 'flags': 0, 'sequence_number': 0, 'pid': 0, 'error': None, 'stats': Stats(qsize=0, delta=0, delay=0)}, 'event': 'RTM_NEWNEIGH'} ... ''event'' には下記のようなものがあります。([参照] [[https://linuxjm.osdn.jp/html/LDP_man-pages/man7/rtnetlink.7.html]]) |<48em 10em 28em>| ^ event ^ 内容 | |RTM_NEWLINK|ネットワークインターフェースの生成| |RTM_DELLINK|ネットワークインターフェースの削除| |RTM_NEWADDR|インターフェースの IP アドレスの追加| |RTM_DELADDR|インターフェースの IP アドレスの削除| |RTM_NEWROUTE|ネットワーク経路の生成| |RTM_DELROUTE|ネットワーク経路の削除| |RTM_NEWNEIGH|近傍テーブル (neighbor table) のエントリー (例えば ARP エントリー) の追加| |RTM_DELNEIGH|近傍テーブル (neighbor table) のエントリー (例えば ARP エントリー) の削除| |RTM_NEWRULE|ルーティングルールの追加| |RTM_DELRULE|ルーティングルールの削除| |RTM_NEWQDISC|キューイングルールの追加| |RTM_DELQDISC|キューイングルールの削除| |RTM_NEWTCLASS|トラフィッククラスの追加| |RTM_DELTCLASS|トラフィッククラスの削除| |RTM_NEWTFILTER|トラフィックフィルターの追加| |RTM_DELTFILTER|トラフィックフィルターの削除| \\ PPP の接続・切断の監視をする場合、次のようなスクリプトでイベントをフィルタリングすることで監視ができます。 #! /usr/bin/env python3 import pprint import pyroute2 pp = pprint.PrettyPrinter(indent=2) ipdb = pyroute2.IPDB() for event in ipdb.eventloop(): for attr in event.get("attrs", []): if attr[0] == "IFLA_IFNAME" and attr[1].startswith("ppp"): print("- event : {}".format(event["event"])) pp.pprint(event) print("") \\ 実際に PPP 接続を行ってみると、次のようにイベントが飛んできます。 * 接続時 - event : RTM_NEWLINK { '__align': (), 'attrs': [ ('IFLA_IFNAME', 'ppp0'), ('IFLA_TXQLEN', 3), ('IFLA_OPERSTATE', 'DOWN'), ('IFLA_LINKMODE', 0), ('IFLA_MTU', 1500), ('UNKNOWN', {'header': {'length': 8, 'type': 50}}), ('UNKNOWN', {'header': {'length': 8, 'type': 51}}), ('IFLA_GROUP', 0), ('IFLA_PROMISCUITY', 0), ('IFLA_NUM_TX_QUEUES', 1), ('IFLA_GSO_MAX_SEGS', 65535), ('IFLA_GSO_MAX_SIZE', 65536), ('IFLA_CARRIER', 1), ('IFLA_QDISC', 'noop'), ('IFLA_CARRIER_CHANGES', 0), ('IFLA_PROTO_DOWN', 0), ('IFLA_CARRIER_UP_COUNT', 0), ('IFLA_CARRIER_DOWN_COUNT', 0), ('IFLA_MAP', {'mem_start': 0, 'mem_end': 0, 'base_addr': 0, 'irq': 0, 'dma': 0, 'port': 0}), ('IFLA_STATS64', {'rx_packets': 0, 'tx_packets': 0, 'rx_bytes': 0, 'tx_bytes': 0, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_STATS', {'rx_packets': 0, 'tx_packets': 0, 'rx_bytes': 0, 'tx_bytes': 0, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_XDP', '05:00:02:00:00:00:00:00'), ('IFLA_LINKINFO', {'attrs': [('IFLA_INFO_KIND', 'ppp'), ('IFLA_INFO_DATA', '')]}), ('IFLA_AF_SPEC', {'attrs': [('AF_INET', {'dummy': 65668, 'forwarding': 1, 'mc_forwarding': 0, 'proxy_arp': 0, 'accept_redirects': 1, 'secure_redirects': 1, 'send_redirects': 1, 'shared_media': 1, 'rp_filter': 1, 'accept_source_route': 1, 'bootp_relay': 0, 'log_martians': 0, 'tag': 0, 'arpfilter': 0, 'medium_id': 0, 'noxfrm': 0, 'nopolicy': 0, 'force_igmp_version': 0, 'arp_announce': 0, 'arp_ignore': 0, 'promote_secondaries': 0, 'arp_accept': 0, 'arp_notify': 0, 'accept_local': 0, 'src_vmark': 0, 'proxy_arp_pvlan': 0, 'route_localnet': 0, 'igmpv2_unsolicited_report_interval': 10000, 'igmpv3_unsolicited_report_interval': 1000}), ('AF_INET6', {'attrs': [('IFLA_INET6_FLAGS', 0), ('IFLA_INET6_CACHEINFO', {'max_reasm_len': 65535, 'tstamp': 2027016, 'reachable_time': 38528, 'retrans_time': 1000}), ('IFLA_INET6_CONF', {'forwarding': 1, 'hop_limit': 64, 'mtu': 1500, 'accept_ra': 1, 'accept_redirects': 1, 'autoconf': 1, 'dad_transmits': 1, 'router_solicitations': 4294967295, 'router_solicitation_interval': 4000, 'router_solicitation_delay': 1000, 'use_tempaddr': 2, 'temp_valid_lft': 604800, 'temp_preferred_lft': 86400, 'regen_max_retry': 3, 'max_desync_factor': 600, 'max_addresses': 16, 'force_mld_version': 0, 'accept_ra_defrtr': 1, 'accept_ra_pinfo': 1, 'accept_ra_rtr_pref': 1, 'router_probe_interval': 60000, 'accept_ra_rt_info_max_plen': 0, 'proxy_ndp': 0, 'optimistic_dad': 0, 'accept_source_route': 0, 'mc_forwarding': 0, 'disable_ipv6': 0, 'accept_dad': 4294967295, 'force_tllao': 0, 'ndisc_notify': 0}), ('IFLA_INET6_STATS', {'num': 37, 'inpkts': 0, 'inoctets': 0, 'indelivers': 0, 'outforwdatagrams': 0, 'outpkts': 0, 'outoctets': 0, 'inhdrerrors': 0, 'intoobigerrors': 0, 'innoroutes': 0, 'inaddrerrors': 0, 'inunknownprotos': 0, 'intruncatedpkts': 0, 'indiscards': 0, 'outdiscards': 0, 'outnoroutes': 0, 'reasmtimeout': 0, 'reasmreqds': 0, 'reasmoks': 0, 'reasmfails': 0, 'fragoks': 0, 'fragfails': 0, 'fragcreates': 0, 'inmcastpkts': 0, 'outmcastpkts': 0, 'inbcastpkts': 0, 'outbcastpkts': 0, 'inmcastoctets': 0, 'outmcastoctets': 0, 'inbcastoctets': 0, 'outbcastoctets': 0, 'csumerrors': 0, 'noectpkts': 0, 'ect1pkts': 0, 'ect0pkts': 0, 'cepkts': 0}), ('IFLA_INET6_ICMP6STATS', {'num': 6, 'inmsgs': 0, 'inerrors': 0, 'outmsgs': 0, 'outerrors': 0, 'csumerrors': 0}), ('IFLA_INET6_TOKEN', '::'), ('IFLA_INET6_ADDR_GEN_MODE', 0)]})]})], 'change': 4294967295, 'event': 'RTM_NEWLINK', 'family': 0, 'flags': 4240, 'header': { 'error': None, 'flags': 0, 'length': 1304, 'pid': 0, 'sequence_number': 0, 'stats': Stats(qsize=0, delta=0, delay=0), 'type': 16}, 'ifi_type': 512, 'index': 10, 'state': 'down'} - event : RTM_NEWLINK { '__align': (), 'attrs': [ ('IFLA_IFNAME', 'ppp0'), ('IFLA_TXQLEN', 3), ('IFLA_OPERSTATE', 'UNKNOWN'), ('IFLA_LINKMODE', 0), ('IFLA_MTU', 1500), ('UNKNOWN', {'header': {'length': 8, 'type': 50}}), ('UNKNOWN', {'header': {'length': 8, 'type': 51}}), ('IFLA_GROUP', 0), ('IFLA_PROMISCUITY', 0), ('IFLA_NUM_TX_QUEUES', 1), ('IFLA_GSO_MAX_SEGS', 65535), ('IFLA_GSO_MAX_SIZE', 65536), ('IFLA_CARRIER', 1), ('IFLA_QDISC', 'pfifo_fast'), ('IFLA_CARRIER_CHANGES', 0), ('IFLA_PROTO_DOWN', 0), ('IFLA_CARRIER_UP_COUNT', 0), ('IFLA_CARRIER_DOWN_COUNT', 0), ('IFLA_MAP', {'mem_start': 0, 'mem_end': 0, 'base_addr': 0, 'irq': 0, 'dma': 0, 'port': 0}), ('IFLA_STATS64', {'rx_packets': 4, 'tx_packets': 4, 'rx_bytes': 52, 'tx_bytes': 58, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_STATS', {'rx_packets': 4, 'tx_packets': 4, 'rx_bytes': 52, 'tx_bytes': 58, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_XDP', '05:00:02:00:00:00:00:00'), ('IFLA_LINKINFO', {'attrs': [('IFLA_INFO_KIND', 'ppp'), ('IFLA_INFO_DATA', '')]}), ('IFLA_AF_SPEC', {'attrs': [('AF_INET', {'dummy': 65668, 'forwarding': 1, 'mc_forwarding': 0, 'proxy_arp': 0, 'accept_redirects': 1, 'secure_redirects': 1, 'send_redirects': 1, 'shared_media': 1, 'rp_filter': 1, 'accept_source_route': 1, 'bootp_relay': 0, 'log_martians': 0, 'tag': 0, 'arpfilter': 0, 'medium_id': 0, 'noxfrm': 0, 'nopolicy': 0, 'force_igmp_version': 0, 'arp_announce': 0, 'arp_ignore': 0, 'promote_secondaries': 0, 'arp_accept': 0, 'arp_notify': 0, 'accept_local': 0, 'src_vmark': 0, 'proxy_arp_pvlan': 0, 'route_localnet': 0, 'igmpv2_unsolicited_report_interval': 10000, 'igmpv3_unsolicited_report_interval': 1000}), ('AF_INET6', {'attrs': [('IFLA_INET6_FLAGS', 0), ('IFLA_INET6_CACHEINFO', {'max_reasm_len': 65535, 'tstamp': 2027016, 'reachable_time': 38528, 'retrans_time': 1000}), ('IFLA_INET6_CONF', {'forwarding': 1, 'hop_limit': 64, 'mtu': 1500, 'accept_ra': 1, 'accept_redirects': 1, 'autoconf': 1, 'dad_transmits': 1, 'router_solicitations': 4294967295, 'router_solicitation_interval': 4000, 'router_solicitation_delay': 1000, 'use_tempaddr': 2, 'temp_valid_lft': 604800, 'temp_preferred_lft': 86400, 'regen_max_retry': 3, 'max_desync_factor': 600, 'max_addresses': 16, 'force_mld_version': 0, 'accept_ra_defrtr': 1, 'accept_ra_pinfo': 1, 'accept_ra_rtr_pref': 1, 'router_probe_interval': 60000, 'accept_ra_rt_info_max_plen': 0, 'proxy_ndp': 0, 'optimistic_dad': 0, 'accept_source_route': 0, 'mc_forwarding': 0, 'disable_ipv6': 0, 'accept_dad': 4294967295, 'force_tllao': 0, 'ndisc_notify': 0}), ('IFLA_INET6_STATS', {'num': 37, 'inpkts': 0, 'inoctets': 0, 'indelivers': 0, 'outforwdatagrams': 0, 'outpkts': 0, 'outoctets': 0, 'inhdrerrors': 0, 'intoobigerrors': 0, 'innoroutes': 0, 'inaddrerrors': 0, 'inunknownprotos': 0, 'intruncatedpkts': 0, 'indiscards': 0, 'outdiscards': 0, 'outnoroutes': 0, 'reasmtimeout': 0, 'reasmreqds': 0, 'reasmoks': 0, 'reasmfails': 0, 'fragoks': 0, 'fragfails': 0, 'fragcreates': 0, 'inmcastpkts': 0, 'outmcastpkts': 0, 'inbcastpkts': 0, 'outbcastpkts': 0, 'inmcastoctets': 0, 'outmcastoctets': 0, 'inbcastoctets': 0, 'outbcastoctets': 0, 'csumerrors': 0, 'noectpkts': 0, 'ect1pkts': 0, 'ect0pkts': 0, 'cepkts': 0}), ('IFLA_INET6_ICMP6STATS', {'num': 6, 'inmsgs': 0, 'inerrors': 0, 'outmsgs': 0, 'outerrors': 0, 'csumerrors': 0}), ('IFLA_INET6_TOKEN', '::'), ('IFLA_INET6_ADDR_GEN_MODE', 0)]})]})], 'change': 1, 'event': 'RTM_NEWLINK', 'family': 0, 'flags': 69841, 'header': { 'error': None, 'flags': 0, 'length': 1308, 'pid': 0, 'sequence_number': 0, 'stats': Stats(qsize=3, delta=-1, delay=0), 'type': 16}, 'ifi_type': 512, 'index': 10, 'state': 'up'} * 切断時 - event : RTM_NEWLINK { '__align': (), 'attrs': [ ('IFLA_IFNAME', 'ppp0'), ('IFLA_TXQLEN', 3), ('IFLA_OPERSTATE', 'DOWN'), ('IFLA_LINKMODE', 0), ('IFLA_MTU', 1500), ('UNKNOWN', {'header': {'length': 8, 'type': 50}}), ('UNKNOWN', {'header': {'length': 8, 'type': 51}}), ('IFLA_GROUP', 0), ('IFLA_PROMISCUITY', 0), ('IFLA_NUM_TX_QUEUES', 1), ('IFLA_GSO_MAX_SEGS', 65535), ('IFLA_GSO_MAX_SIZE', 65536), ('IFLA_CARRIER', 1), ('IFLA_QDISC', 'pfifo_fast'), ('IFLA_CARRIER_CHANGES', 0), ('IFLA_PROTO_DOWN', 0), ('IFLA_CARRIER_UP_COUNT', 0), ('IFLA_CARRIER_DOWN_COUNT', 0), ('IFLA_MAP', {'mem_start': 0, 'mem_end': 0, 'base_addr': 0, 'irq': 0, 'dma': 0, 'port': 0}), ('IFLA_STATS64', {'rx_packets': 4, 'tx_packets': 4, 'rx_bytes': 52, 'tx_bytes': 58, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_STATS', {'rx_packets': 4, 'tx_packets': 4, 'rx_bytes': 52, 'tx_bytes': 58, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_XDP', '05:00:02:00:00:00:00:00'), ('IFLA_LINKINFO', {'attrs': [('IFLA_INFO_KIND', 'ppp'), ('IFLA_INFO_DATA', '')]}), ('IFLA_AF_SPEC', {'attrs': [('AF_INET', {'dummy': 65668, 'forwarding': 1, 'mc_forwarding': 0, 'proxy_arp': 0, 'accept_redirects': 1, 'secure_redirects': 1, 'send_redirects': 1, 'shared_media': 1, 'rp_filter': 1, 'accept_source_route': 1, 'bootp_relay': 0, 'log_martians': 0, 'tag': 0, 'arpfilter': 0, 'medium_id': 0, 'noxfrm': 0, 'nopolicy': 0, 'force_igmp_version': 0, 'arp_announce': 0, 'arp_ignore': 0, 'promote_secondaries': 0, 'arp_accept': 0, 'arp_notify': 0, 'accept_local': 0, 'src_vmark': 0, 'proxy_arp_pvlan': 0, 'route_localnet': 0, 'igmpv2_unsolicited_report_interval': 10000, 'igmpv3_unsolicited_report_interval': 1000}), ('AF_INET6', {'attrs': [('IFLA_INET6_FLAGS', 2147483648), ('IFLA_INET6_CACHEINFO', {'max_reasm_len': 65535, 'tstamp': 2027124, 'reachable_time': 37988, 'retrans_time': 1000}), ('IFLA_INET6_CONF', {'forwarding': 1, 'hop_limit': 64, 'mtu': 1500, 'accept_ra': 1, 'accept_redirects': 1, 'autoconf': 1, 'dad_transmits': 1, 'router_solicitations': 4294967295, 'router_solicitation_interval': 4000, 'router_solicitation_delay': 1000, 'use_tempaddr': 2, 'temp_valid_lft': 604800, 'temp_preferred_lft': 86400, 'regen_max_retry': 3, 'max_desync_factor': 600, 'max_addresses': 16, 'force_mld_version': 0, 'accept_ra_defrtr': 1, 'accept_ra_pinfo': 1, 'accept_ra_rtr_pref': 1, 'router_probe_interval': 60000, 'accept_ra_rt_info_max_plen': 0, 'proxy_ndp': 0, 'optimistic_dad': 0, 'accept_source_route': 0, 'mc_forwarding': 0, 'disable_ipv6': 0, 'accept_dad': 4294967295, 'force_tllao': 0, 'ndisc_notify': 0}), ('IFLA_INET6_STATS', {'num': 37, 'inpkts': 0, 'inoctets': 0, 'indelivers': 0, 'outforwdatagrams': 0, 'outpkts': 0, 'outoctets': 0, 'inhdrerrors': 0, 'intoobigerrors': 0, 'innoroutes': 0, 'inaddrerrors': 0, 'inunknownprotos': 0, 'intruncatedpkts': 0, 'indiscards': 0, 'outdiscards': 0, 'outnoroutes': 0, 'reasmtimeout': 0, 'reasmreqds': 0, 'reasmoks': 0, 'reasmfails': 0, 'fragoks': 0, 'fragfails': 0, 'fragcreates': 0, 'inmcastpkts': 0, 'outmcastpkts': 0, 'inbcastpkts': 0, 'outbcastpkts': 0, 'inmcastoctets': 0, 'outmcastoctets': 0, 'inbcastoctets': 0, 'outbcastoctets': 0, 'csumerrors': 0, 'noectpkts': 0, 'ect1pkts': 0, 'ect0pkts': 0, 'cepkts': 0}), ('IFLA_INET6_ICMP6STATS', {'num': 6, 'inmsgs': 0, 'inerrors': 0, 'outmsgs': 0, 'outerrors': 0, 'csumerrors': 0}), ('IFLA_INET6_TOKEN', '::'), ('IFLA_INET6_ADDR_GEN_MODE', 0)]})]})], 'change': 1, 'event': 'RTM_NEWLINK', 'family': 0, 'flags': 4240, 'header': { 'error': None, 'flags': 0, 'length': 1308, 'pid': 0, 'sequence_number': 0, 'stats': Stats(qsize=0, delta=0, delay=0), 'type': 16}, 'ifi_type': 512, 'index': 10, 'state': 'down'} - event : RTM_DELLINK { '__align': (), 'attrs': [ ('IFLA_IFNAME', 'ppp0'), ('IFLA_TXQLEN', 3), ('IFLA_OPERSTATE', 'DOWN'), ('IFLA_LINKMODE', 0), ('IFLA_MTU', 1500), ('UNKNOWN', {'header': {'length': 8, 'type': 50}}), ('UNKNOWN', {'header': {'length': 8, 'type': 51}}), ('IFLA_GROUP', 0), ('IFLA_PROMISCUITY', 0), ('IFLA_NUM_TX_QUEUES', 1), ('IFLA_GSO_MAX_SEGS', 65535), ('IFLA_GSO_MAX_SIZE', 65536), ('IFLA_CARRIER', 1), ('IFLA_QDISC', 'noop'), ('IFLA_CARRIER_CHANGES', 0), ('IFLA_PROTO_DOWN', 0), ('IFLA_CARRIER_UP_COUNT', 0), ('IFLA_CARRIER_DOWN_COUNT', 0), ('IFLA_MAP', {'mem_start': 0, 'mem_end': 0, 'base_addr': 0, 'irq': 0, 'dma': 0, 'port': 0}), ('IFLA_STATS64', {'rx_packets': 4, 'tx_packets': 4, 'rx_bytes': 52, 'tx_bytes': 58, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_STATS', {'rx_packets': 4, 'tx_packets': 4, 'rx_bytes': 52, 'tx_bytes': 58, 'rx_errors': 0, 'tx_errors': 0, 'rx_dropped': 0, 'tx_dropped': 0, 'multicast': 0, 'collisions': 0, 'rx_length_errors': 0, 'rx_over_errors': 0, 'rx_crc_errors': 0, 'rx_frame_errors': 0, 'rx_fifo_errors': 0, 'rx_missed_errors': 0, 'tx_aborted_errors': 0, 'tx_carrier_errors': 0, 'tx_fifo_errors': 0, 'tx_heartbeat_errors': 0, 'tx_window_errors': 0, 'rx_compressed': 0, 'tx_compressed': 0}), ('IFLA_XDP', '05:00:02:00:00:00:00:00'), ('IFLA_LINKINFO', {'attrs': [('IFLA_INFO_KIND', 'ppp'), ('IFLA_INFO_DATA', '')]}), ('IFLA_AF_SPEC', {'attrs': []})], 'change': 4294967295, 'event': 'RTM_DELLINK', 'family': 0, 'flags': 4240, 'header': { 'error': None, 'flags': 0, 'length': 548, 'pid': 0, 'sequence_number': 0, 'stats': Stats(qsize=0, delta=0, delay=0), 'type': 17}, 'ifi_type': 512, 'index': 10, 'state': 'down'} PPP 接続時には RTM_NEWLINK (state : 'down') -> RTM_NEWLINK (state : 'up')、切断時には RTM_NEWLINK (state : 'down') -> RTM_DELLINK の順序で event が来ますので、\\ ifconfig などで polling せずにイベントドリブンでの PPP 接続監視・制御をすることができます。