5/31/2020

MII Interface 기반의 ETH 과 udevd 사용 및 테스트

 1. MII interface 기반의 ETH 사용 

요즘 대체적으로 systemd-udevd 기반으로 동작

systemd-udevd   


1.1 udevadm 사용법 


systemd-udevd를 사용을 하면 기본의 udev와 다르게 udevadm으로 쉽게 제어가 가능하므로 우선 본인의 systemd-udevd 사용여부를 파악 
ps로 systemd-udevd가 동작 중인 확인 

  • udevadm 사용법 
$ udevadm -h
udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]

Send control commands or test the device manager.

Commands:
  info          Query sysfs or the udev database
  trigger       Request events from the kernel
  settle        Wait for pending udev events
  control       Control the udev daemon
  monitor       Listen to kernel and udev events
  test          Test an event run
  test-builtin  Test a built-in command 

  • udevadm 기본사용법 및 옵션 
  1.  udevadm [--debug] [--version] [--help] 
  2.  udevadm info [options] [devpath] 
  3.  udevadm trigger [options] [devpath] 
  4.  udevadm settle [options] 
  5.  udevadm control option 
  6.  udevadm monitor [options] 
  7.  udevadm test [options] devpath 
  8.  udevadm test-builtin [options] command devpath   

1.2  ETH의 분석 (MII Interface기반)


network driver는 예전처럼 /dev가 존재하지 않는 것으로 보이며, 어쩔 수 없이 /sys 파일시스템에서 확인을 해야하 하는 것으로 보인다. 

- MII Interface기반이므로 PHY 와 같이 확인 

$ SYSTEMD_LOG_LEVEL=debug udevadm info /sys/class/net/eth0 
or 
$ udevadm info /sys/class/net/eth0   // ETH0 의 세부 정보  
P: /devices/soc0/soc/2100000.aips-bus/2188000.ethernet/net/eth0     // sys filesystem path 
E: DEVPATH=/devices/soc0/soc/2100000.aips-bus/2188000.ethernet/net/eth0
E: ID_NET_DRIVER=fec
E: ID_NET_NAME_MAC=enx26e12cc4c7c6
E: ID_PATH=platform-2188000.ethernet
E: ID_PATH_TAG=platform-2188000_ethernet
E: IFINDEX=2
E: INTERFACE=eth0
E: SUBSYSTEM=net
E: SYSTEMD_ALIAS=/sys/subsystem/net/devices/eth0
E: TAGS=:systemd:
E: USEC_INITIALIZED=6203956



$ udevadm info /sys/class/net/eth0/phydev  // MII Interface PHY 정보 
P: /devices/soc0/soc/2100000.aips-bus/2188000.ethernet/mdio_bus/2188000.ethernet-1/2188000.ethernet-1:01
E: DEVPATH=/devices/soc0/soc/2100000.aips-bus/2188000.ethernet/mdio_bus/2188000.ethernet-1/2188000.ethernet-1:01
E: DEVTYPE=PHY
E: DRIVER=Generic PHY
E: MODALIAS=of:Nethernet-phyT
E: OF_COMPATIBLE_N=0
E: OF_FULLNAME=/soc/aips-bus@2100000/ethernet@2188000/mdio/ethernet-phy@1
E: OF_NAME=ethernet-phy
E: SUBSYSTEM=mdio_bus

이전의 MMC와 동일하게 분석하며 항상 uevent를 찾아 분석하자 
  • N: is for device Name in /dev (e.g /dev/ttyAMA0)
  • S: is for Symlinks to that device name in /dev  (추후 udev/rules/에서 SYMLINK)
  • P: is for device Path in /sys
  • E: is for device properties in udev

1.3 ETH0 의 속성분석 


MII Interface 의 경우, Phy와 Host 사이에 Interrupt를 사용하지 않고 Polling으로 사용하며, udev Hotplug가 미지원으로 파악 
Link 부분을 세부변화 관찰(주의, MII Phy의 Interrupt부분 재확인)  
- WOL_INT(Wake-On-Lan) Interrupt (미사용)
- INT Interrupt(Open Drain) (미사용)

  https://ahyuo79.blogspot.com/2015/02/blog-post_4.html

  • RJ45 연결시 속성값
