# openrc -- prioritize services in a runlevel?

## 1clue

Hi,

I have a box with 7 nics.  I've renamed the interfaces according to the physical location of the port on the box.  The problem is, when I list ip addresses they show up out of order.

I'm setting this box up as a VM host which will contain 2 firewalls of different operating systems and an IPS and VPN, so I have each NIC attached to a bridge and a tap.

ip address list | grep -v '^ ' | wgetpaste is here:  https://bpaste.net/show/6595315b12d4

I'd like to show in this order:

lo

cnet0

lan0-lan6 (in numerical order)

tap0-tap6 (in numerical order)

br0-br6 (in numerical order)

The lan interfaces show up in the same order they did by default, but the names are not intuitive, they're using enp4s0, enp0s20f0-3, enp5s0f0-1. I think it's listing them in order of the PCI bus being scanned during boot.

Is there a way to get them to show up in my preferred order?

Thanks.

----------

## NeddySeagoon

1clue,

```
ip address list | grep -v '^ ' | sort 
```

 helps a bit but that's lexical order.

You can tell udev not to apply 'persistent' device names like enp4s0, enp0s20f0-3 and so on.

You can even assign MAC address based interface names of your own choosing, you need to write udev rules.

That's probably safer that using kernel assigned names, which are allocated in interface discovery order.

There is supposed to be a race condition that makes kernel assigned names non deterministic.  That might be an issue with seven NICs

In the good old days, udev used to to do MAC based interface names by default.

----------

## khayyam

 *1clue wrote:*   

> I'd like to show in this order: lo
> 
> cnet0
> 
> lan0-lan6 (in numerical order)
> ...

 

1clue ... if I understand correctly, you mean start in a certain order? If so then see the 'rc_foo_after' example in /etc/rc.conf ... so, eg:

```
rc_net_lan0_after="net.cnet0"

rc_net_lan1_after="net.lan0"

rc_net_lan2_after="net.lan1"
```

... untested, but that, along with 'before', 'need', etc, is the method.

best ... khay

----------

## 1clue

Guys,

I mean that I want to change the order they're listed in, and sort won't work because all the entries are multi-line.

I've already renamed the interfaces according to the physical order on the board. Both the old ethN and the persistent enp* names are scrambled with respect to physical order on the board. 

I can't do the initialization order because different custom runlevels will have different sets of nics enabled.

I suspect what I'm trying for won't happen.

Thanks.

----------

## khayyam

 *1clue wrote:*   

> I mean that I want to change the order they're listed in, and sort won't work because all the entries are multi-line.

 

1clue ... in which case I don't understand the subject line: "openrc -- prioritize services in a runlevel".

 *Quote:*   

> I can't do the initialization order because different custom runlevels will have different sets of nics enabled.

 

You can using /etc/conf.d/net.{iface}.{runlevel} ... but I'm really not sure what it is your asking.

best ... khay

----------

## Cyker

Sorry, trying to clarify what you mean; Are you saying everything is right (Names, IP addresses etc), just the order they appear when you list them is wrong?

----------

## 1clue

@Cyker,

Yes.

I realize there's probably no way to convince the system to rearrange the default listing order, so it's a dead end.

The persistent interface names were indecipherable.  Past tense.

