On Thu, 12 Sep 2019 03:48:06 +0900 "Daniel T. Lee" <[email protected]> wrote:
> This commit adds CIDR parsing and IP validate helper function to parse > single IP or range of IP with CIDR. (e.g. 198.18.0.0/15) > > Helpers will be used in prior to set target address in samples/pktgen. > > Signed-off-by: Daniel T. Lee <[email protected]> > --- > samples/pktgen/functions.sh | 122 ++++++++++++++++++++++++++++++++++++ > 1 file changed, 122 insertions(+) > > diff --git a/samples/pktgen/functions.sh b/samples/pktgen/functions.sh > index 4af4046d71be..8be5a6b6c097 100644 [...] > +# Given a single IP(v4/v6) or CIDR, return minimum and maximum IP addr. > +function parse_addr() > +{ > + # check function is called with (funcname)6 > + [[ ${FUNCNAME[1]: -1} == 6 ]] && local IP6=6 > + local bitlen=$[ IP6 ? 128 : 32 ] > + local octet=$[ IP6 ? 16 : 8 ] > + > + local addr=$1 > + local net prefix > + local min_ip max_ip > + > + IFS='/' read net prefix <<< $addr > + [[ $IP6 ]] && net=$(extend_addr6 $net) > + validate_addr$IP6 $net > + > + if [[ $prefix -gt $bitlen ]]; then > + err 5 "Invalid prefix: $prefix" > + elif [[ -z $prefix ]]; then > + min_ip=$net > + max_ip=$net > + else > + # defining array for converting Decimal 2 Binary > + # 00000000 00000001 00000010 00000011 00000100 ... > + local d2b='{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}' > + [[ $IP6 ]] && d2b+=$d2b > + eval local D2B=($d2b) I must say this is a rather cool shell/bash trick to use an array for converting decimal numbers into binary. > + > + local shift=$[ bitlen-prefix ] Using a variable named 'shift' is slightly problematic for shell/bash code. It works, but it is just confusing. > + local min_mask max_mask > + local min max > + local ip_bit > + local ip sep > + > + # set separator for each IP(v4/v6) > + [[ $IP6 ]] && sep=: || sep=. > + IFS=$sep read -ra ip <<< $net > + > + min_mask="$(printf '1%.s' $(seq $prefix))$(printf '0%.s' $(seq > $shift))" > + max_mask="$(printf '0%.s' $(seq $prefix))$(printf '1%.s' $(seq > $shift))" Also a surprising shell trick to get binary numbers out of a prefix number. > + > + # calculate min/max ip with &,| operator > + for i in "${!ip[@]}"; do > + digit=$[ IP6 ? 16#${ip[$i]} : ${ip[$i]} ] > + ip_bit=${D2B[$digit]} > + > + idx=$[ octet*i ] > + min[$i]=$[ 2#$ip_bit & 2#${min_mask:$idx:$octet} ] > + max[$i]=$[ 2#$ip_bit | 2#${max_mask:$idx:$octet} ] > + [[ $IP6 ]] && { min[$i]=$(printf '%X' ${min[$i]}); > + max[$i]=$(printf '%X' ${max[$i]}); } > + done > + > + min_ip=$(IFS=$sep; echo "${min[*]}") > + max_ip=$(IFS=$sep; echo "${max[*]}") > + fi > + > + echo $min_ip $max_ip > +} If you just fix the variable name 'shift' to something else, then I'm happy with this patch. Again, I'm very impressed with your shell/bash skills, I were certainly challenged when reviewing this :-) -- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
