Network Interface Monitoring Tool - Comprehensive Guide

## 📋 Overview

This tool provides comprehensive network interface monitoring and analysis using Linux RTNetlink and Generic Netlink protocols. It leverages CFFI (C Foreign Function Interface) to directly interface with kernel networking subsystems, offering detailed insights into network configurations, addresses, and specialized interface types.

Key Capabilities:

- Real-time network interface status monitoring
- Complete IP address information including IPv6 DAD states
- Bridge configuration and STP details
- WireGuard VPN interface monitoring via Generic Netlink
- VLAN, veth, and GENEVE virtual interface support
- Hardware offload capabilities detection
- DPLL (Digital Phase-Locked Loop) pin synchronization info

### Why This Tool?

Traditional tools like `ip` and `ifconfig` provide basic interface information, but this tool offers:

- Programmatic access: JSON output for automation and integration
- Deep inspection: Access to all kernel-provided interface attributes
- WireGuard insights: Detailed peer information without external tools
- Address readiness: IPv6 DAD state and address operational status
- Bridge topology: Complete STP and port state information

## 💾 Installation

### System Requirements

Component | Version | Status
--- | --- | ---
Python | 3.8 or higher | Required
Linux Kernel | 2.6+ (5.0+ recommended) | Required
CFFI | 1.0.0 or higher | Required
setuptools | Latest | Required (Python 3.12+)
Root/sudo access | - | Required

### Quick Installation

$ pip install cffi setuptools

Or for system-wide installation:

$ sudo pip3 install cffi setuptools

### Verification

Verify your Python version:

    $ python3 --version
    Python 3.8.0 (or higher)

Check if CFFI is installed:

    $ python3 -c "import cffi; print(cffi.__version__)"
    1.15.0

⚠️ Python 3.12+ Notice:
Python 3.12 and higher require `setuptools` to be explicitly installed for CFFI to work properly. The script will check for this and provide a clear error message if it's missing.

### File Setup

1. Save the script as `device_info.py`
2. Make it executable:
   $ chmod +x device_info.py
3. Verify it runs:
   $ sudo python3 device_info.py --help

## 🚀 Usage

### Basic Usage Patterns

#### 1. Full JSON Output (Default)

Get complete interface information in JSON format:

    $ sudo python3 device_info.py

This outputs a comprehensive JSON structure containing all detected interfaces, their configurations, addresses, and special attributes.

#### 2. Extended Interface Details

Show human-readable interface information with extensive details:

    $ sudo python3 device_info.py --extended

Output includes:

- Interface name, index, and type
- MAC address and MTU
- Operational and administrative state
- Carrier status and change counts
- Hardware offload capabilities
- Bridge, VLAN, or WireGuard specific configuration

#### 3. Detailed Address Information

Focus on IP address configuration and readiness:

    $ sudo python3 device_info.py --addresses

Shows address-specific details:

- Readiness status (✓=ready, ⋯=pending, ✗=failed, ○=down)
- IPv4 and IPv6 addresses with prefix lengths
- Network, netmask, and broadcast information
- Address scope and flags
- IPv6 DAD (Duplicate Address Detection) state
- Address lifetime information
- Configuration protocol (manual, SLAAC, kernel)

#### 4. WireGuard Interfaces Only

Filter output to show only WireGuard interfaces with peer details:

    $ sudo python3 device_info.py --wireguard

Displays:

- WireGuard interface configuration
- Listen port and fwmark settings
- Public key information
- Peer count and individual peer details
- Allowed IPs per peer
- Latest handshake times
- Transfer statistics per peer

#### 5. Summary View

Condensed view of special interfaces (bridges, VLANs, WireGuard, veth):

    $ sudo python3 device_info.py --summary

💡 Pro Tip: Pipe JSON output to `jq` for advanced filtering:

    $ sudo python3 device_info.py | jq '.eth0.addresses'

### Common Use Cases

#### Monitoring IPv6 Address Configuration

    # Check if IPv6 addresses have completed DAD
    $ sudo python3 device_info.py --addresses | grep -A 10 "ipv6"

    # Get readiness status of all addresses
    $ sudo python3 device_info.py | jq '.[] | .addresses[] | {addr: .address, ready: .readiness}'