$ udevadm info -a /sys/class/net/eth0

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/soc0/soc/2100000.aips-bus/2188000.ethernet/net/eth0':       // sys file system 기준이며, 상위 P: Node와 동일 
    KERNEL=="eth0"
    SUBSYSTEM=="net"
    DRIVER==""
    ATTR{addr_assign_type}=="0"
    ATTR{addr_len}=="6"
    ATTR{address}=="26:e1:2c:c4:c7:c6"
    ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
    ATTR{carrier}=="0"      // 현재 Not Connect 
    ATTR{carrier_changes}=="2"
    ATTR{carrier_down_count}=="1"
    ATTR{carrier_up_count}=="1"
    ATTR{dev_id}=="0x0"
    ATTR{dev_port}=="0"
    ATTR{dormant}=="0"
    ATTR{duplex}=="full"
    ATTR{flags}=="0x1003"
    ATTR{gro_flush_timeout}=="0"
    ATTR{ifalias}==""
    ATTR{ifindex}=="2"
    ATTR{iflink}=="2"
    ATTR{link_mode}=="0"
    ATTR{mtu}=="1500"
    ATTR{netdev_group}=="0"
    ATTR{operstate}=="down"   // 현재 Not Connect 
    ATTR{proto_down}=="0"
    ATTR{speed}=="100"
    ATTR{tx_queue_len}=="1000"
    ATTR{type}=="1"

  looking at parent device '/devices/soc0/soc/2100000.aips-bus/2188000.ethernet':
    KERNELS=="2188000.ethernet"
    SUBSYSTEMS=="platform"
    DRIVERS=="fec"
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/soc0/soc/2100000.aips-bus':
    KERNELS=="2100000.aips-bus"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/soc0/soc':
    KERNELS=="soc"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/soc0':
    KERNELS=="soc0"
    SUBSYSTEMS=="soc"
    DRIVERS==""
    ATTRS{family}=="Freescale i.MX"
    ATTRS{revision}=="1.4"
    ATTRS{soc_id}=="i.MX6SX"    

  • RJ45 비연결할 경우 
$ udevadm info -a /sys/class/net/eth0

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/soc0/soc/2100000.aips-bus/2188000.ethernet/net/eth0':
    KERNEL=="eth0"
    SUBSYSTEM=="net"
    DRIVER==""
    ATTR{addr_assign_type}=="0"
    ATTR{addr_len}=="6"
    ATTR{address}=="26:e1:2c:c4:c7:c6"
    ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
    ATTR{carrier}=="1"               // 현재 Connect(up) 상태 
    ATTR{carrier_changes}=="3"      // 현재 Connect(up/down) 상태 변환 Count
    ATTR{carrier_down_count}=="1"  // down count
    ATTR{carrier_up_count}=="2"    // up count 
    ATTR{dev_id}=="0x0"
    ATTR{dev_port}=="0"
    ATTR{dormant}=="0"
    ATTR{duplex}=="full"
    ATTR{flags}=="0x1003"
    ATTR{gro_flush_timeout}=="0"
    ATTR{ifalias}==""
    ATTR{ifindex}=="2"
    ATTR{iflink}=="2"
    ATTR{link_mode}=="0"
    ATTR{mtu}=="1500"
    ATTR{netdev_group}=="0"
    ATTR{operstate}=="up"  // 현재 Connect 상태 
    ATTR{proto_down}=="0"
    ATTR{speed}=="100"
    ATTR{tx_queue_len}=="1000"
    ATTR{type}=="1"

  looking at parent device '/devices/soc0/soc/2100000.aips-bus/2188000.ethernet':
    KERNELS=="2188000.ethernet"
    SUBSYSTEMS=="platform"
    DRIVERS=="fec"
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/soc0/soc/2100000.aips-bus':
    KERNELS=="2100000.aips-bus"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/soc0/soc':
    KERNELS=="soc"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/soc0':
    KERNELS=="soc0"
    SUBSYSTEMS=="soc"
    DRIVERS==""
    ATTRS{family}=="Freescale i.MX"
    ATTRS{revision}=="1.4"
    ATTRS{soc_id}=="i.MX6SX"

  • sys filesystem에서 Ethernet Link 확인 
fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
$ cat /sys/class/net/eth0/carrier        // sys filesystem의 상태 확인 
1

fec 2188000.ethernet eth0: Link is Down
$ cat /sys/class/net/eth0/carrier        // sys filesystem 의 상태확인 
0    

$ networkctl list  // networkctl에서도 감지 
2 eth0         ether    routable    configured

$ networkctl list  // networkctl에서도 감지 
2 eth0         ether    no-carrier    configured

$ networkctl status eth0


/etc/systemd/network/eth0.network에서 DefaultRouteOnDevice=yes 설정하여 상위에서 routable 가능 


1.4 udevadm 으로 uevent 감시 


세부적으로 SUBSYSTEM 값이 "net"이므로, 이를 기반으로 세부적으로 감시했으나, ETH0의 변화가 없음 

$ udevadm -d monitor -p -k -u --subsystem-match=net   // eth0 Hotplug 포인트를 못찾음
calling: monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

fec 2188000.ethernet eth0: Link is Down
fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx



KERNEL[44684.453030] remove   /devices/virtual/net/ppp0 (net)     // 오직 ppp만 찾음 
ACTION=remove
DEVPATH=/devices/virtual/net/ppp0
DEVTYPE=ppp
IFINDEX=9
INTERFACE=ppp0
SEQNUM=2191
SUBSYSTEM=net

UDEV  [44684.474359] remove   /devices/virtual/net/ppp0 (net)
ACTION=remove
DEVPATH=/devices/virtual/net/ppp0
DEVTYPE=ppp
IFINDEX=9
INTERFACE=ppp0
SEQNUM=2191
SUBSYSTEM=net
SYSTEMD_ALIAS=/sys/subsystem/net/devices/ppp0
TAGS=:systemd:
USEC_INITIALIZED=26876345

KERNEL[44690.852770] add      /devices/virtual/net/ppp0 (net)
ACTION=add
DEVPATH=/devices/virtual/net/ppp0
DEVTYPE=ppp
IFINDEX=10
INTERFACE=ppp0
SEQNUM=2192
SUBSYSTEM=net

UDEV  [44690.883719] add      /devices/virtual/net/ppp0 (net)
ACTION=add
DEVPATH=/devices/virtual/net/ppp0
DEVTYPE=ppp
IFINDEX=10
INTERFACE=ppp0
SEQNUM=2192
SUBSYSTEM=net
SYSTEMD_ALIAS=/sys/subsystem/net/devices/ppp0
TAGS=:systemd:
USEC_INITIALIZED=44690865786

$ udevadm monitor /sys/class/net/eth0
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
fec 2188000.ethernet eth0: Link is Down
fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx

2. udev Rule 설정 


아래와 같이 넣어 동작확인을 했지만, 동작되지 않으며 세부감시를 위해서 udev monitor에서 감시했지만, 감시가 안됨 (udev로 control 이 안됨)

$ vi /etc/udev/rules.d/30-eth.rules  // 동작테스트 (실패)
KERNEL=="eth0", SUBSYSTEM=="net", ATTR{carrier}=="0", RUN+="echo hello world" 

$ vi /etc/udev/rules.d/30-eth.rules  // 동작테스트 (실패)
ACTION=="add" KERNEL=="eth0", SUBSYSTEM=="net", ATTR{carrier}=="1", RUN+="echo 11111111" 
ACTION=="remove" KERNEL=="eth0", SUBSYSTEM=="net", ATTR{carrier}=="0", RUN+="echo 22222222" 

// 상위 두개 다 동작이 안됨  udev로 보고가 안됨 MII Phy의 연결된 Interrupt가 udev와 같이 동작되지 않는 것으로 추측
// ATTR{operstate} 로 해도 동일 


/sys/class/net/eth0/operstate  Application C언어 예제 
(Kernel의 rtnetlink.h 사용)
  https://stackoverflow.com/questions/26672414/inotify-add-watch-fails-on-sys-class-net-eth0-operstate#26674239

GPIO의 경우 /sys/class/gpio 로 fopen or open으로 직접 control 하자 
  https://infoarts.tistory.com/21


udev write rules 관련사항
  http://www.reactivated.net/writing_udev_rules.html