The old eth* network names were in random physical order on the board (meaning looking at the back of the computer, they hopped around.  Past tense.

I renamed the interfaces to lan0-lan6 and cnet0 (which is a maintenance-only nic by my choice, will not have Internet access.)

I'm investigating a way to sort the interfaces with multi-line output, so that IP addresses and such follow the nic correctly.

I'm fine with writing a script to do this, just gotta have time to do it.

Thanks.

----------

## 1clue

In case anyone's interested this is my solution.

It's a bit of a hack but it works for my purposes.  The 'iplist' script could be replaced with 'ip address list'

```

# Collect interfaces in an array.  'lo' will be first so we exclude it here.

readarray -t NOLO <<< `ip link list | grep '^[0-9]*:' | sed 's/^[0-9]*: \([^:@]*\)..*/\1/'\ | grep -v '^lo$' | sort`

# iplist is a scripted pipe which sanitizes public IP addresses for use on forums, and hilights inet and inet6.

echo "`iplist lo`"

I=2

for nic in ${NOLO[@]}

do

   # sanitize and renumber the interface as we print it

   echo "`iplist $nic` | sed 's/^[0-9]*/$I/'"

   ((I++))

done

```

----------

## khayyam

1clue ... I see, by "list" you mean the output of 'ip' ... a few possible improvements:

```
#!/bin/bash

readarray -t NOLO <<< $(ip link show | awk '!/^1/&&/^[0-9]/{gsub(/:/,"") ; print $2}' | sort)

ip link show lo

i=2

for nic in ${NOLO[@]} ; do

    ip link show $nic | sed "s/^[0-9]/$i/"

    ((i++))

done
```

BTW, I'm supprised yours works with single quotes because sed will treat '$I' literally.

best ... khay

----------

## 1clue

Khayyam,

Sed doesn't see $I.  Bash does.  Bash sees the outer double quote and performs its substitutions, then passing the value to sed.

Interesting changes, I'll look closer.

Thanks.

----------

## khayyam

 *1clue wrote:*   

> Sed doesn't see $I.  Bash does.  Bash sees the outer double quote and performs its substitutions, then passing the value to sed.

 

1clue ... that is not the case ...

```
$ var=foo ; echo "$(echo ba | sed 's/ba/$var/')"

$var

$ var=foo ; echo "$(echo ba | sed "s/ba/$var/")"

foo
```

 *1clue wrote:*   

> Interesting changes, I'll look closer. Thanks.

 

You're welcome & best ... khay

----------

## 1clue

Khayyam,

I posted a working script. I've been doing it that way for more than a decade.

You can explain it some other way if you want. Let me know if you figure it out.

----------

## khayyam

 *1clue wrote:*   

> I posted a working script. I've been doing it that way for more than a decade. You can explain it some other way if you want. Let me know if you figure it out.

 

1clue ... ok, well, here is your script exactly as posted, the only change made is substituing 'iplist' for 'ip address list'.

```
readarray -t NOLO <<< `ip link list | grep '^[0-9]*:' | sed 's/^[0-9]*: \([^:@]*\)..*/\1/'\ | grep -v '^lo$' | sort

 

echo "`ip address list lo`" 

I=2

for nic in ${NOLO[@]} ; do

   echo "`ip address list $nic` | sed 's/^[0-9]*/$I/'"

   ((I++))

done
```

... and here the output of 'bash ./script'

```
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo

       valid_lft forever preferred_lft forever

8: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000

    link/ether 00:01:41:27:44:c6 brd ff:ff:ff:ff:ff:ff

    inet 192.168.2.14/24 brd 192.168.2.255 scope global wlan0

       valid_lft forever preferred_lft forever | sed 's/^[0-9]*/2/'
```

Let me know when you're ready to accept valid criticism ...

best ... khay

----------

## 1clue

You're right.  I must have been pretty tired.

My inner script, iplist, shows the interfaces numbered correctly, my outer script (the one I showed) shows the interfaces in order but with wrong numbers.  I didn't notice the inconsistency.  I was going off the idea that:

```

X="It's a wonderful world!"

echo "X is '$X'"

```

prints out 

```
X is 'It's a wonderful world!'
```

Corrected script:

```

#!/bin/bash

function scrub {

        ip address list $1 | sed 's/my:ipv6:prefix/ea7:dead:beef/g'

}

function colorize {

        egrep --color '^|inet|inet6|ea7:dead:beef'

}

readarray -t NOLO <<< `ip link list | grep '^[0-9]*:' | sed 's/^[0-9]*: \([^:@]*\)..*/\1/'\ | grep -v '^lo$' | sort`

LOLO=('lo')

scrub lo | colorize

I=2

for nic in ${NOLO[@]}

do

        scrub $nic | sed "s/^[0-9][0-9]*/$I/" | colorize

        ((I++))

done

```

Corrected script output:

```

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo

       valid_lft forever preferred_lft forever

2: br0@NONE: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default 

    link/ether 0c:c4:7a:16:8d:7e brd ff:ff:ff:ff:ff:ff

3: br1@NONE: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default 

    link/ether 0c:c4:7a:16:8d:7f brd ff:ff:ff:ff:ff:ff

4: br2@NONE: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 

    link/ether 0c:c4:7a:16:a5:ca brd ff:ff:ff:ff:ff:ff

5: br3@NONE: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default 

    link/ether 0c:c4:7a:16:a5:cb brd ff:ff:ff:ff:ff:ff

6: br4@NONE: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default 

    link/ether 0c:c4:7a:16:a5:c8 brd ff:ff:ff:ff:ff:ff

7: br5@NONE: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default 

    link/ether 0c:c4:7a:16:a5:c9 brd ff:ff:ff:ff:ff:ff

8: cnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000

    link/ether 0c:c4:7a:16:a6:7e brd ff:ff:ff:ff:ff:ff

    inet 192.168.1.253/24 brd 192.168.1.255 scope global cnet0

       valid_lft forever preferred_lft forever

    inet6 ea7:dead:beef:6fc:ec4:7aff:fe16:a67e/64 scope global mngtmpaddr dynamic 

       valid_lft 2539088sec preferred_lft 551888sec

    inet6 fe80::ec4:7aff:fe16:a67e/64 scope link 

       valid_lft forever preferred_lft forever

9: lan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br0 state DOWN group default qlen 1000

    link/ether 0c:c4:7a:16:8d:7e brd ff:ff:ff:ff:ff:ff

10: lan1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br1 state DOWN group default qlen 1000

    link/ether 0c:c4:7a:16:8d:7f brd ff:ff:ff:ff:ff:ff

11: lan2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br2 state UP group default qlen 1000

    link/ether 0c:c4:7a:16:a5:ca brd ff:ff:ff:ff:ff:ff

12: lan3: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br3 state DOWN group default qlen 1000

    link/ether 0c:c4:7a:16:a5:cb brd ff:ff:ff:ff:ff:ff

13: lan4: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br4 state DOWN group default qlen 1000

    link/ether 0c:c4:7a:16:a5:c8 brd ff:ff:ff:ff:ff:ff

14: lan5: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br5 state DOWN group default qlen 1000

    link/ether 0c:c4:7a:16:a5:c9 brd ff:ff:ff:ff:ff:ff

15: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default 

    link/sit 0.0.0.0 brd 0.0.0.0

16: tap0@NONE: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state LOWERLAYERDOWN group default qlen 500

    link/ether ce:17:45:12:1a:b5 brd ff:ff:ff:ff:ff:ff

17: tap1@NONE: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br1 state LOWERLAYERDOWN group default qlen 500

    link/ether 16:00:d6:49:44:1e brd ff:ff:ff:ff:ff:ff

18: tap2@NONE: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br2 state LOWERLAYERDOWN group default qlen 500

    link/ether 2a:c9:6f:00:79:a3 brd ff:ff:ff:ff:ff:ff

19: tap3@NONE: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br3 state LOWERLAYERDOWN group default qlen 500

    link/ether 8a:e9:eb:28:e2:37 brd ff:ff:ff:ff:ff:ff

20: tap4@NONE: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br4 state LOWERLAYERDOWN group default qlen 500

    link/ether 2a:64:ca:e0:b6:36 brd ff:ff:ff:ff:ff:ff

21: tap5@NONE: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br5 state LOWERLAYERDOWN group default qlen 500

    link/ether d2:ba:6e:9a:e7:34 brd ff:ff:ff:ff:ff:ff

```

----------