#### Bridge Management

    # View all bridge configurations
    $ sudo python3 device_info.py --summary | grep -i bridge

    # Get detailed bridge STP status
    $ sudo python3 device_info.py --extended | grep -A 20 "Bridge Master"

#### WireGuard Monitoring

    # Check WireGuard peer status
    $ sudo python3 device_info.py --wireguard

    # Monitor peer handshakes
    $ sudo python3 device_info.py | jq '.wg0.wireguard.peers[] | {endpoint: .endpoint, handshake: .latest_handshake_str}'

#### Automated Monitoring

    #!/bin/bash
    # Monitor for interface changes every 5 seconds

    while true; do
        sudo python3 device_info.py > /tmp/interfaces_new.json
        if ! diff -q /tmp/interfaces_old.json /tmp/interfaces_new.json &>/dev/null; then
            echo "$(date): Interface configuration changed"
            diff /tmp/interfaces_old.json /tmp/interfaces_new.json
        fi
        mv /tmp/interfaces_new.json /tmp/interfaces_old.json
        sleep 5
    done

## ✨ Features

#### 🔗 RTNetlink Integration

Direct kernel interface using RTM_GETLINK and RTM_GETADDR messages for low-level network configuration access.

#### 🔐 WireGuard Support

Generic Netlink integration provides detailed WireGuard interface information including peer configurations and statistics.

#### 🌉 Bridge Monitoring

Complete bridge configuration including STP state, VLAN filtering, multicast snooping, and port attributes.

#### 📡 Address Readiness

Smart address state computation considering IPv6 DAD, interface operational state, and address flags.

#### ⚡ Hardware Offload

Detection and reporting of GSO, GRO, TSO capabilities and limits for network performance tuning.

#### 🏷️ VLAN & Virtual Interfaces

Support for VLAN, veth, GENEVE, and other virtual interface types with detailed configuration.

#### 🎯 DPLL Synchronization

Hardware time synchronization information including pin types, states, and frequency adjustments.

#### 📊 Comprehensive Statistics

Interface counters, carrier changes, multicast groups, and historical event tracking.

### Supported Interface Types

Interface Type | Support Level | Key Features
--- | --- | ---
Physical (eth*, enp*) | Full | Hardware offload, carrier detection, statistics
Bridge (br*) | Full | STP, VLAN filtering, multicast, port configuration
WireGuard (wg*) | Full | Peers, allowed IPs, handshakes, transfer stats
VLAN (*.*, vlan*) | Full | VLAN ID, protocol, parent interface
veth | Full | Peer interface detection
GENEVE | Full | VNI, remote endpoint, port configuration
Loopback (lo) | Full | Standard interface attributes
Bonding (bond*) | Partial | Basic interface info, slave detection

### Comprehensive Attribute Decoding

The tool decodes 64+ IFLA attributes and 11+ IFA attributes, including:

#### IFLA (Interface Link Attributes)

- Basic: IFNAME, MTU, ADDRESS, BROADCAST, OPERSTATE, TXQLEN
- Relationships: MASTER, LINK, NET_NS_PID, PARENT_DEV_NAME
- Offload: GSO_MAX_SIZE, TSO_MAX_SIZE, GRO_MAX_SIZE, XDP
- Statistics: STATS64, CARRIER_CHANGES, CARRIER_UP_COUNT
- Advanced: LINKINFO, AF_SPEC, PROTINFO, VFINFO_LIST

#### IFA (Interface Address Attributes)

- Addresses: ADDRESS, LOCAL, BROADCAST, ANYCAST
- Properties: FLAGS, LABEL, CACHEINFO, RT_PRIORITY
- Protocol: PROTO (configuration source)

## 🏗️ Architecture

### System Design

