1*2f2c4c7aSAndroid Build Coastguard Worker#!/usr/bin/python3 2*2f2c4c7aSAndroid Build Coastguard Worker# 3*2f2c4c7aSAndroid Build Coastguard Worker# Copyright 2014 The Android Open Source Project 4*2f2c4c7aSAndroid Build Coastguard Worker# 5*2f2c4c7aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*2f2c4c7aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*2f2c4c7aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*2f2c4c7aSAndroid Build Coastguard Worker# 9*2f2c4c7aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*2f2c4c7aSAndroid Build Coastguard Worker# 11*2f2c4c7aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*2f2c4c7aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*2f2c4c7aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*2f2c4c7aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*2f2c4c7aSAndroid Build Coastguard Worker# limitations under the License. 16*2f2c4c7aSAndroid Build Coastguard Worker 17*2f2c4c7aSAndroid Build Coastguard Worker"""Partial Python implementation of iproute functionality.""" 18*2f2c4c7aSAndroid Build Coastguard Worker 19*2f2c4c7aSAndroid Build Coastguard Worker# pylint: disable=g-bad-todo 20*2f2c4c7aSAndroid Build Coastguard Worker 21*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import AF_INET 22*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import AF_INET6 23*2f2c4c7aSAndroid Build Coastguard Worker 24*2f2c4c7aSAndroid Build Coastguard Workerimport binascii 25*2f2c4c7aSAndroid Build Coastguard Workerimport errno 26*2f2c4c7aSAndroid Build Coastguard Workerimport os 27*2f2c4c7aSAndroid Build Coastguard Workerimport socket 28*2f2c4c7aSAndroid Build Coastguard Workerimport struct 29*2f2c4c7aSAndroid Build Coastguard Worker 30*2f2c4c7aSAndroid Build Coastguard Workerimport net_test 31*2f2c4c7aSAndroid Build Coastguard Workerimport csocket 32*2f2c4c7aSAndroid Build Coastguard Workerimport cstruct 33*2f2c4c7aSAndroid Build Coastguard Workerimport netlink 34*2f2c4c7aSAndroid Build Coastguard Worker 35*2f2c4c7aSAndroid Build Coastguard Worker### rtnetlink constants. See include/uapi/linux/rtnetlink.h. 36*2f2c4c7aSAndroid Build Coastguard Worker# Message types. 37*2f2c4c7aSAndroid Build Coastguard WorkerRTM_NEWLINK = 16 38*2f2c4c7aSAndroid Build Coastguard WorkerRTM_DELLINK = 17 39*2f2c4c7aSAndroid Build Coastguard WorkerRTM_GETLINK = 18 40*2f2c4c7aSAndroid Build Coastguard WorkerRTM_NEWADDR = 20 41*2f2c4c7aSAndroid Build Coastguard WorkerRTM_DELADDR = 21 42*2f2c4c7aSAndroid Build Coastguard WorkerRTM_GETADDR = 22 43*2f2c4c7aSAndroid Build Coastguard WorkerRTM_NEWROUTE = 24 44*2f2c4c7aSAndroid Build Coastguard WorkerRTM_DELROUTE = 25 45*2f2c4c7aSAndroid Build Coastguard WorkerRTM_GETROUTE = 26 46*2f2c4c7aSAndroid Build Coastguard WorkerRTM_NEWNEIGH = 28 47*2f2c4c7aSAndroid Build Coastguard WorkerRTM_DELNEIGH = 29 48*2f2c4c7aSAndroid Build Coastguard WorkerRTM_GETNEIGH = 30 49*2f2c4c7aSAndroid Build Coastguard WorkerRTM_NEWRULE = 32 50*2f2c4c7aSAndroid Build Coastguard WorkerRTM_DELRULE = 33 51*2f2c4c7aSAndroid Build Coastguard WorkerRTM_GETRULE = 34 52*2f2c4c7aSAndroid Build Coastguard WorkerRTM_NEWNDUSEROPT = 68 53*2f2c4c7aSAndroid Build Coastguard Worker 54*2f2c4c7aSAndroid Build Coastguard Worker# Routing message type values (rtm_type). 55*2f2c4c7aSAndroid Build Coastguard WorkerRTN_UNSPEC = 0 56*2f2c4c7aSAndroid Build Coastguard WorkerRTN_UNICAST = 1 57*2f2c4c7aSAndroid Build Coastguard WorkerRTN_UNREACHABLE = 7 58*2f2c4c7aSAndroid Build Coastguard WorkerRTN_THROW = 9 59*2f2c4c7aSAndroid Build Coastguard Worker 60*2f2c4c7aSAndroid Build Coastguard Worker# Routing protocol values (rtm_protocol). 61*2f2c4c7aSAndroid Build Coastguard WorkerRTPROT_UNSPEC = 0 62*2f2c4c7aSAndroid Build Coastguard WorkerRTPROT_BOOT = 3 63*2f2c4c7aSAndroid Build Coastguard WorkerRTPROT_STATIC = 4 64*2f2c4c7aSAndroid Build Coastguard WorkerRTPROT_RA = 9 65*2f2c4c7aSAndroid Build Coastguard Worker 66*2f2c4c7aSAndroid Build Coastguard Worker# Route scope values (rtm_scope). 67*2f2c4c7aSAndroid Build Coastguard WorkerRT_SCOPE_UNIVERSE = 0 68*2f2c4c7aSAndroid Build Coastguard WorkerRT_SCOPE_LINK = 253 69*2f2c4c7aSAndroid Build Coastguard Worker 70*2f2c4c7aSAndroid Build Coastguard Worker# Named routing tables. 71*2f2c4c7aSAndroid Build Coastguard WorkerRT_TABLE_UNSPEC = 0 72*2f2c4c7aSAndroid Build Coastguard Worker 73*2f2c4c7aSAndroid Build Coastguard Worker# Routing attributes. 74*2f2c4c7aSAndroid Build Coastguard WorkerRTA_DST = 1 75*2f2c4c7aSAndroid Build Coastguard WorkerRTA_SRC = 2 76*2f2c4c7aSAndroid Build Coastguard WorkerRTA_IIF = 3 77*2f2c4c7aSAndroid Build Coastguard WorkerRTA_OIF = 4 78*2f2c4c7aSAndroid Build Coastguard WorkerRTA_GATEWAY = 5 79*2f2c4c7aSAndroid Build Coastguard WorkerRTA_PRIORITY = 6 80*2f2c4c7aSAndroid Build Coastguard WorkerRTA_PREFSRC = 7 81*2f2c4c7aSAndroid Build Coastguard WorkerRTA_METRICS = 8 82*2f2c4c7aSAndroid Build Coastguard WorkerRTA_CACHEINFO = 12 83*2f2c4c7aSAndroid Build Coastguard WorkerRTA_TABLE = 15 84*2f2c4c7aSAndroid Build Coastguard WorkerRTA_MARK = 16 85*2f2c4c7aSAndroid Build Coastguard WorkerRTA_PREF = 20 86*2f2c4c7aSAndroid Build Coastguard WorkerRTA_UID = 25 87*2f2c4c7aSAndroid Build Coastguard Worker 88*2f2c4c7aSAndroid Build Coastguard Worker# Netlink groups. 89*2f2c4c7aSAndroid Build Coastguard WorkerRTMGRP_IPV6_IFADDR = 0x100 90*2f2c4c7aSAndroid Build Coastguard WorkerRTNLGRP_ND_USEROPT = 20 91*2f2c4c7aSAndroid Build Coastguard WorkerRTMGRP_ND_USEROPT = (1 << (RTNLGRP_ND_USEROPT - 1)) # Not a kernel constant 92*2f2c4c7aSAndroid Build Coastguard Worker 93*2f2c4c7aSAndroid Build Coastguard Worker# Route metric attributes. 94*2f2c4c7aSAndroid Build Coastguard WorkerRTAX_MTU = 2 95*2f2c4c7aSAndroid Build Coastguard WorkerRTAX_HOPLIMIT = 10 96*2f2c4c7aSAndroid Build Coastguard Worker 97*2f2c4c7aSAndroid Build Coastguard Worker# Data structure formats. 98*2f2c4c7aSAndroid Build Coastguard WorkerIfinfoMsg = cstruct.Struct( 99*2f2c4c7aSAndroid Build Coastguard Worker "IfinfoMsg", "=BBHiII", "family pad type index flags change") 100*2f2c4c7aSAndroid Build Coastguard WorkerRTMsg = cstruct.Struct( 101*2f2c4c7aSAndroid Build Coastguard Worker "RTMsg", "=BBBBBBBBI", 102*2f2c4c7aSAndroid Build Coastguard Worker "family dst_len src_len tos table protocol scope type flags") 103*2f2c4c7aSAndroid Build Coastguard WorkerRTACacheinfo = cstruct.Struct( 104*2f2c4c7aSAndroid Build Coastguard Worker "RTACacheinfo", "=IIiiI", "clntref lastuse expires error used") 105*2f2c4c7aSAndroid Build Coastguard WorkerNdUseroptMsg = cstruct.Struct("nduseroptmsg", "=BxHiBBxxxxxx", 106*2f2c4c7aSAndroid Build Coastguard Worker "family opts_len ifindex icmp_type icmp_code") 107*2f2c4c7aSAndroid Build Coastguard Worker 108*2f2c4c7aSAndroid Build Coastguard Worker### Interface address constants. See include/uapi/linux/if_addr.h. 109*2f2c4c7aSAndroid Build Coastguard Worker# Interface address attributes. 110*2f2c4c7aSAndroid Build Coastguard WorkerIFA_ADDRESS = 1 111*2f2c4c7aSAndroid Build Coastguard WorkerIFA_LOCAL = 2 112*2f2c4c7aSAndroid Build Coastguard WorkerIFA_LABEL = 3 113*2f2c4c7aSAndroid Build Coastguard WorkerIFA_CACHEINFO = 6 114*2f2c4c7aSAndroid Build Coastguard Worker 115*2f2c4c7aSAndroid Build Coastguard Worker# Address flags. 116*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_SECONDARY = 0x01 117*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_TEMPORARY = IFA_F_SECONDARY 118*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_NODAD = 0x02 119*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_OPTIMISTIC = 0x04 120*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_DADFAILED = 0x08 121*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_HOMEADDRESS = 0x10 122*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_DEPRECATED = 0x20 123*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_TENTATIVE = 0x40 124*2f2c4c7aSAndroid Build Coastguard WorkerIFA_F_PERMANENT = 0x80 125*2f2c4c7aSAndroid Build Coastguard Worker 126*2f2c4c7aSAndroid Build Coastguard Worker# This cannot contain members that do not yet exist in older kernels, because 127*2f2c4c7aSAndroid Build Coastguard Worker# GetIfaceStats will fail if the kernel returns fewer bytes than the size of 128*2f2c4c7aSAndroid Build Coastguard Worker# RtnlLinkStats[64]. 129*2f2c4c7aSAndroid Build Coastguard Worker_LINK_STATS_MEMBERS = ( 130*2f2c4c7aSAndroid Build Coastguard Worker "rx_packets tx_packets rx_bytes tx_bytes rx_errors tx_errors " 131*2f2c4c7aSAndroid Build Coastguard Worker "rx_dropped tx_dropped multicast collisions " 132*2f2c4c7aSAndroid Build Coastguard Worker "rx_length_errors rx_over_errors rx_crc_errors rx_frame_errors " 133*2f2c4c7aSAndroid Build Coastguard Worker "rx_fifo_errors rx_missed_errors tx_aborted_errors tx_carrier_errors " 134*2f2c4c7aSAndroid Build Coastguard Worker "tx_fifo_errors tx_heartbeat_errors tx_window_errors " 135*2f2c4c7aSAndroid Build Coastguard Worker "rx_compressed tx_compressed") 136*2f2c4c7aSAndroid Build Coastguard Worker 137*2f2c4c7aSAndroid Build Coastguard Worker# Data structure formats. 138*2f2c4c7aSAndroid Build Coastguard WorkerIfAddrMsg = cstruct.Struct( 139*2f2c4c7aSAndroid Build Coastguard Worker "IfAddrMsg", "=BBBBI", 140*2f2c4c7aSAndroid Build Coastguard Worker "family prefixlen flags scope index") 141*2f2c4c7aSAndroid Build Coastguard WorkerIFACacheinfo = cstruct.Struct( 142*2f2c4c7aSAndroid Build Coastguard Worker "IFACacheinfo", "=IIII", "prefered valid cstamp tstamp") 143*2f2c4c7aSAndroid Build Coastguard WorkerNDACacheinfo = cstruct.Struct( 144*2f2c4c7aSAndroid Build Coastguard Worker "NDACacheinfo", "=IIII", "confirmed used updated refcnt") 145*2f2c4c7aSAndroid Build Coastguard WorkerRtnlLinkStats = cstruct.Struct( 146*2f2c4c7aSAndroid Build Coastguard Worker "RtnlLinkStats", "=IIIIIIIIIIIIIIIIIIIIIII", _LINK_STATS_MEMBERS) 147*2f2c4c7aSAndroid Build Coastguard WorkerRtnlLinkStats64 = cstruct.Struct( 148*2f2c4c7aSAndroid Build Coastguard Worker "RtnlLinkStats64", "=QQQQQQQQQQQQQQQQQQQQQQQ", _LINK_STATS_MEMBERS) 149*2f2c4c7aSAndroid Build Coastguard Worker 150*2f2c4c7aSAndroid Build Coastguard Worker### Neighbour table entry constants. See include/uapi/linux/neighbour.h. 151*2f2c4c7aSAndroid Build Coastguard Worker# Neighbour cache entry attributes. 152*2f2c4c7aSAndroid Build Coastguard WorkerNDA_DST = 1 153*2f2c4c7aSAndroid Build Coastguard WorkerNDA_LLADDR = 2 154*2f2c4c7aSAndroid Build Coastguard WorkerNDA_CACHEINFO = 3 155*2f2c4c7aSAndroid Build Coastguard WorkerNDA_PROBES = 4 156*2f2c4c7aSAndroid Build Coastguard WorkerNDA_IFINDEX = 8 157*2f2c4c7aSAndroid Build Coastguard Worker 158*2f2c4c7aSAndroid Build Coastguard Worker# Neighbour cache entry states. 159*2f2c4c7aSAndroid Build Coastguard WorkerNUD_PERMANENT = 0x80 160*2f2c4c7aSAndroid Build Coastguard Worker 161*2f2c4c7aSAndroid Build Coastguard Worker# Data structure formats. 162*2f2c4c7aSAndroid Build Coastguard WorkerNdMsg = cstruct.Struct( 163*2f2c4c7aSAndroid Build Coastguard Worker "NdMsg", "=BxxxiHBB", 164*2f2c4c7aSAndroid Build Coastguard Worker "family ifindex state flags type") 165*2f2c4c7aSAndroid Build Coastguard Worker 166*2f2c4c7aSAndroid Build Coastguard Worker 167*2f2c4c7aSAndroid Build Coastguard Worker### FIB rule constants. See include/uapi/linux/fib_rules.h. 168*2f2c4c7aSAndroid Build Coastguard WorkerFRA_IIFNAME = 3 169*2f2c4c7aSAndroid Build Coastguard WorkerFRA_PRIORITY = 6 170*2f2c4c7aSAndroid Build Coastguard WorkerFRA_FWMARK = 10 171*2f2c4c7aSAndroid Build Coastguard WorkerFRA_SUPPRESS_PREFIXLEN = 14 172*2f2c4c7aSAndroid Build Coastguard WorkerFRA_TABLE = 15 173*2f2c4c7aSAndroid Build Coastguard WorkerFRA_FWMASK = 16 174*2f2c4c7aSAndroid Build Coastguard WorkerFRA_OIFNAME = 17 175*2f2c4c7aSAndroid Build Coastguard WorkerFRA_UID_RANGE = 20 176*2f2c4c7aSAndroid Build Coastguard Worker 177*2f2c4c7aSAndroid Build Coastguard Worker# Data structure formats. 178*2f2c4c7aSAndroid Build Coastguard WorkerFibRuleUidRange = cstruct.Struct("FibRuleUidRange", "=II", "start end") 179*2f2c4c7aSAndroid Build Coastguard Worker 180*2f2c4c7aSAndroid Build Coastguard Worker# Link constants. See include/uapi/linux/if_link.h. 181*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_UNSPEC = 0 182*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_ADDRESS = 1 183*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_BROADCAST = 2 184*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_IFNAME = 3 185*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_MTU = 4 186*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_LINK = 5 187*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_QDISC = 6 188*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_STATS = 7 189*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_COST = 8 190*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_PRIORITY = 9 191*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_MASTER = 10 192*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_WIRELESS = 11 193*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_PROTINFO = 12 194*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_TXQLEN = 13 195*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_MAP = 14 196*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_WEIGHT = 15 197*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_OPERSTATE = 16 198*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_LINKMODE = 17 199*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_LINKINFO = 18 200*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_NET_NS_PID = 19 201*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_IFALIAS = 20 202*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_STATS64 = 23 203*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_AF_SPEC = 26 204*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_GROUP = 27 205*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_EXT_MASK = 29 206*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_PROMISCUITY = 30 207*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_NUM_TX_QUEUES = 31 208*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_NUM_RX_QUEUES = 32 209*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_CARRIER = 33 210*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_CARRIER_CHANGES = 35 211*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_PROTO_DOWN = 39 212*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_GSO_MAX_SEGS = 40 213*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_GSO_MAX_SIZE = 41 214*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_PAD = 42 215*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_XDP = 43 216*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_EVENT = 44 217*2f2c4c7aSAndroid Build Coastguard Worker 218*2f2c4c7aSAndroid Build Coastguard Worker# include/uapi/linux/if_link.h 219*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INFO_UNSPEC = 0 220*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INFO_KIND = 1 221*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INFO_DATA = 2 222*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INFO_XSTATS = 3 223*2f2c4c7aSAndroid Build Coastguard Worker 224*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET_CONF = 1 225*2f2c4c7aSAndroid Build Coastguard Worker 226*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_FLAGS = 1 227*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_CONF = 2 228*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_STATS = 3 229*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_MCAST = 4 230*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_CACHEINFO = 5 231*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_ICMP6STATS = 6 232*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_TOKEN = 7 233*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_ADDR_GEN_MODE = 8 234*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_INET6_RA_MTU = 9 235*2f2c4c7aSAndroid Build Coastguard Worker 236*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_XFRM_UNSPEC = 0 237*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_XFRM_LINK = 1 238*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_XFRM_IF_ID = 2 239*2f2c4c7aSAndroid Build Coastguard Worker 240*2f2c4c7aSAndroid Build Coastguard Worker# include/uapi/linux/if_tunnel.h 241*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_VTI_UNSPEC = 0 242*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_VTI_LINK = 1 243*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_VTI_IKEY = 2 244*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_VTI_OKEY = 3 245*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_VTI_LOCAL = 4 246*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_VTI_REMOTE = 5 247*2f2c4c7aSAndroid Build Coastguard Worker 248*2f2c4c7aSAndroid Build Coastguard Worker# include/net/if_inet6.h 249*2f2c4c7aSAndroid Build Coastguard WorkerIF_RA_OTHERCONF = 0x80 250*2f2c4c7aSAndroid Build Coastguard WorkerIF_RA_MANAGED = 0x40 251*2f2c4c7aSAndroid Build Coastguard WorkerIF_RA_RCVD = 0x20 252*2f2c4c7aSAndroid Build Coastguard WorkerIF_RS_SENT = 0x10 253*2f2c4c7aSAndroid Build Coastguard WorkerIF_READY = 0x80000000 254*2f2c4c7aSAndroid Build Coastguard Worker 255*2f2c4c7aSAndroid Build Coastguard Worker# Hack to use _ParseAttributes to parse family-specific interface attributes. 256*2f2c4c7aSAndroid Build Coastguard Worker# These are not actual kernel constants. 257*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_AF_SPEC_AF_INET = AF_INET 258*2f2c4c7aSAndroid Build Coastguard WorkerIFLA_AF_SPEC_AF_INET6 = AF_INET6 259*2f2c4c7aSAndroid Build Coastguard Worker 260*2f2c4c7aSAndroid Build Coastguard Worker 261*2f2c4c7aSAndroid Build Coastguard WorkerCONSTANT_PREFIXES = netlink.MakeConstantPrefixes( 262*2f2c4c7aSAndroid Build Coastguard Worker ["RTM_", "RTN_", "RTPROT_", "RT_SCOPE_", "RT_TABLE_", "RTA_", "RTMGRP_", 263*2f2c4c7aSAndroid Build Coastguard Worker "RTNLGRP_", "RTAX_", "IFA_", "IFA_F_", "NDA_", "FRA_", "IFLA_", 264*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_INFO_", "IFLA_XFRM_", "IFLA_VTI_", "IFLA_AF_SPEC_", "IFLA_INET_", 265*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_INET6_"]) 266*2f2c4c7aSAndroid Build Coastguard Worker 267*2f2c4c7aSAndroid Build Coastguard Worker 268*2f2c4c7aSAndroid Build Coastguard Workerdef CommandVerb(command): 269*2f2c4c7aSAndroid Build Coastguard Worker return ["NEW", "DEL", "GET", "SET"][command % 4] 270*2f2c4c7aSAndroid Build Coastguard Worker 271*2f2c4c7aSAndroid Build Coastguard Worker 272*2f2c4c7aSAndroid Build Coastguard Workerdef CommandSubject(command): 273*2f2c4c7aSAndroid Build Coastguard Worker return ["LINK", "ADDR", "ROUTE", "NEIGH", "RULE"][(command - 16) // 4] 274*2f2c4c7aSAndroid Build Coastguard Worker 275*2f2c4c7aSAndroid Build Coastguard Worker 276*2f2c4c7aSAndroid Build Coastguard Workerdef CommandName(command): 277*2f2c4c7aSAndroid Build Coastguard Worker try: 278*2f2c4c7aSAndroid Build Coastguard Worker return "RTM_%s%s" % (CommandVerb(command), CommandSubject(command)) 279*2f2c4c7aSAndroid Build Coastguard Worker except IndexError: 280*2f2c4c7aSAndroid Build Coastguard Worker return "RTM_%d" % command 281*2f2c4c7aSAndroid Build Coastguard Worker 282*2f2c4c7aSAndroid Build Coastguard Worker 283*2f2c4c7aSAndroid Build Coastguard Workerclass IPRoute(netlink.NetlinkSocket): 284*2f2c4c7aSAndroid Build Coastguard Worker """Provides a tiny subset of iproute functionality.""" 285*2f2c4c7aSAndroid Build Coastguard Worker 286*2f2c4c7aSAndroid Build Coastguard Worker def _NlAttrInterfaceName(self, nla_type, interface): 287*2f2c4c7aSAndroid Build Coastguard Worker return self._NlAttr(nla_type, interface.encode() + b"\x00") 288*2f2c4c7aSAndroid Build Coastguard Worker 289*2f2c4c7aSAndroid Build Coastguard Worker def _GetConstantName(self, value, prefix): 290*2f2c4c7aSAndroid Build Coastguard Worker return super(IPRoute, self)._GetConstantName(__name__, value, prefix) 291*2f2c4c7aSAndroid Build Coastguard Worker 292*2f2c4c7aSAndroid Build Coastguard Worker def _Decode(self, command, msg, nla_type, nla_data, nested): 293*2f2c4c7aSAndroid Build Coastguard Worker """Decodes netlink attributes to Python types. 294*2f2c4c7aSAndroid Build Coastguard Worker 295*2f2c4c7aSAndroid Build Coastguard Worker Values for which the code knows the type (e.g., the fwmark ID in a 296*2f2c4c7aSAndroid Build Coastguard Worker RTM_NEWRULE command) are decoded to Python integers, strings, etc. Values 297*2f2c4c7aSAndroid Build Coastguard Worker of unknown type are returned as raw byte strings. 298*2f2c4c7aSAndroid Build Coastguard Worker 299*2f2c4c7aSAndroid Build Coastguard Worker Args: 300*2f2c4c7aSAndroid Build Coastguard Worker command: An integer. 301*2f2c4c7aSAndroid Build Coastguard Worker - If positive, the number of the rtnetlink command being carried out. 302*2f2c4c7aSAndroid Build Coastguard Worker This is used to interpret the attributes. For example, for an 303*2f2c4c7aSAndroid Build Coastguard Worker RTM_NEWROUTE command, attribute type 3 is the incoming interface and 304*2f2c4c7aSAndroid Build Coastguard Worker is an integer, but for a RTM_NEWRULE command, attribute type 3 is the 305*2f2c4c7aSAndroid Build Coastguard Worker incoming interface name and is a string. 306*2f2c4c7aSAndroid Build Coastguard Worker family: The address family. Used to convert IP addresses into strings. 307*2f2c4c7aSAndroid Build Coastguard Worker nla_type: An integer, then netlink attribute type. 308*2f2c4c7aSAndroid Build Coastguard Worker nla_data: A byte string, the netlink attribute data. 309*2f2c4c7aSAndroid Build Coastguard Worker nested: A list, outermost first, of each of the attributes the NLAttrs are 310*2f2c4c7aSAndroid Build Coastguard Worker nested inside. Empty for non-nested attributes. 311*2f2c4c7aSAndroid Build Coastguard Worker 312*2f2c4c7aSAndroid Build Coastguard Worker Returns: 313*2f2c4c7aSAndroid Build Coastguard Worker A tuple (name, data): 314*2f2c4c7aSAndroid Build Coastguard Worker - name is a string (e.g., "FRA_PRIORITY") if we understood the attribute, 315*2f2c4c7aSAndroid Build Coastguard Worker or an integer if we didn't. 316*2f2c4c7aSAndroid Build Coastguard Worker - data can be an integer, a string, a nested dict of attributes as 317*2f2c4c7aSAndroid Build Coastguard Worker returned by _ParseAttributes (e.g., for RTA_METRICS), a cstruct.Struct 318*2f2c4c7aSAndroid Build Coastguard Worker (e.g., RTACacheinfo), etc. If we didn't understand the attribute, it 319*2f2c4c7aSAndroid Build Coastguard Worker will be the raw byte string. 320*2f2c4c7aSAndroid Build Coastguard Worker """ 321*2f2c4c7aSAndroid Build Coastguard Worker lastnested = nested[-1] if nested else None 322*2f2c4c7aSAndroid Build Coastguard Worker if lastnested == "RTA_METRICS": 323*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "RTAX_") 324*2f2c4c7aSAndroid Build Coastguard Worker elif lastnested == "IFLA_LINKINFO": 325*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "IFLA_INFO_") 326*2f2c4c7aSAndroid Build Coastguard Worker elif lastnested == "IFLA_INFO_DATA": 327*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "IFLA_VTI_") 328*2f2c4c7aSAndroid Build Coastguard Worker elif lastnested == "IFLA_AF_SPEC": 329*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "IFLA_AF_SPEC_") 330*2f2c4c7aSAndroid Build Coastguard Worker elif lastnested == "IFLA_AF_SPEC_AF_INET": 331*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "IFLA_INET_") 332*2f2c4c7aSAndroid Build Coastguard Worker elif lastnested == "IFLA_AF_SPEC_AF_INET6": 333*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "IFLA_INET6_") 334*2f2c4c7aSAndroid Build Coastguard Worker elif CommandSubject(command) == "ADDR": 335*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "IFA_") 336*2f2c4c7aSAndroid Build Coastguard Worker elif CommandSubject(command) == "LINK": 337*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "IFLA_") 338*2f2c4c7aSAndroid Build Coastguard Worker elif CommandSubject(command) == "RULE": 339*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "FRA_") 340*2f2c4c7aSAndroid Build Coastguard Worker elif CommandSubject(command) == "ROUTE": 341*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "RTA_") 342*2f2c4c7aSAndroid Build Coastguard Worker elif CommandSubject(command) == "NEIGH": 343*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "NDA_") 344*2f2c4c7aSAndroid Build Coastguard Worker else: 345*2f2c4c7aSAndroid Build Coastguard Worker # Don't know what this is. Leave it as an integer. 346*2f2c4c7aSAndroid Build Coastguard Worker name = nla_type 347*2f2c4c7aSAndroid Build Coastguard Worker 348*2f2c4c7aSAndroid Build Coastguard Worker if name in ["FRA_PRIORITY", "FRA_FWMARK", "FRA_TABLE", "FRA_FWMASK", 349*2f2c4c7aSAndroid Build Coastguard Worker "RTA_OIF", "RTA_PRIORITY", "RTA_TABLE", "RTA_MARK", 350*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_MTU", "IFLA_TXQLEN", "IFLA_GROUP", "IFLA_EXT_MASK", 351*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_PROMISCUITY", "IFLA_NUM_RX_QUEUES", 352*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_NUM_TX_QUEUES", "NDA_PROBES", "RTAX_MTU", 353*2f2c4c7aSAndroid Build Coastguard Worker "RTAX_HOPLIMIT", "IFLA_CARRIER_CHANGES", "IFLA_GSO_MAX_SEGS", 354*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_GSO_MAX_SIZE", "RTA_UID", "IFLA_INET6_FLAGS"]: 355*2f2c4c7aSAndroid Build Coastguard Worker data = struct.unpack("=I", nla_data)[0] 356*2f2c4c7aSAndroid Build Coastguard Worker # HACK: the code cannot distinguish between IFLA_VTI_OKEY and 357*2f2c4c7aSAndroid Build Coastguard Worker # IFLA_INET6_STATS, because they have the same values and similar context: 358*2f2c4c7aSAndroid Build Coastguard Worker # they're both in an IFLA_INFO_DATA attribute, and knowing which one is 359*2f2c4c7aSAndroid Build Coastguard Worker # being used requires remembering the IFLA_INFO_KIND attribute which is a 360*2f2c4c7aSAndroid Build Coastguard Worker # peer of the IFLA_INFO_DATA). 361*2f2c4c7aSAndroid Build Coastguard Worker # TODO: support parsing attributes whose meaning depends on the value of 362*2f2c4c7aSAndroid Build Coastguard Worker # attributes that don't directly contain them. 363*2f2c4c7aSAndroid Build Coastguard Worker # For now, disambiguate by checking the length. 364*2f2c4c7aSAndroid Build Coastguard Worker elif name in ["IFLA_VTI_OKEY", "IFLA_VTI_IKEY"] and len(nla_data) == 4: 365*2f2c4c7aSAndroid Build Coastguard Worker data = struct.unpack("!I", nla_data)[0] 366*2f2c4c7aSAndroid Build Coastguard Worker elif name == "FRA_SUPPRESS_PREFIXLEN": 367*2f2c4c7aSAndroid Build Coastguard Worker data = struct.unpack("=i", nla_data)[0] 368*2f2c4c7aSAndroid Build Coastguard Worker elif name in ["IFLA_LINKMODE", "IFLA_OPERSTATE", "IFLA_CARRIER", 369*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_INET6_ADDR_GEN_MODE"]: 370*2f2c4c7aSAndroid Build Coastguard Worker data = ord(nla_data) 371*2f2c4c7aSAndroid Build Coastguard Worker elif name in ["IFA_ADDRESS", "IFA_LOCAL", "RTA_DST", "RTA_SRC", 372*2f2c4c7aSAndroid Build Coastguard Worker "RTA_GATEWAY", "RTA_PREFSRC", "NDA_DST"]: 373*2f2c4c7aSAndroid Build Coastguard Worker data = socket.inet_ntop(msg.family, nla_data) 374*2f2c4c7aSAndroid Build Coastguard Worker elif name in ["IFLA_INET_CONF", "IFLA_INET6_CONF"]: 375*2f2c4c7aSAndroid Build Coastguard Worker data = [struct.unpack("=I", nla_data[i:i+4])[0] 376*2f2c4c7aSAndroid Build Coastguard Worker for i in range(0, len(nla_data), 4)] 377*2f2c4c7aSAndroid Build Coastguard Worker elif name == "IFLA_INET6_TOKEN": 378*2f2c4c7aSAndroid Build Coastguard Worker data = socket.inet_ntop(AF_INET6, nla_data) 379*2f2c4c7aSAndroid Build Coastguard Worker elif name in ["FRA_IIFNAME", "FRA_OIFNAME", "IFLA_IFNAME", "IFLA_QDISC", 380*2f2c4c7aSAndroid Build Coastguard Worker "IFA_LABEL", "IFLA_INFO_KIND"]: 381*2f2c4c7aSAndroid Build Coastguard Worker data = nla_data.strip(b"\x00") 382*2f2c4c7aSAndroid Build Coastguard Worker elif name in ["RTA_METRICS", "IFLA_LINKINFO", "IFLA_INFO_DATA", 383*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_AF_SPEC", "IFLA_AF_SPEC_AF_INET", 384*2f2c4c7aSAndroid Build Coastguard Worker "IFLA_AF_SPEC_AF_INET6"]: 385*2f2c4c7aSAndroid Build Coastguard Worker data = self._ParseAttributes(command, None, nla_data, nested + [name]) 386*2f2c4c7aSAndroid Build Coastguard Worker elif name == "RTA_CACHEINFO": 387*2f2c4c7aSAndroid Build Coastguard Worker data = RTACacheinfo(nla_data) 388*2f2c4c7aSAndroid Build Coastguard Worker elif name == "IFA_CACHEINFO": 389*2f2c4c7aSAndroid Build Coastguard Worker data = IFACacheinfo(nla_data) 390*2f2c4c7aSAndroid Build Coastguard Worker elif name == "NDA_CACHEINFO": 391*2f2c4c7aSAndroid Build Coastguard Worker data = NDACacheinfo(nla_data) 392*2f2c4c7aSAndroid Build Coastguard Worker elif name in ["NDA_LLADDR", "IFLA_ADDRESS", "IFLA_BROADCAST"]: 393*2f2c4c7aSAndroid Build Coastguard Worker data = ":".join(net_test.ByteToHex(x) for x in nla_data) 394*2f2c4c7aSAndroid Build Coastguard Worker elif name == "FRA_UID_RANGE": 395*2f2c4c7aSAndroid Build Coastguard Worker data = FibRuleUidRange(nla_data) 396*2f2c4c7aSAndroid Build Coastguard Worker elif name == "IFLA_STATS": 397*2f2c4c7aSAndroid Build Coastguard Worker data = RtnlLinkStats(nla_data) 398*2f2c4c7aSAndroid Build Coastguard Worker elif name == "IFLA_STATS64": 399*2f2c4c7aSAndroid Build Coastguard Worker data = RtnlLinkStats64(nla_data) 400*2f2c4c7aSAndroid Build Coastguard Worker else: 401*2f2c4c7aSAndroid Build Coastguard Worker data = nla_data 402*2f2c4c7aSAndroid Build Coastguard Worker 403*2f2c4c7aSAndroid Build Coastguard Worker return name, data 404*2f2c4c7aSAndroid Build Coastguard Worker 405*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self): 406*2f2c4c7aSAndroid Build Coastguard Worker super(IPRoute, self).__init__(netlink.NETLINK_ROUTE) 407*2f2c4c7aSAndroid Build Coastguard Worker 408*2f2c4c7aSAndroid Build Coastguard Worker def _AddressFamily(self, version): 409*2f2c4c7aSAndroid Build Coastguard Worker return {4: AF_INET, 6: AF_INET6}[version] 410*2f2c4c7aSAndroid Build Coastguard Worker 411*2f2c4c7aSAndroid Build Coastguard Worker def _SendNlRequest(self, command, data, flags=0): 412*2f2c4c7aSAndroid Build Coastguard Worker """Sends a netlink request and expects an ack.""" 413*2f2c4c7aSAndroid Build Coastguard Worker 414*2f2c4c7aSAndroid Build Coastguard Worker flags |= netlink.NLM_F_REQUEST 415*2f2c4c7aSAndroid Build Coastguard Worker if CommandVerb(command) != "GET": 416*2f2c4c7aSAndroid Build Coastguard Worker flags |= netlink.NLM_F_ACK 417*2f2c4c7aSAndroid Build Coastguard Worker if CommandVerb(command) == "NEW": 418*2f2c4c7aSAndroid Build Coastguard Worker if flags & (netlink.NLM_F_REPLACE | netlink.NLM_F_CREATE) == 0: 419*2f2c4c7aSAndroid Build Coastguard Worker flags |= netlink.NLM_F_CREATE | netlink.NLM_F_EXCL 420*2f2c4c7aSAndroid Build Coastguard Worker 421*2f2c4c7aSAndroid Build Coastguard Worker super(IPRoute, self)._SendNlRequest(command, data, flags) 422*2f2c4c7aSAndroid Build Coastguard Worker 423*2f2c4c7aSAndroid Build Coastguard Worker def _Rule(self, version, is_add, rule_type, table, match_nlattr, priority): 424*2f2c4c7aSAndroid Build Coastguard Worker """Python equivalent of "ip rule <add|del> <match_cond> lookup <table>". 425*2f2c4c7aSAndroid Build Coastguard Worker 426*2f2c4c7aSAndroid Build Coastguard Worker Args: 427*2f2c4c7aSAndroid Build Coastguard Worker version: An integer, 4 or 6. 428*2f2c4c7aSAndroid Build Coastguard Worker is_add: True to add a rule, False to delete it. 429*2f2c4c7aSAndroid Build Coastguard Worker rule_type: Type of rule, e.g., RTN_UNICAST or RTN_UNREACHABLE. 430*2f2c4c7aSAndroid Build Coastguard Worker table: If nonzero, rule looks up this table. 431*2f2c4c7aSAndroid Build Coastguard Worker match_nlattr: A blob of struct nlattrs that express the match condition. 432*2f2c4c7aSAndroid Build Coastguard Worker If None, match everything. 433*2f2c4c7aSAndroid Build Coastguard Worker priority: An integer, the priority. 434*2f2c4c7aSAndroid Build Coastguard Worker 435*2f2c4c7aSAndroid Build Coastguard Worker Raises: 436*2f2c4c7aSAndroid Build Coastguard Worker IOError: If the netlink request returns an error. 437*2f2c4c7aSAndroid Build Coastguard Worker ValueError: If the kernel's response could not be parsed. 438*2f2c4c7aSAndroid Build Coastguard Worker """ 439*2f2c4c7aSAndroid Build Coastguard Worker # Create a struct rtmsg specifying the table and the given match attributes. 440*2f2c4c7aSAndroid Build Coastguard Worker family = self._AddressFamily(version) 441*2f2c4c7aSAndroid Build Coastguard Worker rtmsg = RTMsg((family, 0, 0, 0, RT_TABLE_UNSPEC, 442*2f2c4c7aSAndroid Build Coastguard Worker RTPROT_STATIC, RT_SCOPE_UNIVERSE, rule_type, 0)).Pack() 443*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(FRA_PRIORITY, priority) 444*2f2c4c7aSAndroid Build Coastguard Worker if match_nlattr: 445*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += match_nlattr 446*2f2c4c7aSAndroid Build Coastguard Worker if table: 447*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(FRA_TABLE, table) 448*2f2c4c7aSAndroid Build Coastguard Worker 449*2f2c4c7aSAndroid Build Coastguard Worker # Create a netlink request containing the rtmsg. 450*2f2c4c7aSAndroid Build Coastguard Worker command = RTM_NEWRULE if is_add else RTM_DELRULE 451*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(command, rtmsg) 452*2f2c4c7aSAndroid Build Coastguard Worker 453*2f2c4c7aSAndroid Build Coastguard Worker def DeleteRulesAtPriority(self, version, priority): 454*2f2c4c7aSAndroid Build Coastguard Worker family = self._AddressFamily(version) 455*2f2c4c7aSAndroid Build Coastguard Worker rtmsg = RTMsg((family, 0, 0, 0, RT_TABLE_UNSPEC, 456*2f2c4c7aSAndroid Build Coastguard Worker RTPROT_STATIC, RT_SCOPE_UNIVERSE, RTN_UNICAST, 0)).Pack() 457*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(FRA_PRIORITY, priority) 458*2f2c4c7aSAndroid Build Coastguard Worker while True: 459*2f2c4c7aSAndroid Build Coastguard Worker try: 460*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(RTM_DELRULE, rtmsg) 461*2f2c4c7aSAndroid Build Coastguard Worker except IOError as e: 462*2f2c4c7aSAndroid Build Coastguard Worker if e.errno == errno.ENOENT: 463*2f2c4c7aSAndroid Build Coastguard Worker break 464*2f2c4c7aSAndroid Build Coastguard Worker else: 465*2f2c4c7aSAndroid Build Coastguard Worker raise 466*2f2c4c7aSAndroid Build Coastguard Worker 467*2f2c4c7aSAndroid Build Coastguard Worker def FwmarkRule(self, version, is_add, fwmark, fwmask, table, priority): 468*2f2c4c7aSAndroid Build Coastguard Worker nlattr = self._NlAttrU32(FRA_FWMARK, fwmark) 469*2f2c4c7aSAndroid Build Coastguard Worker nlattr += self._NlAttrU32(FRA_FWMASK, fwmask) 470*2f2c4c7aSAndroid Build Coastguard Worker return self._Rule(version, is_add, RTN_UNICAST, table, nlattr, priority) 471*2f2c4c7aSAndroid Build Coastguard Worker 472*2f2c4c7aSAndroid Build Coastguard Worker def IifRule(self, version, is_add, iif, table, priority): 473*2f2c4c7aSAndroid Build Coastguard Worker nlattr = self._NlAttrInterfaceName(FRA_IIFNAME, iif) 474*2f2c4c7aSAndroid Build Coastguard Worker return self._Rule(version, is_add, RTN_UNICAST, table, nlattr, priority) 475*2f2c4c7aSAndroid Build Coastguard Worker 476*2f2c4c7aSAndroid Build Coastguard Worker def OifRule(self, version, is_add, oif, table, priority): 477*2f2c4c7aSAndroid Build Coastguard Worker nlattr = self._NlAttrInterfaceName(FRA_OIFNAME, oif) 478*2f2c4c7aSAndroid Build Coastguard Worker return self._Rule(version, is_add, RTN_UNICAST, table, nlattr, priority) 479*2f2c4c7aSAndroid Build Coastguard Worker 480*2f2c4c7aSAndroid Build Coastguard Worker def UidRangeRule(self, version, is_add, start, end, table, priority): 481*2f2c4c7aSAndroid Build Coastguard Worker nlattr = self._NlAttrInterfaceName(FRA_IIFNAME, "lo") 482*2f2c4c7aSAndroid Build Coastguard Worker nlattr += self._NlAttr(FRA_UID_RANGE, 483*2f2c4c7aSAndroid Build Coastguard Worker FibRuleUidRange((start, end)).Pack()) 484*2f2c4c7aSAndroid Build Coastguard Worker return self._Rule(version, is_add, RTN_UNICAST, table, nlattr, priority) 485*2f2c4c7aSAndroid Build Coastguard Worker 486*2f2c4c7aSAndroid Build Coastguard Worker def UnreachableRule(self, version, is_add, priority): 487*2f2c4c7aSAndroid Build Coastguard Worker return self._Rule(version, is_add, RTN_UNREACHABLE, None, None, priority) 488*2f2c4c7aSAndroid Build Coastguard Worker 489*2f2c4c7aSAndroid Build Coastguard Worker def DefaultRule(self, version, is_add, table, priority): 490*2f2c4c7aSAndroid Build Coastguard Worker return self.FwmarkRule(version, is_add, 0, 0, table, priority) 491*2f2c4c7aSAndroid Build Coastguard Worker 492*2f2c4c7aSAndroid Build Coastguard Worker def CommandToString(self, command, data): 493*2f2c4c7aSAndroid Build Coastguard Worker try: 494*2f2c4c7aSAndroid Build Coastguard Worker name = CommandName(command) 495*2f2c4c7aSAndroid Build Coastguard Worker subject = CommandSubject(command) 496*2f2c4c7aSAndroid Build Coastguard Worker struct_type = { 497*2f2c4c7aSAndroid Build Coastguard Worker "ADDR": IfAddrMsg, 498*2f2c4c7aSAndroid Build Coastguard Worker "LINK": IfinfoMsg, 499*2f2c4c7aSAndroid Build Coastguard Worker "NEIGH": NdMsg, 500*2f2c4c7aSAndroid Build Coastguard Worker "ROUTE": RTMsg, 501*2f2c4c7aSAndroid Build Coastguard Worker "RULE": RTMsg, 502*2f2c4c7aSAndroid Build Coastguard Worker }[subject] 503*2f2c4c7aSAndroid Build Coastguard Worker parsed = self._ParseNLMsg(data, struct_type) 504*2f2c4c7aSAndroid Build Coastguard Worker return "%s %s" % (name, str(parsed)) 505*2f2c4c7aSAndroid Build Coastguard Worker except IndexError: 506*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Don't know how to print command type %s" % name) 507*2f2c4c7aSAndroid Build Coastguard Worker 508*2f2c4c7aSAndroid Build Coastguard Worker def MaybeDebugCommand(self, command, unused_flags, data): 509*2f2c4c7aSAndroid Build Coastguard Worker subject = CommandSubject(command) 510*2f2c4c7aSAndroid Build Coastguard Worker if "ALL" not in self.NL_DEBUG and subject not in self.NL_DEBUG: 511*2f2c4c7aSAndroid Build Coastguard Worker return 512*2f2c4c7aSAndroid Build Coastguard Worker print(self.CommandToString(command, data)) 513*2f2c4c7aSAndroid Build Coastguard Worker 514*2f2c4c7aSAndroid Build Coastguard Worker def MaybeDebugMessage(self, message): 515*2f2c4c7aSAndroid Build Coastguard Worker hdr = netlink.NLMsgHdr(message) 516*2f2c4c7aSAndroid Build Coastguard Worker self.MaybeDebugCommand(hdr.type, message) 517*2f2c4c7aSAndroid Build Coastguard Worker 518*2f2c4c7aSAndroid Build Coastguard Worker def PrintMessage(self, message): 519*2f2c4c7aSAndroid Build Coastguard Worker hdr = netlink.NLMsgHdr(message) 520*2f2c4c7aSAndroid Build Coastguard Worker print(self.CommandToString(hdr.type, message)) 521*2f2c4c7aSAndroid Build Coastguard Worker 522*2f2c4c7aSAndroid Build Coastguard Worker def DumpRules(self, version): 523*2f2c4c7aSAndroid Build Coastguard Worker """Returns the IP rules for the specified IP version.""" 524*2f2c4c7aSAndroid Build Coastguard Worker # Create a struct rtmsg specifying the table and the given match attributes. 525*2f2c4c7aSAndroid Build Coastguard Worker family = self._AddressFamily(version) 526*2f2c4c7aSAndroid Build Coastguard Worker rtmsg = RTMsg((family, 0, 0, 0, 0, 0, 0, 0, 0)) 527*2f2c4c7aSAndroid Build Coastguard Worker return self._Dump(RTM_GETRULE, rtmsg, RTMsg) 528*2f2c4c7aSAndroid Build Coastguard Worker 529*2f2c4c7aSAndroid Build Coastguard Worker def DumpLinks(self): 530*2f2c4c7aSAndroid Build Coastguard Worker ifinfomsg = IfinfoMsg((0, 0, 0, 0, 0, 0)) 531*2f2c4c7aSAndroid Build Coastguard Worker return self._Dump(RTM_GETLINK, ifinfomsg, IfinfoMsg) 532*2f2c4c7aSAndroid Build Coastguard Worker 533*2f2c4c7aSAndroid Build Coastguard Worker def DumpAddresses(self, version): 534*2f2c4c7aSAndroid Build Coastguard Worker family = self._AddressFamily(version) 535*2f2c4c7aSAndroid Build Coastguard Worker ifaddrmsg = IfAddrMsg((family, 0, 0, 0, 0)) 536*2f2c4c7aSAndroid Build Coastguard Worker return self._Dump(RTM_GETADDR, ifaddrmsg, IfAddrMsg) 537*2f2c4c7aSAndroid Build Coastguard Worker 538*2f2c4c7aSAndroid Build Coastguard Worker def _Address(self, version, command, addr, prefixlen, flags, scope, ifindex): 539*2f2c4c7aSAndroid Build Coastguard Worker """Adds or deletes an IP address.""" 540*2f2c4c7aSAndroid Build Coastguard Worker family = self._AddressFamily(version) 541*2f2c4c7aSAndroid Build Coastguard Worker ifaddrmsg = IfAddrMsg((family, prefixlen, flags, scope, ifindex)).Pack() 542*2f2c4c7aSAndroid Build Coastguard Worker ifaddrmsg += self._NlAttrIPAddress(IFA_ADDRESS, family, addr) 543*2f2c4c7aSAndroid Build Coastguard Worker if version == 4: 544*2f2c4c7aSAndroid Build Coastguard Worker ifaddrmsg += self._NlAttrIPAddress(IFA_LOCAL, family, addr) 545*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(command, ifaddrmsg) 546*2f2c4c7aSAndroid Build Coastguard Worker 547*2f2c4c7aSAndroid Build Coastguard Worker def _WaitForAddress(self, sock, address, ifindex): 548*2f2c4c7aSAndroid Build Coastguard Worker # IPv6 addresses aren't immediately usable when the netlink ACK comes back. 549*2f2c4c7aSAndroid Build Coastguard Worker # Even if DAD is disabled via IFA_F_NODAD or on the interface, when the ACK 550*2f2c4c7aSAndroid Build Coastguard Worker # arrives the input route has not yet been added to the local table. The 551*2f2c4c7aSAndroid Build Coastguard Worker # route is added in addrconf_dad_begin with a delayed timer of 0, but if 552*2f2c4c7aSAndroid Build Coastguard Worker # the system is under load, we could win the race against that timer and 553*2f2c4c7aSAndroid Build Coastguard Worker # cause the tests to be flaky. So, wait for RTM_NEWADDR to arrive 554*2f2c4c7aSAndroid Build Coastguard Worker csocket.SetSocketTimeout(sock, 100) 555*2f2c4c7aSAndroid Build Coastguard Worker while True: 556*2f2c4c7aSAndroid Build Coastguard Worker try: 557*2f2c4c7aSAndroid Build Coastguard Worker data = sock.recv(4096) 558*2f2c4c7aSAndroid Build Coastguard Worker except EnvironmentError as e: 559*2f2c4c7aSAndroid Build Coastguard Worker raise AssertionError("Address %s did not appear on ifindex %d: %s" % 560*2f2c4c7aSAndroid Build Coastguard Worker (address, ifindex, e.strerror)) 561*2f2c4c7aSAndroid Build Coastguard Worker msg, attrs = self._ParseNLMsg(data, IfAddrMsg)[0] 562*2f2c4c7aSAndroid Build Coastguard Worker if msg.index == ifindex and attrs["IFA_ADDRESS"] == address: 563*2f2c4c7aSAndroid Build Coastguard Worker return 564*2f2c4c7aSAndroid Build Coastguard Worker 565*2f2c4c7aSAndroid Build Coastguard Worker def AddAddress(self, address, prefixlen, ifindex): 566*2f2c4c7aSAndroid Build Coastguard Worker """Adds a statically-configured IP address to an interface. 567*2f2c4c7aSAndroid Build Coastguard Worker 568*2f2c4c7aSAndroid Build Coastguard Worker The address is created with flags IFA_F_PERMANENT, and, if IPv6, 569*2f2c4c7aSAndroid Build Coastguard Worker IFA_F_NODAD. The requested scope is RT_SCOPE_UNIVERSE, but at least for 570*2f2c4c7aSAndroid Build Coastguard Worker IPv6, is instead determined by the kernel. 571*2f2c4c7aSAndroid Build Coastguard Worker 572*2f2c4c7aSAndroid Build Coastguard Worker In order to avoid races (see comments in _WaitForAddress above), when 573*2f2c4c7aSAndroid Build Coastguard Worker configuring IPv6 addresses, the method blocks until it receives an 574*2f2c4c7aSAndroid Build Coastguard Worker RTM_NEWADDR from the kernel confirming that the address has been added. 575*2f2c4c7aSAndroid Build Coastguard Worker If the address does not appear within 100ms, AssertionError is thrown. 576*2f2c4c7aSAndroid Build Coastguard Worker 577*2f2c4c7aSAndroid Build Coastguard Worker Args: 578*2f2c4c7aSAndroid Build Coastguard Worker address: A string, the IP address to configure. 579*2f2c4c7aSAndroid Build Coastguard Worker prefixlen: The prefix length passed to the kernel. If not /32 for IPv4 or 580*2f2c4c7aSAndroid Build Coastguard Worker /128 for IPv6, the kernel creates an implicit directly-connected route. 581*2f2c4c7aSAndroid Build Coastguard Worker ifindex: The interface index to add the address to. 582*2f2c4c7aSAndroid Build Coastguard Worker 583*2f2c4c7aSAndroid Build Coastguard Worker Raises: 584*2f2c4c7aSAndroid Build Coastguard Worker AssertionError: An IPv6 address was requested, and it did not appear 585*2f2c4c7aSAndroid Build Coastguard Worker within the timeout. 586*2f2c4c7aSAndroid Build Coastguard Worker """ 587*2f2c4c7aSAndroid Build Coastguard Worker version = csocket.AddressVersion(address) 588*2f2c4c7aSAndroid Build Coastguard Worker 589*2f2c4c7aSAndroid Build Coastguard Worker flags = IFA_F_PERMANENT 590*2f2c4c7aSAndroid Build Coastguard Worker if version == 6: 591*2f2c4c7aSAndroid Build Coastguard Worker flags |= IFA_F_NODAD 592*2f2c4c7aSAndroid Build Coastguard Worker sock = self._OpenNetlinkSocket(netlink.NETLINK_ROUTE, RTMGRP_IPV6_IFADDR) 593*2f2c4c7aSAndroid Build Coastguard Worker 594*2f2c4c7aSAndroid Build Coastguard Worker self._Address(version, RTM_NEWADDR, address, prefixlen, flags, 595*2f2c4c7aSAndroid Build Coastguard Worker RT_SCOPE_UNIVERSE, ifindex) 596*2f2c4c7aSAndroid Build Coastguard Worker 597*2f2c4c7aSAndroid Build Coastguard Worker if version == 6: 598*2f2c4c7aSAndroid Build Coastguard Worker self._WaitForAddress(sock, address, ifindex) 599*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 600*2f2c4c7aSAndroid Build Coastguard Worker 601*2f2c4c7aSAndroid Build Coastguard Worker def DelAddress(self, address, prefixlen, ifindex): 602*2f2c4c7aSAndroid Build Coastguard Worker self._Address(csocket.AddressVersion(address), 603*2f2c4c7aSAndroid Build Coastguard Worker RTM_DELADDR, address, prefixlen, 0, 0, ifindex) 604*2f2c4c7aSAndroid Build Coastguard Worker 605*2f2c4c7aSAndroid Build Coastguard Worker def GetAddress(self, address, ifindex=0): 606*2f2c4c7aSAndroid Build Coastguard Worker """Returns an ifaddrmsg for the requested address.""" 607*2f2c4c7aSAndroid Build Coastguard Worker if ":" not in address: 608*2f2c4c7aSAndroid Build Coastguard Worker # The address is likely an IPv4 address. RTM_GETADDR without the 609*2f2c4c7aSAndroid Build Coastguard Worker # NLM_F_DUMP flag is not supported by the kernel. We do not currently 610*2f2c4c7aSAndroid Build Coastguard Worker # implement parsing dump results. 611*2f2c4c7aSAndroid Build Coastguard Worker raise NotImplementedError("IPv4 RTM_GETADDR not implemented.") 612*2f2c4c7aSAndroid Build Coastguard Worker self._Address(6, RTM_GETADDR, address, 0, 0, RT_SCOPE_UNIVERSE, ifindex) 613*2f2c4c7aSAndroid Build Coastguard Worker return self._GetMsg(IfAddrMsg) 614*2f2c4c7aSAndroid Build Coastguard Worker 615*2f2c4c7aSAndroid Build Coastguard Worker def _Route(self, version, proto, command, table, dest, prefixlen, nexthop, 616*2f2c4c7aSAndroid Build Coastguard Worker dev, mark, uid, route_type=RTN_UNICAST, priority=None, iif=None): 617*2f2c4c7aSAndroid Build Coastguard Worker """Adds, deletes, or queries a route.""" 618*2f2c4c7aSAndroid Build Coastguard Worker family = self._AddressFamily(version) 619*2f2c4c7aSAndroid Build Coastguard Worker scope = RT_SCOPE_UNIVERSE if nexthop else RT_SCOPE_LINK 620*2f2c4c7aSAndroid Build Coastguard Worker rtmsg = RTMsg((family, prefixlen, 0, 0, RT_TABLE_UNSPEC, 621*2f2c4c7aSAndroid Build Coastguard Worker proto, scope, route_type, 0)).Pack() 622*2f2c4c7aSAndroid Build Coastguard Worker if command == RTM_NEWROUTE and not table: 623*2f2c4c7aSAndroid Build Coastguard Worker # Don't allow setting routes in table 0, since its behaviour is confusing 624*2f2c4c7aSAndroid Build Coastguard Worker # and differs between IPv4 and IPv6. 625*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Cowardly refusing to add a route to table 0") 626*2f2c4c7aSAndroid Build Coastguard Worker if table: 627*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(FRA_TABLE, table) 628*2f2c4c7aSAndroid Build Coastguard Worker if dest != "default": # The default is the default route. 629*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrIPAddress(RTA_DST, family, dest) 630*2f2c4c7aSAndroid Build Coastguard Worker if nexthop: 631*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrIPAddress(RTA_GATEWAY, family, nexthop) 632*2f2c4c7aSAndroid Build Coastguard Worker if dev: 633*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(RTA_OIF, dev) 634*2f2c4c7aSAndroid Build Coastguard Worker if mark is not None: 635*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(RTA_MARK, mark) 636*2f2c4c7aSAndroid Build Coastguard Worker if uid is not None: 637*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(RTA_UID, uid) 638*2f2c4c7aSAndroid Build Coastguard Worker if priority is not None: 639*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(RTA_PRIORITY, priority) 640*2f2c4c7aSAndroid Build Coastguard Worker if iif is not None: 641*2f2c4c7aSAndroid Build Coastguard Worker rtmsg += self._NlAttrU32(RTA_IIF, iif) 642*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(command, rtmsg) 643*2f2c4c7aSAndroid Build Coastguard Worker 644*2f2c4c7aSAndroid Build Coastguard Worker def AddRoute(self, version, table, dest, prefixlen, nexthop, dev): 645*2f2c4c7aSAndroid Build Coastguard Worker self._Route(version, RTPROT_STATIC, RTM_NEWROUTE, table, dest, prefixlen, 646*2f2c4c7aSAndroid Build Coastguard Worker nexthop, dev, None, None) 647*2f2c4c7aSAndroid Build Coastguard Worker 648*2f2c4c7aSAndroid Build Coastguard Worker def DelRoute(self, version, table, dest, prefixlen, nexthop, dev): 649*2f2c4c7aSAndroid Build Coastguard Worker self._Route(version, RTPROT_STATIC, RTM_DELROUTE, table, dest, prefixlen, 650*2f2c4c7aSAndroid Build Coastguard Worker nexthop, dev, None, None) 651*2f2c4c7aSAndroid Build Coastguard Worker 652*2f2c4c7aSAndroid Build Coastguard Worker def GetRoutes(self, dest, oif, mark, uid, iif=None): 653*2f2c4c7aSAndroid Build Coastguard Worker version = csocket.AddressVersion(dest) 654*2f2c4c7aSAndroid Build Coastguard Worker prefixlen = {4: 32, 6: 128}[version] 655*2f2c4c7aSAndroid Build Coastguard Worker self._Route(version, RTPROT_STATIC, RTM_GETROUTE, 0, dest, prefixlen, None, 656*2f2c4c7aSAndroid Build Coastguard Worker oif, mark, uid, iif=iif) 657*2f2c4c7aSAndroid Build Coastguard Worker data = self._Recv() 658*2f2c4c7aSAndroid Build Coastguard Worker # The response will either be an error or a list of routes. 659*2f2c4c7aSAndroid Build Coastguard Worker if netlink.NLMsgHdr(data).type == netlink.NLMSG_ERROR: 660*2f2c4c7aSAndroid Build Coastguard Worker self._ParseAck(data) 661*2f2c4c7aSAndroid Build Coastguard Worker routes = self._GetMsgList(RTMsg, data, False) 662*2f2c4c7aSAndroid Build Coastguard Worker return routes 663*2f2c4c7aSAndroid Build Coastguard Worker 664*2f2c4c7aSAndroid Build Coastguard Worker def DumpRoutes(self, version, ifindex): 665*2f2c4c7aSAndroid Build Coastguard Worker rtmsg = RTMsg(family=self._AddressFamily(version)) 666*2f2c4c7aSAndroid Build Coastguard Worker return [(m, r) for (m, r) in self._Dump(RTM_GETROUTE, rtmsg, RTMsg) 667*2f2c4c7aSAndroid Build Coastguard Worker if r['RTA_TABLE'] == ifindex] 668*2f2c4c7aSAndroid Build Coastguard Worker 669*2f2c4c7aSAndroid Build Coastguard Worker def _Neighbour(self, version, is_add, addr, lladdr, dev, state, flags=0): 670*2f2c4c7aSAndroid Build Coastguard Worker """Adds or deletes a neighbour cache entry.""" 671*2f2c4c7aSAndroid Build Coastguard Worker family = self._AddressFamily(version) 672*2f2c4c7aSAndroid Build Coastguard Worker 673*2f2c4c7aSAndroid Build Coastguard Worker # Convert the link-layer address to a raw byte string. 674*2f2c4c7aSAndroid Build Coastguard Worker if is_add and lladdr: 675*2f2c4c7aSAndroid Build Coastguard Worker lladdr = lladdr.split(":") 676*2f2c4c7aSAndroid Build Coastguard Worker if len(lladdr) != 6 or any (len(b) not in range(1, 3) for b in lladdr): 677*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Invalid lladdr %s" % ":".join(lladdr)) 678*2f2c4c7aSAndroid Build Coastguard Worker lladdr = binascii.unhexlify("".join(lladdr)) 679*2f2c4c7aSAndroid Build Coastguard Worker 680*2f2c4c7aSAndroid Build Coastguard Worker ndmsg = NdMsg((family, dev, state, 0, RTN_UNICAST)).Pack() 681*2f2c4c7aSAndroid Build Coastguard Worker ndmsg += self._NlAttrIPAddress(NDA_DST, family, addr) 682*2f2c4c7aSAndroid Build Coastguard Worker if is_add and lladdr: 683*2f2c4c7aSAndroid Build Coastguard Worker ndmsg += self._NlAttr(NDA_LLADDR, lladdr) 684*2f2c4c7aSAndroid Build Coastguard Worker command = RTM_NEWNEIGH if is_add else RTM_DELNEIGH 685*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(command, ndmsg, flags) 686*2f2c4c7aSAndroid Build Coastguard Worker 687*2f2c4c7aSAndroid Build Coastguard Worker def AddNeighbour(self, version, addr, lladdr, dev): 688*2f2c4c7aSAndroid Build Coastguard Worker self._Neighbour(version, True, addr, lladdr, dev, NUD_PERMANENT) 689*2f2c4c7aSAndroid Build Coastguard Worker 690*2f2c4c7aSAndroid Build Coastguard Worker def DelNeighbour(self, version, addr, lladdr, dev): 691*2f2c4c7aSAndroid Build Coastguard Worker self._Neighbour(version, False, addr, lladdr, dev, 0) 692*2f2c4c7aSAndroid Build Coastguard Worker 693*2f2c4c7aSAndroid Build Coastguard Worker def UpdateNeighbour(self, version, addr, lladdr, dev, state): 694*2f2c4c7aSAndroid Build Coastguard Worker self._Neighbour(version, True, addr, lladdr, dev, state, 695*2f2c4c7aSAndroid Build Coastguard Worker flags=netlink.NLM_F_REPLACE) 696*2f2c4c7aSAndroid Build Coastguard Worker 697*2f2c4c7aSAndroid Build Coastguard Worker def DumpNeighbours(self, version, ifindex): 698*2f2c4c7aSAndroid Build Coastguard Worker ndmsg = NdMsg((self._AddressFamily(version), 0, 0, 0, 0)) 699*2f2c4c7aSAndroid Build Coastguard Worker attrs = self._NlAttrU32(NDA_IFINDEX, ifindex) if ifindex else b"" 700*2f2c4c7aSAndroid Build Coastguard Worker return self._Dump(RTM_GETNEIGH, ndmsg, NdMsg, attrs) 701*2f2c4c7aSAndroid Build Coastguard Worker 702*2f2c4c7aSAndroid Build Coastguard Worker def ParseNeighbourMessage(self, msg): 703*2f2c4c7aSAndroid Build Coastguard Worker msg, _ = self._ParseNLMsg(msg, NdMsg) 704*2f2c4c7aSAndroid Build Coastguard Worker return msg 705*2f2c4c7aSAndroid Build Coastguard Worker 706*2f2c4c7aSAndroid Build Coastguard Worker def DeleteLink(self, dev_name): 707*2f2c4c7aSAndroid Build Coastguard Worker ifinfo = IfinfoMsg().Pack() 708*2f2c4c7aSAndroid Build Coastguard Worker ifinfo += self._NlAttrStr(IFLA_IFNAME, dev_name) 709*2f2c4c7aSAndroid Build Coastguard Worker return self._SendNlRequest(RTM_DELLINK, ifinfo) 710*2f2c4c7aSAndroid Build Coastguard Worker 711*2f2c4c7aSAndroid Build Coastguard Worker def GetIfinfo(self, dev_name): 712*2f2c4c7aSAndroid Build Coastguard Worker """Fetches information about the specified interface. 713*2f2c4c7aSAndroid Build Coastguard Worker 714*2f2c4c7aSAndroid Build Coastguard Worker Args: 715*2f2c4c7aSAndroid Build Coastguard Worker dev_name: A string, the name of the interface. 716*2f2c4c7aSAndroid Build Coastguard Worker 717*2f2c4c7aSAndroid Build Coastguard Worker Returns: 718*2f2c4c7aSAndroid Build Coastguard Worker A tuple containing an IfinfoMsg struct and raw, undecoded attributes. 719*2f2c4c7aSAndroid Build Coastguard Worker """ 720*2f2c4c7aSAndroid Build Coastguard Worker ifinfo = IfinfoMsg().Pack() 721*2f2c4c7aSAndroid Build Coastguard Worker ifinfo += self._NlAttrStr(IFLA_IFNAME, dev_name) 722*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(RTM_GETLINK, ifinfo) 723*2f2c4c7aSAndroid Build Coastguard Worker hdr, data = cstruct.Read(self._Recv(), netlink.NLMsgHdr) 724*2f2c4c7aSAndroid Build Coastguard Worker if hdr.type == RTM_NEWLINK: 725*2f2c4c7aSAndroid Build Coastguard Worker return cstruct.Read(data, IfinfoMsg) 726*2f2c4c7aSAndroid Build Coastguard Worker elif hdr.type == netlink.NLMSG_ERROR: 727*2f2c4c7aSAndroid Build Coastguard Worker error = -netlink.NLMsgErr(data).error 728*2f2c4c7aSAndroid Build Coastguard Worker raise IOError(error, os.strerror(error)) 729*2f2c4c7aSAndroid Build Coastguard Worker else: 730*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Unknown Netlink Message Type %d" % hdr.type) 731*2f2c4c7aSAndroid Build Coastguard Worker 732*2f2c4c7aSAndroid Build Coastguard Worker def GetIfIndex(self, dev_name): 733*2f2c4c7aSAndroid Build Coastguard Worker """Returns the interface index for the specified interface.""" 734*2f2c4c7aSAndroid Build Coastguard Worker ifinfo, _ = self.GetIfinfo(dev_name) 735*2f2c4c7aSAndroid Build Coastguard Worker return ifinfo.index 736*2f2c4c7aSAndroid Build Coastguard Worker 737*2f2c4c7aSAndroid Build Coastguard Worker def GetIfaceStats(self, dev_name): 738*2f2c4c7aSAndroid Build Coastguard Worker """Returns an RtnlLinkStats64 stats object for the specified interface.""" 739*2f2c4c7aSAndroid Build Coastguard Worker _, attrs = self.GetIfinfo(dev_name) 740*2f2c4c7aSAndroid Build Coastguard Worker attrs = self._ParseAttributes(RTM_NEWLINK, IfinfoMsg, attrs, []) 741*2f2c4c7aSAndroid Build Coastguard Worker return attrs["IFLA_STATS64"] 742*2f2c4c7aSAndroid Build Coastguard Worker 743*2f2c4c7aSAndroid Build Coastguard Worker def GetIfinfoData(self, dev_name): 744*2f2c4c7aSAndroid Build Coastguard Worker """Returns an IFLA_INFO_DATA dict object for the specified interface.""" 745*2f2c4c7aSAndroid Build Coastguard Worker _, attrs = self.GetIfinfo(dev_name) 746*2f2c4c7aSAndroid Build Coastguard Worker attrs = self._ParseAttributes(RTM_NEWLINK, IfinfoMsg, attrs, []) 747*2f2c4c7aSAndroid Build Coastguard Worker return attrs["IFLA_LINKINFO"]["IFLA_INFO_DATA"] 748*2f2c4c7aSAndroid Build Coastguard Worker 749*2f2c4c7aSAndroid Build Coastguard Worker def GetRxTxPackets(self, dev_name): 750*2f2c4c7aSAndroid Build Coastguard Worker stats = self.GetIfaceStats(dev_name) 751*2f2c4c7aSAndroid Build Coastguard Worker return stats.rx_packets, stats.tx_packets 752*2f2c4c7aSAndroid Build Coastguard Worker 753*2f2c4c7aSAndroid Build Coastguard Worker def GetIflaAfSpecificData(self, dev_name, family): 754*2f2c4c7aSAndroid Build Coastguard Worker _, attrs = self.GetIfinfo(dev_name) 755*2f2c4c7aSAndroid Build Coastguard Worker attrs = self._ParseAttributes(RTM_NEWLINK, IfinfoMsg, attrs, []) 756*2f2c4c7aSAndroid Build Coastguard Worker if family == AF_INET: 757*2f2c4c7aSAndroid Build Coastguard Worker attrname = "IFLA_AF_SPEC_AF_INET" 758*2f2c4c7aSAndroid Build Coastguard Worker elif family == AF_INET6: 759*2f2c4c7aSAndroid Build Coastguard Worker attrname = "IFLA_AF_SPEC_AF_INET6" 760*2f2c4c7aSAndroid Build Coastguard Worker else: 761*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Unsupported address family %d" % family) 762*2f2c4c7aSAndroid Build Coastguard Worker return attrs["IFLA_AF_SPEC"][attrname] 763*2f2c4c7aSAndroid Build Coastguard Worker 764*2f2c4c7aSAndroid Build Coastguard Worker def CreateVirtualTunnelInterface(self, dev_name, local_addr, remote_addr, 765*2f2c4c7aSAndroid Build Coastguard Worker i_key=None, o_key=None, is_update=False): 766*2f2c4c7aSAndroid Build Coastguard Worker """ 767*2f2c4c7aSAndroid Build Coastguard Worker Create a Virtual Tunnel Interface that provides a proxy interface 768*2f2c4c7aSAndroid Build Coastguard Worker for IPsec tunnels. 769*2f2c4c7aSAndroid Build Coastguard Worker 770*2f2c4c7aSAndroid Build Coastguard Worker The VTI Newlink structure is a series of nested netlink 771*2f2c4c7aSAndroid Build Coastguard Worker attributes following a mostly-ignored 'struct ifinfomsg': 772*2f2c4c7aSAndroid Build Coastguard Worker 773*2f2c4c7aSAndroid Build Coastguard Worker NLMSGHDR (type=RTM_NEWLINK) 774*2f2c4c7aSAndroid Build Coastguard Worker | 775*2f2c4c7aSAndroid Build Coastguard Worker |-{IfinfoMsg} 776*2f2c4c7aSAndroid Build Coastguard Worker | 777*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_IFNAME = <user-provided ifname> 778*2f2c4c7aSAndroid Build Coastguard Worker | 779*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_LINKINFO 780*2f2c4c7aSAndroid Build Coastguard Worker | 781*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_INFO_KIND = "vti" 782*2f2c4c7aSAndroid Build Coastguard Worker | 783*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_INFO_DATA 784*2f2c4c7aSAndroid Build Coastguard Worker | 785*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_VTI_LOCAL = <local addr> 786*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_VTI_REMOTE = <remote addr> 787*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_VTI_LINK = ???? 788*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_VTI_OKEY = [outbound mark] 789*2f2c4c7aSAndroid Build Coastguard Worker |-IFLA_VTI_IKEY = [inbound mark] 790*2f2c4c7aSAndroid Build Coastguard Worker """ 791*2f2c4c7aSAndroid Build Coastguard Worker family = AF_INET6 if ":" in remote_addr else AF_INET 792*2f2c4c7aSAndroid Build Coastguard Worker 793*2f2c4c7aSAndroid Build Coastguard Worker ifinfo = IfinfoMsg().Pack() 794*2f2c4c7aSAndroid Build Coastguard Worker ifinfo += self._NlAttrStr(IFLA_IFNAME, dev_name) 795*2f2c4c7aSAndroid Build Coastguard Worker 796*2f2c4c7aSAndroid Build Coastguard Worker linkinfo = self._NlAttrStr(IFLA_INFO_KIND, 797*2f2c4c7aSAndroid Build Coastguard Worker {AF_INET6: "vti6", AF_INET: "vti"}[family]) 798*2f2c4c7aSAndroid Build Coastguard Worker 799*2f2c4c7aSAndroid Build Coastguard Worker ifdata = self._NlAttrIPAddress(IFLA_VTI_LOCAL, family, local_addr) 800*2f2c4c7aSAndroid Build Coastguard Worker ifdata += self._NlAttrIPAddress(IFLA_VTI_REMOTE, family, 801*2f2c4c7aSAndroid Build Coastguard Worker remote_addr) 802*2f2c4c7aSAndroid Build Coastguard Worker if i_key is not None: 803*2f2c4c7aSAndroid Build Coastguard Worker ifdata += self._NlAttrU32(IFLA_VTI_IKEY, socket.htonl(i_key)) 804*2f2c4c7aSAndroid Build Coastguard Worker if o_key is not None: 805*2f2c4c7aSAndroid Build Coastguard Worker ifdata += self._NlAttrU32(IFLA_VTI_OKEY, socket.htonl(o_key)) 806*2f2c4c7aSAndroid Build Coastguard Worker linkinfo += self._NlAttr(IFLA_INFO_DATA, ifdata) 807*2f2c4c7aSAndroid Build Coastguard Worker 808*2f2c4c7aSAndroid Build Coastguard Worker ifinfo += self._NlAttr(IFLA_LINKINFO, linkinfo) 809*2f2c4c7aSAndroid Build Coastguard Worker 810*2f2c4c7aSAndroid Build Coastguard Worker # Always pass CREATE to prevent _SendNlRequest() from incorrectly 811*2f2c4c7aSAndroid Build Coastguard Worker # guessing the flags. 812*2f2c4c7aSAndroid Build Coastguard Worker flags = netlink.NLM_F_CREATE 813*2f2c4c7aSAndroid Build Coastguard Worker if not is_update: 814*2f2c4c7aSAndroid Build Coastguard Worker flags |= netlink.NLM_F_EXCL 815*2f2c4c7aSAndroid Build Coastguard Worker return self._SendNlRequest(RTM_NEWLINK, ifinfo, flags) 816*2f2c4c7aSAndroid Build Coastguard Worker 817*2f2c4c7aSAndroid Build Coastguard Worker def CreateXfrmInterface(self, dev_name, xfrm_if_id, underlying_ifindex): 818*2f2c4c7aSAndroid Build Coastguard Worker """Creates an XFRM interface with the specified parameters.""" 819*2f2c4c7aSAndroid Build Coastguard Worker # The netlink attribute structure is essentially identical to the one 820*2f2c4c7aSAndroid Build Coastguard Worker # for VTI above (q.v). 821*2f2c4c7aSAndroid Build Coastguard Worker ifdata = self._NlAttrU32(IFLA_XFRM_LINK, underlying_ifindex) 822*2f2c4c7aSAndroid Build Coastguard Worker ifdata += self._NlAttrU32(IFLA_XFRM_IF_ID, xfrm_if_id) 823*2f2c4c7aSAndroid Build Coastguard Worker 824*2f2c4c7aSAndroid Build Coastguard Worker linkinfo = self._NlAttrStr(IFLA_INFO_KIND, "xfrm") 825*2f2c4c7aSAndroid Build Coastguard Worker linkinfo += self._NlAttr(IFLA_INFO_DATA, ifdata) 826*2f2c4c7aSAndroid Build Coastguard Worker 827*2f2c4c7aSAndroid Build Coastguard Worker msg = IfinfoMsg().Pack() 828*2f2c4c7aSAndroid Build Coastguard Worker msg += self._NlAttrStr(IFLA_IFNAME, dev_name) 829*2f2c4c7aSAndroid Build Coastguard Worker msg += self._NlAttr(IFLA_LINKINFO, linkinfo) 830*2f2c4c7aSAndroid Build Coastguard Worker 831*2f2c4c7aSAndroid Build Coastguard Worker return self._SendNlRequest(RTM_NEWLINK, msg) 832*2f2c4c7aSAndroid Build Coastguard Worker 833*2f2c4c7aSAndroid Build Coastguard Worker 834*2f2c4c7aSAndroid Build Coastguard Workerif __name__ == "__main__": 835*2f2c4c7aSAndroid Build Coastguard Worker iproute = IPRoute() 836*2f2c4c7aSAndroid Build Coastguard Worker iproute.DEBUG = True 837*2f2c4c7aSAndroid Build Coastguard Worker iproute.DumpRules(6) 838*2f2c4c7aSAndroid Build Coastguard Worker iproute.DumpLinks() 839*2f2c4c7aSAndroid Build Coastguard Worker print(iproute.GetRoutes("2001:4860:4860::8888", 0, 0, None)) 840