udev network rules 관련사항
  https://alwaystinkering.wordpress.com/2016/05/15/udev-network-interface-renaming-with-no-reboot/

3. udev TEST 


$ udevadm control --reload-rules  // 상위에서 만든 Rules 적용했지만 Trigger에서 미동작함 
$ udevadm test /sys/class/net/eth0  //TEST를 진행을 해보면 쉽게 우선순위를 확인가능
calling: test
version 239
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

Load module index
Skipping empty file: /etc/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /etc/udev/rules.d/10-imx.rules
Reading rules file: /etc/udev/rules.d/30-mmc.rules
Reading rules file: /etc/udev/rules.d/40-eth.rules
Reading rules file: /lib/udev/rules.d/50-firmware.rules
Reading rules file: /etc/udev/rules.d/50-ttyACM.rules
Reading rules file: /lib/udev/rules.d/50-udev-default.rules
Reading rules file: /lib/udev/rules.d/60-block.rules
Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /lib/udev/rules.d/60-drm.rules
Reading rules file: /lib/udev/rules.d/60-evdev.rules
Reading rules file: /lib/udev/rules.d/60-input-id.rules
Reading rules file: /lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /lib/udev/rules.d/60-sensor.rules
Reading rules file: /lib/udev/rules.d/60-serial.rules
Reading rules file: /lib/udev/rules.d/64-btrfs.rules
Reading rules file: /lib/udev/rules.d/70-joystick.rules
Reading rules file: /lib/udev/rules.d/70-mouse.rules
Reading rules file: /lib/udev/rules.d/70-power-switch.rules
Reading rules file: /lib/udev/rules.d/70-touchpad.rules
Reading rules file: /lib/udev/rules.d/70-uaccess.rules
Reading rules file: /lib/udev/rules.d/71-seat.rules
Reading rules file: /lib/udev/rules.d/73-seat-late.rules
Reading rules file: /lib/udev/rules.d/75-net-description.rules
Reading rules file: /lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /lib/udev/rules.d/78-sound-card.rules
Reading rules file: /lib/udev/rules.d/80-drivers.rules
Reading rules file: /lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /lib/udev/rules.d/90-alsa-restore.rules
Reading rules file: /lib/udev/rules.d/90-vconsole.rules
Reading rules file: /lib/udev/rules.d/97-hid2hci.rules
Reading rules file: /lib/udev/rules.d/99-systemd.rules
Reading rules file: /etc/udev/rules.d/touchscreen.rules
rules contain 24576 bytes tokens (2048 * 12 bytes), 11301 bytes strings
1619 strings (19672 bytes), 1047 de-duplicated (8944 bytes), 573 trie nodes used
IMPORT builtin 'net_id' /lib/udev/rules.d/75-net-description.rules:6
IMPORT builtin 'path_id' /lib/udev/rules.d/80-net-setup-link.rules:5
IMPORT builtin 'net_setup_link' /lib/udev/rules.d/80-net-setup-link.rules:9
No matching link configuration found.
RUN '/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/$name --prefix=/net/ipv4/neigh/$name --prefix=/net/ipv6/conf/$name --prefix=/net/ipv6/neigh/$name' /lib/udev/rules.d/99-systemd.rules:60
ACTION=add
DEVPATH=/devices/soc0/soc/2100000.aips-bus/2188000.ethernet/net/eth0
ID_NET_DRIVER=fec
ID_NET_NAME_MAC=enx26e12cc4c7c6
ID_PATH=platform-2188000.ethernet
ID_PATH_TAG=platform-2188000_ethernet
IFINDEX=2
INTERFACE=eth0
SUBSYSTEM=net
SYSTEMD_ALIAS=/sys/subsystem/net/devices/eth0
TAGS=:systemd:
USEC_INITIALIZED=6371280
run: '/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/eth0 --prefix=/net/ipv4/neigh/eth0 --prefix=/net/ipv6/conf/eth0 --prefix=/net/ipv6/neigh/eth0'
Unload module index
Unloaded link configuration context.




$ udevadm trigger -c change -a carrier=0 /sys/class/net/eth0   // 변경이 안됨 
$ udevadm trigger -c change -a carrier=1 /sys/class/net/eth0     // 변경이 안됨