The tool uses a layered architecture to interact with the Linux kernel:

    ┌─────────────────────────────────────────┐
    │          Python Application             │
    │  (Argument Parsing, JSON Output, etc.)  │
    └────────────────┬────────────────────────┘
                     │
                     ▼
    ┌─────────────────────────────────────────┐
    │          CFFI Interface Layer           │
    │     (Python ↔ C Type Conversion)        │
    └────────────────┬────────────────────────┘
                     │
                     ▼
    ┌─────────────────────────────────────────┐
    │          C Library Functions            │
    │  - create_rtnetlink_socket()            │
    │  - query_links()                        │
    │  - query_addresses()                    │
    │  - query_wireguard_info()               │
    │  - parse_ifla_attributes()              │
    └────────────────┬────────────────────────┘
                     │
                     ▼
    ┌─────────────────────────────────────────┐
    │         Linux Kernel Netlink            │
    │  RTNetlink  │  Generic Netlink          │
    │  (RTM_*)    │  (GENL_*)                 │
    └─────────────────────────────────────────┘
                     │
                     ▼
    ┌─────────────────────────────────────────┐
    │         Network Subsystem               │
    │  Interfaces, Addresses, Routing, etc.   │
    └─────────────────────────────────────────┘

### Key Components

#### 1. C Library Integration (Lines 57-5100)

Comprehensive C code embedded in Python that handles:

- Socket Management: Creates and manages Netlink sockets
- Message Construction: Builds RTNetlink and Generic Netlink messages
- Response Parsing: Decodes kernel responses with proper attribute handling
- Type-Specific Decoders: Specialized parsers for bridges, WireGuard, VLAN, etc.

#### 2. CFFI Builder (Lines 5102-5150)

Dynamic compilation of C code with Python binding generation:

    ffi = FFI()
    ffi.cdef("""
        typedef struct { ... } response_buffer_t;
        int create_rtnetlink_socket(void);
        // ... function declarations
    """)

    # Compile C code at runtime
    lib = ffi.verify(C_SOURCE, libraries=[], extra_compile_args=['-O2'])

#### 3. Python Interface Layer (Lines 5150-5300)

High-level functions that:

- Call C functions through CFFI
- Parse JSON responses from C code
- Apply additional Python-side logic
- Compute derived attributes (readiness, network info)

#### 4. Output Formatters (Lines 5400-5750)

Multiple presentation modes:

- JSON serialization for programmatic access
- Human-readable extended format
- Address-focused detailed view
- Summary reports for special interfaces

### Data Flow

1. Initialization: CFFI compiles C code and creates Python bindings
2. Socket Creation: Opens Netlink socket with appropriate protocols
3. Query Dispatch: Sends RTM_GETLINK and RTM_GETADDR requests
4. Kernel Response: Receives and buffers Netlink messages
5. Attribute Parsing: Decodes nested TLV (Type-Length-Value) structures
6. JSON Assembly: C code builds JSON strings for easy Python consumption
7. Python Processing: Enriches data with computed fields
8. Output Generation: Formats according to user-selected mode

### Memory Management

Safety Features:

- Response buffers automatically grow to accommodate large messages
- Buffer capacity is tracked and never exceeded
- All C-allocated memory is properly freed
- CFFI handles Python ↔ C memory lifetime correctly

### Attribute Decoding Strategy

The tool employs a comprehensive attribute decoding system:

1. Known Attributes: Explicitly decoded with proper type handling
2. Nested Attributes: Recursively parsed (e.g., IFLA_LINKINFO, IFLA_AF_SPEC)
3. Binary Data: Base64-encoded or hex-formatted for safe transport
4. Unknown Attributes: Recorded but not fully decoded
5. Type-Specific: Bridge, WireGuard, VLAN use specialized decoders

## 🔧 Maintenance

### Regular Maintenance Tasks

#### 1. Update Dependency Versions

    # Update CFFI
    $ pip install --upgrade cffi

    # Update setuptools (Python 3.12+)
    $ pip install --upgrade setuptools

    # Verify versions
    $ pip list | grep -E "(cffi|setuptools)"

#### 2. Check Kernel Compatibility

When upgrading your kernel, verify that new attributes are properly supported:

    # Check kernel version
    $ uname -r

    # Test the script
    $ sudo python3 device_info.py --extended

    # Look for "unknown_attrs" in output
    $ sudo python3 device_info.py | jq '.[] | select(.unknown_attrs != null)'

#### 3. Monitor for Deprecation Warnings

    # Run with warnings enabled
    $ python3 -W all device_info.py > /dev/null

### Extending the Tool

#### Adding New IFLA Attributes

When new kernel versions introduce new IFLA_* constants:

1. Find the constant definition in `/usr/include/linux/if_link.h`
2. Add it to the C code's IFLA_ATTR_NAMES array (around line 300)
3. Implement decoding logic in `parse_ifla_attributes()` (around line 1500)
4. Update the Python post-processing if needed (around line 5200)
5. Document it in the reference guide

Example for a hypothetical IFLA_NEW_FEATURE (65):

    // In C_SOURCE - Add to IFLA_ATTR_NAMES
    [65] = "IFLA_NEW_FEATURE",

    // In parse_ifla_attributes() - Add decode case
    case 65:  // IFLA_NEW_FEATURE
        if (rta_len >= sizeof(uint32_t)) {
            uint32_t value = *(uint32_t*)RTA_DATA(rta);
            append_comma(info_json);
            append_to_buffer(info_json, "\"new_feature\": %u", value);
        }
        break;

#### Adding New Interface Types

To support a new interface kind (e.g., "newtype"):

1. Add kind detection in IFLA_LINKINFO parsing (around line 2000)
2. Create a type-specific attribute parser
3. Add Python-side processing if needed
4. Update output formatters

#### Debugging New Features

Enable verbose debugging during development:

    # Add debug output in C code (temporary)
    fprintf(stderr, "DEBUG: Processing attribute type %d, len %d\n",
            rta_type, rta_len);

    # Or use Python logging
    import logging
    logging.basicConfig(level=logging.DEBUG)
    logger = logging.getLogger(__name__)
    logger.debug(f"Interface: {if_name}, Data: {data}")

### Code Organization Best Practices

⚠️ Important Guidelines:

- Keep C and Python synchronized: Struct definitions must match between C code and CFFI cdef
- Handle padding: Use `__attribute__((packed))` for structs read directly from kernel
- Version guards: Check kernel version before using newer attributes
- Error handling: Always check return values from C functions
- Memory safety: Free allocated memory before returning from C functions

### Testing Strategy

#### Unit Testing

Create test scenarios for different interface configurations:

    #!/bin/bash
    # test_script.sh - Comprehensive testing

    # Test 1: Basic execution
    echo "Test 1: Basic execution"
    sudo python3 device_info.py > /tmp/test1.json || exit 1

    # Test 2: Validate JSON
    echo "Test 2: JSON validation"
    jq empty /tmp/test1.json || exit 1

    # Test 3: Check for required fields
    echo "Test 3: Required fields"
    jq -e '.lo.ifname == "lo"' /tmp/test1.json || exit 1

    # Test 4: All output modes
    for mode in "--extended" "--addresses" "--summary"; do
        echo "Test 4: Mode $mode"
        sudo python3 device_info.py $mode > /dev/null || exit 1
    done

    echo "All tests passed!"

#### Integration Testing

Test with various interface configurations:

    # Create test VLAN
    sudo ip link add link eth0 name eth0.100 type vlan id 100
    sudo python3 device_info.py | jq '.["eth0.100"]'
    sudo ip link del eth0.100

    # Create test bridge
    sudo ip link add br0 type bridge
    sudo python3 device_info.py --summary | grep br0
    sudo ip link del br0

    # Create veth pair
    sudo ip link add veth0 type veth peer name veth1
    sudo python3 device_info.py | jq '.veth0.veth'
    sudo ip link del veth0

### Performance Monitoring

Track execution time and resource usage:

    # Time the execution
    $ time sudo python3 device_info.py > /dev/null

    # Monitor memory usage
    $ /usr/bin/time -v sudo python3 device_info.py > /dev/null 2>&1 | \
      grep -E "(Maximum resident set size|User time|System time)"

    # Profile the script
    $ sudo python3 -m cProfile -o profile.stats device_info.py
    $ python3 -c "import pstats; p = pstats.Stats('profile.stats'); p.sort_stats('cumulative').print_stats(20)"

### Documentation Updates

When modifying the tool, update:

- Docstring at the top of the file
- This guide (HTML)
- IFLA_IFA_REFERENCE.md for new attributes
- Usage examples for new features
- Change log with version notes

## 🔍 Troubleshooting

### Common Issues and Solutions

#### Issue: Permission Denied

Error: `OSError: [Errno 13] Permission denied`

Solution: The script requires root access to create Netlink sockets:

    $ sudo python3 device_info.py

Or add CAP_NET_ADMIN capability:

    $ sudo setcap cap_net_admin+ep $(which python3)
    $ python3 device_info.py  # No sudo needed

#### Issue: CFFI Import Error

Error: `ModuleNotFoundError: No module named 'cffi'`

Solution: Install CFFI:

    $ pip install cffi
    # Or system-wide
    $ sudo pip3 install cffi

#### Issue: Python 3.12+ Setuptools Error

Error: `RuntimeError: Python 3.12+ requires setuptools for CFFI`

Solution: Install setuptools:

    $ pip install setuptools

#### Issue: Old Python Version

Error: `RuntimeError: Python 3.8 or higher is required`

Solution: Upgrade Python or use a virtual environment:

    # Check your Python version
    $ python3 --version

    # Use a newer Python if available
    $ python3.10 device_info.py

    # Or install a newer Python version
    $ sudo apt-get install python3.10  # Debian/Ubuntu
    $ sudo yum install python310       # RHEL/CentOS

#### Issue: Compilation Errors

Error: `CompileError: command 'gcc' failed`

Solution: Install build essentials and kernel headers:

    # Debian/Ubuntu
    $ sudo apt-get install build-essential linux-headers-$(uname -r)

    # RHEL/CentOS
    $ sudo yum groupinstall "Development Tools"
    $ sudo yum install kernel-devel

    # Verify gcc is installed
    $ gcc --version

#### Issue: Empty or Incomplete Output

Possible causes and solutions:

- Netlink socket timeout: Increase timeout in C code (SOCKET_TIMEOUT)
- Buffer overflow: Increase INITIAL_BUFFER_SIZE or MAX_BUFFER_SIZE
- Kernel version too old: Some attributes require newer kernels
- Namespace isolation: Run in appropriate network namespace

    # Check for kernel version requirements
    $ uname -r
    $ grep -A 5 "IFLA_.*Min Kernel" IFLA_IFA_REFERENCE.md

    # Run in specific namespace
    $ sudo ip netns exec myns python3 device_info.py

#### Issue: WireGuard Information Not Showing

Checklist:

1. Verify WireGuard module is loaded: `lsmod | grep wireguard`
2. Check if WireGuard interfaces exist: `wg show`
3. Ensure Generic Netlink family is registered: `genl-ctrl-list | grep wireguard`
4. Use `--wireguard` flag to isolate WireGuard output

    # Load WireGuard module
    $ sudo modprobe wireguard

    # Create test interface
    $ sudo ip link add dev wg0 type wireguard

    # Run script
    $ sudo python3 device_info.py --wireguard

#### Issue: Unknown Attributes Appearing

If you see `unknown_attrs` in the output, it means the kernel is providing attributes that aren't decoded by the script.

Investigation steps:

1. Note the attribute numbers
2. Check `/usr/include/linux/if_link.h` for the constant definition
3. Add the attribute to IFLA_ATTR_NAMES in the C code
4. Implement proper decoding

    # Find attribute definition
    $ grep "IFLA_.*=" /usr/include/linux/if_link.h | grep -E "\s+$(unknown_attr_num)\b"

#### Issue: CFFI Struct Padding Errors

If you encounter alignment or padding issues with C structs:

Solution: Add `__attribute__((packed))` to struct definitions, especially for:

- Structs read directly from kernel buffers
- Netlink message headers
- Attribute structures

    // Correct struct definition
    typedef struct __attribute__((packed)) {
        uint16_t rta_len;
        uint16_t rta_type;
    } rtattr_t;

### Debugging Techniques

#### Enable Verbose Output

Modify the C code temporarily to add debug prints:

    // Add at the beginning of problematic function
    #define DEBUG 1
    #ifdef DEBUG
    fprintf(stderr, "DEBUG: Entering function with param=%d\n", param);
    #endif

#### Capture Raw Netlink Messages

Use `strace` to see raw Netlink communication:

    $ sudo strace -e trace=sendto,recvfrom python3 device_info.py 2>&1 | \
      grep -A 5 "sendto.*netlink"

#### Compare with ip Command

Verify output against standard tools:

    # Compare interface list
    $ ip -j link show | jq -r '.[].ifname' | sort > /tmp/ip_output.txt
    $ sudo python3 device_info.py | jq -r 'keys[]' | sort > /tmp/script_output.txt
    $ diff /tmp/ip_output.txt /tmp/script_output.txt

    # Compare addresses
    $ ip -j addr show dev eth0 | jq '.[] | .addr_info'
    $ sudo python3 device_info.py | jq '.eth0.addresses'

### Getting Help

If you encounter issues not covered here:

1. Check kernel logs: `sudo dmesg | tail -50`
2. Verify system requirements are met
3. Test with minimal configuration (only loopback interface)
4. Check for conflicting network management tools
5. Review recent kernel or distribution updates

## 📚 API Reference

Complete reference for IFLA and IFA constants used in Linux RTNetlink.

### IFLA Constants (Interface Link Attributes)

These constants are defined in `<linux/if_link.h>` and used for querying/configuring network interface properties.

#### Basic Interface Properties (0-10)

Constant | Value | Description
--- | --- | ---
IFLA_UNSPEC | 0 | Unspecified/invalid attribute
IFLA_ADDRESS | 1 | Hardware (MAC) address
IFLA_BROADCAST | 2 | Hardware broadcast address
IFLA_IFNAME | 3 | Interface name (string)
IFLA_MTU | 4 | Maximum Transmission Unit
IFLA_LINK | 5 | Link to parent device (for VLANs, etc.)
IFLA_QDISC | 6 | Queueing discipline name
IFLA_STATS | 7 | Interface statistics (legacy, 32-bit)
IFLA_MASTER | 10 | Master device for bonding/bridging

#### Operational State and Configuration (11-20)

Constant | Value | Description
--- | --- | ---
IFLA_TXQLEN | 13 | Transmit queue length
IFLA_OPERSTATE | 16 | Operational state (up/down/dormant)
IFLA_LINKMODE | 17 | Link mode (default/dormant)
IFLA_LINKINFO | 18 | Link type specific info (nested)
IFLA_IFALIAS | 20 | Interface alias (description)

#### Statistics and Monitoring (21-35)

Constant | Value | Description
--- | --- | ---
IFLA_STATS64 | 23 | Interface statistics (64-bit, preferred)
IFLA_AF_SPEC | 26 | Address family specific attributes
IFLA_PROMISCUITY | 30 | Promiscuity count
IFLA_CARRIER | 33 | Physical carrier status
IFLA_CARRIER_CHANGES | 35 | Number of carrier changes

#### Hardware Offload Properties (40-43)

Constant | Value | Description
--- | --- | ---
IFLA_GSO_MAX_SEGS | 40 | GSO max segments
IFLA_GSO_MAX_SIZE | 41 | Generic Segmentation Offload max size
IFLA_XDP | 43 | eXpress Data Path (XDP) configuration

#### Carrier Event Tracking (47-49)

Constant | Value | Description
--- | --- | ---
IFLA_CARRIER_UP_COUNT | 47 | Carrier up event count
IFLA_CARRIER_DOWN_COUNT | 48 | Carrier down event count
IFLA_NEW_IFINDEX | 49 | New interface index

#### Recent Additions (52-64) - Kernel 5.0+

Constant | Value | Min Kernel | Description
--- | --- | --- | ---
IFLA_ALT_IFNAME | 53 | 5.5 | Alternative interface names
IFLA_PERM_ADDRESS | 54 | 5.6 | Permanent hardware address
IFLA_PARENT_DEV_NAME | 56 | 5.10 | Parent device name
IFLA_GRO_MAX_SIZE | 58 | 5.15 | GRO max size
IFLA_TSO_MAX_SIZE | 59 | 5.18 | TSO max size
IFLA_TSO_MAX_SEGS | 60 | 5.18 | TSO max segments
IFLA_GSO_IPV4_MAX_SIZE | 63 | 6.2 | GSO IPv4 max size
IFLA_GRO_IPV4_MAX_SIZE | 64 | 6.2 | GRO IPv4 max size

### IFA Constants (Interface Address Attributes)

These constants are defined in `<linux/if_addr.h>` and used for querying/configuring IP addresses.

#### Basic Address Properties (0-8)

Constant | Value | Description
--- | --- | ---
IFA_UNSPEC | 0 | Unspecified/invalid attribute
IFA_ADDRESS | 1 | Interface address (IPv4/IPv6)
IFA_LOCAL | 2 | Local address (for point-to-point)
IFA_LABEL | 3 | Address label/alias
IFA_BROADCAST | 4 | Broadcast address (IPv4 only)
IFA_ANYCAST | 5 | Anycast address (IPv6 only)
IFA_CACHEINFO | 6 | Address lifetime information
IFA_FLAGS | 8 | Extended address flags (32-bit)

#### Recent Additions (9-11) - Kernel 4.20+

Constant | Value | Min Kernel | Description
--- | --- | --- | ---
IFA_RT_PRIORITY | 9 | 4.20 | Route priority for this address
IFA_TARGET_NETNSID | 10 | 5.0 | Target network namespace ID
IFA_PROTO | 11 | 5.1 | Address protocol (how configured)

### Address Flags (IFA_F_*)

These are flag bits used within the IFA_FLAGS attribute:

Flag | Hex Value | Description
--- | --- | ---
IFA_F_SECONDARY | 0x01 | Secondary/alias address (IPv4)
IFA_F_TEMPORARY | 0x01 | Temporary address (IPv6 privacy)
IFA_F_NODAD | 0x02 | Skip Duplicate Address Detection
IFA_F_OPTIMISTIC | 0x04 | Optimistic DAD (usable immediately)
IFA_F_DADFAILED | 0x08 | DAD failed
IFA_F_DEPRECATED | 0x20 | Deprecated address
IFA_F_TENTATIVE | 0x40 | Tentative (DAD in progress)
IFA_F_PERMANENT | 0x80 | Permanent address
IFA_F_MANAGETEMPADDR | 0x100 | Manage temporary addresses
IFA_F_NOPREFIXROUTE | 0x200 | Don't create prefix route
IFA_F_STABLE_PRIVACY | 0x800 | Stable privacy address

### Address Readiness States

The tool computes an address "readiness" state based on interface state and address flags:

State | Symbol | Condition | Meaning
--- | --- | --- | ---
ready | ✓ | Interface UP, no DAD flags | Address is fully operational
pending | ⋯ | TENTATIVE or OPTIMISTIC flag, or link DORMANT | Configuration in progress
failed | ✗ | DADFAILED flag set | Duplicate address detected
down | ○ | Interface DOWN or LOWERLAYERDOWN | Interface not operational

### Operational States (IF_OPER_*)

Value | Name | Description
--- | --- | ---
0 | UNKNOWN | Operational state unknown
1 | NOTPRESENT | Interface not present
2 | DOWN | Interface is down
3 | LOWERLAYERDOWN | Lower layer is down
4 | TESTING | Interface in testing mode
5 | DORMANT | Interface dormant
6 | UP | Interface is up

### Bridge STP States

Value | Name | Description
--- | --- | ---
0 | DISABLED | STP disabled
1 | LISTENING | Port is listening
2 | LEARNING | Port is learning
3 | FORWARDING | Port is forwarding
4 | BLOCKING | Port is blocking

📖 Full Reference:
For complete details on all 64+ IFLA and 11+ IFA constants, including kernel version compatibility and usage examples, refer to the included `IFLA_IFA_REFERENCE.md` document.

## 💡 Advanced Examples

### Scripting and Automation

#### Monitor for New Interfaces

    #!/bin/bash
    # Watch for interface additions/removals

    LAST_COUNT=0

    while true; do
        CURRENT_COUNT=$(sudo python3 device_info.py | jq 'length')

        if [ "$CURRENT_COUNT" -ne "$LAST_COUNT" ]; then
            echo "$(date): Interface count changed: $LAST_COUNT → $CURRENT_COUNT"
            sudo python3 device_info.py --summary
            LAST_COUNT=$CURRENT_COUNT
        fi

        sleep 2
    done

#### Alert on Carrier Loss

    #!/bin/bash
    # Alert when critical interfaces lose carrier

    CRITICAL_IFACES="eth0 eth1"

    for iface in $CRITICAL_IFACES; do
        CARRIER=$(sudo python3 device_info.py | \
                 jq -r ".\"$iface\".carrier // false")

        if [ "$CARRIER" = "false" ]; then
            echo "ALERT: $iface has no carrier!"
            # Send notification, email, etc.
        fi
    done

#### Generate Interface Report

    #!/bin/bash
    # Create comprehensive interface report

    REPORT="/tmp/interface_report_$(date +%Y%m%d_%H%M%S).txt"

    {
        echo "==================================="
        echo "Interface Report - $(date)"
        echo "==================================="
        echo ""

        echo "System Information:"
        echo "  Kernel: $(uname -r)"
        echo "  Hostname: $(hostname)"
        echo ""

        echo "Interface Summary:"
        sudo python3 device_info.py --summary
        echo ""

        echo "==================================="
        echo "Physical Interfaces:"
        echo "==================================="
        sudo python3 device_info.py | \
            jq -r 'to_entries[] | select(.value.kind == null) |
                   "\(.key): \(.value.operstate) - \(.value.mac_address)"'
        echo ""

        echo "==================================="
        echo "Virtual Interfaces:"
        echo "==================================="
        sudo python3 device_info.py | \
            jq -r 'to_entries[] | select(.value.kind != null) |
                   "\(.key): \(.value.kind)"'
        echo ""

        echo "==================================="
        echo "WireGuard Interfaces:"
        echo "==================================="
        sudo python3 device_info.py --wireguard

    } > "$REPORT"

    echo "Report saved to: $REPORT"

### Integration with Monitoring Systems

#### Prometheus Exporter Pattern

    #!/usr/bin/env python3
    # Export metrics in Prometheus format

    import subprocess
    import json
    import sys

    def main():
        result = subprocess.run(
            ['sudo', 'python3', 'device_info.py'],
            capture_output=True,
            text=True
        )

        if result.returncode != 0:
            sys.exit(1)

        interfaces = json.loads(result.stdout)

        # Export carrier status
        for name, info in interfaces.items():
            carrier = 1 if info.get('carrier', False) else 0
            print(f'interface_carrier{{interface="{name}"}} {carrier}')

        # Export MTU
        for name, info in interfaces.items():
            if 'mtu' in info:
                print(f'interface_mtu{{interface="{name}"}} {info["mtu"]}')

        # Export address count
        for name, info in interfaces.items():
            addr_count = len(info.get('addresses', []))
            print(f'interface_addresses{{interface="{name}"}} {addr_count}')

    if __name__ == '__main__':
        main()

#### Nagios/Icinga Check Plugin

    #!/bin/bash
    # Nagios plugin to check interface status

    CRITICAL_IFACES="$1"
    WARNING=""
    CRITICAL=""

    for iface in $CRITICAL_IFACES; do
        DATA=$(sudo python3 device_info.py | jq -r ".\"$iface\"")

        if [ "$DATA" = "null" ]; then
            CRITICAL="$CRITICAL Interface $iface not found."
            continue
        fi

        OPERSTATE=$(echo "$DATA" | jq -r '.operstate')
        CARRIER=$(echo "$DATA" | jq -r '.carrier // false')

        if [ "$OPERSTATE" != "UP" ]; then
            CRITICAL="$CRITICAL $iface is $OPERSTATE."
        elif [ "$CARRIER" = "false" ]; then
            WARNING="$WARNING $iface has no carrier."
        fi
    done

    if [ -n "$CRITICAL" ]; then
        echo "CRITICAL:$CRITICAL"
        exit 2
    elif [ -n "$WARNING" ]; then
        echo "WARNING:$WARNING"
        exit 1
    else
        echo "OK: All interfaces operational"
        exit 0
    fi

### Data Analysis Examples

#### Find Interfaces with Most Carrier Changes

    $ sudo python3 device_info.py | \
      jq -r 'to_entries |
             map({name: .key, changes: .value.carrier_changes // 0}) |
             sort_by(.changes) |
             reverse |
             .[] |
             "\(.name): \(.changes) changes"'

#### List All IPv6 Addresses with DAD State

    $ sudo python3 device_info.py | \
      jq -r 'to_entries[] |
             .key as $iface |
             .value.addresses[] |
             select(.family == "ipv6") |
             "\($iface): \(.address) - \(.readiness)"'

#### Find All Bridge Ports

    $ sudo python3 device_info.py | \
      jq -r 'to_entries[] |
             select(.value.bridge_port != null) |
             "\(.key) → \(.value.master) (STP: \(.value.bridge_port.stp_state))"'