¿ù°£ Àα⠰Խù°

°Ô½Ã¹° 160°Ç
   
htb.init
±Û¾´ÀÌ : ÃÖ°í°ü¸®ÀÚ ³¯Â¥ : 2010-05-25 (È­) 16:14 Á¶È¸ : 4618
±ÛÁÖ¼Ò :
htb.init (32.3K), Down : 6, 2010-05-25 16:14:35
                          

cbq.init¸¦ htb¿ëÀ¸·Î ¼öÁ¤ (ÆÄÀÏ÷ºÎ)

#############################################################################
#!/bin/bash

export LC_ALL=C

### Command locations
#TC=/home/htb/tc
TC=/sbin/tc
IP=/sbin/ip
MP=/sbin/modprobe

### Default filter priorities (must be different)
PRIO_RULE_DEFAULT=${PRIO_RULE:-100}
PRIO_MARK_DEFAULT=${PRIO_MARK:-200}
PRIO_REALM_DEFAULT=${PRIO_REALM:-300}

### Default HTB_PATH & HTB_CACHE settings
HTB_PATH=${HTB_PATH:-/etc/sysconfig/htb}
HTB_CACHE=${HTB_CACHE:-/var/cache/htb.init}

### Uncomment for sed/find with less features (useful for busybox)
#HTB_BASIC="yes"

### Uncomment to enable logfile for debugging
#HTB_DEBUG="/var/run/htb-$1"

### Modules to probe for. Uncomment the last HTB_PROBE
### line if you have QoS support compiled into kernel
HTB_PROBE="sch_htb sch_sfq cls_fw cls_u32 cls_route"
#HTB_PROBE=""

### Config keywords
HTB_QDISC="DEFAULT\|DCACHE\|R2Q"
HTB_CLASS="RATE\|CEIL\|BURST\|CBURST\|PRIO\|LEAF\|MTU"
HTB_CLASS="$HTB_CLASS\|PRIO_RULE\|PRIO_MARK\|PRIO_REALM"
HTB_CLASS="$HTB_CLASS\|LIMIT\|QUANTUM\|PERTURB"
#############################################################################
############################# SUPPORT FUNCTIONS #############################
#############################################################################

if [ -z "$HTB_BASIC" ]; then
 ### List of network devices
 all_device_list () {
  ip link show \
  | sed -n "/^[0-9]/ { s/[[:space:]]//g; \
  s/^[0-9]\+:\([^@-]\+\)\(@.\+\)\?:<.*/\1/; p; }"
 } # all_device_list


 ### Load & filter file $HTB_PATH/$1
 htb_filter_file () {
  sed -n "s/#.*//; s/[^a-zA-Z0-9.,;:=/*-_]\+//g; \
  /^[a-zA-Z0-9]\+=[a-zA-Z0-9.,:;/*-_]\+$/ p" $HTB_PATH/$1
 } # htb_filter_file


 ### Parse class ID chain from file name
 htb_clsid_chain () {
  echo "${1#*-}" \
  | sed -n "/^[0-9a-fA-F]/ { s/^\([0-9a-fA-F:]\+\).*/\1/; \
  s/::/:/g; s/:$//; p; }"
 } # htb_clsid_chain


 ### List of classes in $HTB_PATH
 htb_class_list () {
  for dev in `htb_device_list`; do
   find $HTB_PATH \( -type f -or -type l \) \
   -name "$dev-*" -not -name '*~' -maxdepth 1 \
   -printf "%f\n"| sort
  done
 } # htb_class_list

 ### Gather $1 rules from $CFILE
 htb_cfile_rules () {
  echo "$CFILE"| sed -n "/^$1=/ { s/.*=//; p; }"
 } # htb_cfile_rules


 ### Validate cache against config files
 htb_valid_cache () {
  for dev in `htb_device_list`; do
   [ `find $HTB_PATH \( -type f -or -type l \) \
     -name "$dev*" -maxdepth 1 -newer $HTB_CACHE| \
     wc -l` -gt 0 ] && VALID=0
   [ $VALID -ne 1 ] && break
  done
 } # htb_valid_cache


 ### Find class config for device $1, which is newer than cache
 htb_cache_older () {
  [ `find $HTB_PATH -type f -name "$1*" -maxdepth 1 \
     -newer $HTB_CACHE| wc -l` -gt 0 ] && return 0
  return 1
 } # htb_cache_older


 ### Get current RATE and CEIL
 htb_class_state () {
  tc class show dev $1 \
  | sed -n "s/[[:space:]]\+/ /g; /^class htb 1:$2 / \
  { s/.*rate \(.\+\) burst.*/\1/; p; q; }"
 } # htb_class_state

else ### Less feature-hungry versions of above functions

 all_device_list () {
  ip link show \
  | grep "^[0-9]" \
  | sed "s/[[:space:]]//g; \
  s/^[0-9]\+:\([^@-]\+\)\(@.\+\)\?:<.*/\1/"
 } # all_device_list

 htb_filter_file () {
  sed 's/#.*//; s/[^a-zA-Z0-9.,;:=/*-_]\+//g' $HTB_PATH/$1 \
  | grep '^[a-zA-Z0-9]\+=[a-zA-Z0-9.,;:/*-_]\+$'
 } # htb_filter_file

 htb_clsid_chain () {
  echo "${1#*-}" \
  | grep '^[a-fA-F0-9]' \
  | sed 's/^\([a-fA-F0-9:]\+\).*/\1/; s/::/:/g; s/:$//'
 } # htb_clsid_chain

 htb_class_list () {
  PFX=`echo "$HTB_PATH"| sed 's/\//\\\\\//g'`
  for dev in `htb_device_list`; do
   find $HTB_PATH -type f -name "$dev-*" \
   | grep "^$HTB_PATH/$dev-[^/]\+[^~]$" \
   | sed "s/$PFX\///" \
   | sort
  done
 } # htb_class_list

 htb_cfile_rules () {
  echo "$CFILE"| grep "^$1="| cut -d"=" -f2
 } # htb_cfile_rules

 htb_cache_older () {
  ### cache is always up-to-date
  return 1
 } # htb_cache_older

 htb_class_state () {
  tc class show dev $1 \
  | sed 's/[[:space:]]\+/ /g' \
  | grep "^class htb 1:$2 " \
  | sed 's/.*rate \(.\+\) burst.*/\1/'
 } # htb_class_state
fi # HTB_BASIC


### List of HTB devices
htb_device_list () {
 for dev in `all_device_list`; do
  [ -f $HTB_PATH/$dev ] && echo $dev
 done
} # htb_device_list


### Remove root class from device $1
htb_device_off () {
 tc qdisc del dev $1 root 2> /dev/null
} # htb_device_off


### Remove HTB from all devices
htb_off () {
 for dev in `htb_device_list`; do
  htb_device_off $dev
 done
} # htb_off


### Prefixed message
htb_message () {
 echo -e "**HTB: $@"
} # htb_message

### Failure message
htb_failure () {
 htb_message "$@"
 exit 1
} # htb_failure

### Failure w/htb_off
htb_fail_off () {
 htb_message "$@"
 htb_off
 exit 1
} # htb_fail_off


### Convert time to absolute value
htb_time2abs () {
 local min=${1##*:}; min=${min##0}
 local hrs=${1%%:*}; hrs=${hrs##0}
 echo $[hrs*60 + min]
} # htb_time2abs


### Display traffic control setup
htb_show () {
 for dev in `all_device_list`; do
  [ `tc qdisc show dev $dev| wc -l` -eq 0 ] && continue
  echo -e "### $dev: queueing disciplines\n"
  tc $1 qdisc show dev $dev; echo

  [ `tc class show dev $dev| wc -l` -eq 0 ] && continue
  echo -e "### $dev: traffic classes\n"
  tc $1 class show dev $dev; echo

  [ `tc filter show dev $dev| wc -l` -eq 0 ] && continue
  echo -e "### $dev: filtering rules\n"
  tc $1 filter show dev $dev; echo
 done
} # htb_show

 

### Derive DEVICE, CLASS and PARENT from $1
### Check validity of CLASS and PARENT class IDs
### Load class configuration from $HTP_PATH/$1
### Configure class parameters from CFILE
htb_load_class () {
 DEVICE=${1%%-*}
 CLSIDS=`htb_clsid_chain $1`
 CLASS=${CLSIDS##*:}; [ -z "$CLASS" ] &&
  htb_fail_off "$1 has invalid class ID!"

 [ $[0x$CLASS] -lt 2 -o $[0x$CLASS] -gt 65535 ] &&
  htb_fail_off "class ID of $1 must be in range 0x2-0xFFFF!"

 CLSIDS=${CLSIDS%$CLASS}; CLSIDS=${CLSIDS%:}
 PARENT=${CLSIDS##*:}; [ -n "$PARENT" ] &&
  [ $[0x$PARENT] -lt 2 -o $[0x$PARENT] -gt 65535 ] &&
   htb_fail_off "parent ID of $1 must be in range 0x2-0xFFFF!"

 CFILE=`htb_filter_file $1`


 ### Set defaults & load class
 MTU=""; LEAF=none; PERTURB=10
 RATE=""; BURST=""; CEIL=""; CBURST=""
 PRIO=""; LIMIT=""; QUANTUM=""
 
 PRIO_RULE=$PRIO_RULE_DEFAULT
 PRIO_MARK=$PRIO_MARK_DEFAULT
 PRIO_REALM=$PRIO_REALM_DEFAULT

 eval `echo "$CFILE"| grep "^\($HTB_CLASS\)="`
 RNAME=""; CNAME=""

 ### Resolve RATE if needed
 [ "$RATE" = "prate" ] && RNAME=RATE_$PARENT
 [ "$RATE" = "pceil" ] && RNAME=CEIL_$PARENT
 [ -n "$RNAME" ] && RATE=${!RNAME}

 ### RATE is required
 [ -z "$RATE" ] &&
  htb_fail_off "missing or unresolvable RATE in $1!"

 ### Resolve CEIL if needed
 [ "$CEIL" = "prate" ] && CNAME=RATE_$PARENT
 [ "$CEIL" = "pceil" ] && CNAME=CEIL_$PARENT
 [ -n "$CNAME" ] && CEIL=${!CNAME}

 ### Store CEIL & RATE for children
 eval RATE_$CLASS=$RATE
 eval CEIL_$CLASS=${CEIL:-$RATE}
} # htb_load_class


#############################################################################
#################################### INIT ###################################
#############################################################################

### Check iproute2 tools
[ -x $TC -a -x $IP ] ||
 htb_failure "iproute2 utilities not installed or executable!"

### Check $HTB_PATH directory
[ -d $HTB_PATH -a -r $HTB_PATH -a -x $HTB_PATH ] ||
 htb_failure "$HTB_PATH does not exist or is not readable!"

### ip/tc wrappers
if [ "$1" = "compile" ]; then
 ### no module probing
 HTB_PROBE=""

 ip () {
  $IP "$@"
 } # ip
 
 ### echo-only version of "tc" command
 tc () {
  echo "$TC $@"
 } # tc

elif [ -n "$HTB_DEBUG" ]; then
 echo -e "# `date`" > $HTB_DEBUG

 ### Logging version of "ip" command
 ip () {
  echo -e "\n# ip $@" >> $HTB_DEBUG
  $IP "$@" 2>&1 | tee -a $HTB_DEBUG
 } # ip

 ### Logging version of "tc" command
 tc () {
  echo -e "\n# tc $@" >> $HTB_DEBUG
  $TC "$@" 2>&1 | tee -a $HTB_DEBUG
 } # tc
else
 # default wrappers
 
 ip () {
  $IP "$@"
 } # ip
 
 tc () {
  $TC "$@"
 } # tc
fi # ip/tc wrappers


case "$1" in

#############################################################################
############################### START/COMPILE ###############################
#############################################################################

start|compile)

### Probe QoS modules (start only)
for module in $HTB_PROBE; do
 $MP $module || htb_failure "failed to load module $module"
done

### If we are in compile/nocache/logging mode, don't bother with cache
if [ "$1" != "compile" -a "$2" != "nocache" -a -z "$HTB_DEBUG" ]; then
 VALID=1

 ### validate the cache
 [ "$2" = "invalidate" -o ! -f $HTB_CACHE ] && VALID=0
 [ $VALID -eq 1 ] && for dev in `htb_device_list`; do
  htb_cache_older $dev && VALID=0
  [ $VALID -ne 1 ] && break
 done

 ### compile the config if the cache is invalid
 if [ $VALID -ne 1 ]; then
  $0 compile > $HTB_CACHE ||
   htb_fail_off "failed to compile HTB configuration!"
 fi

 ### run the cached commands
 exec /bin/sh $HTB_CACHE 2> /dev/null
fi


### Setup root qdisc on all configured devices
DEVICES=`htb_device_list`
[ -z "$DEVICES" ] && htb_failure "no configured devices found!"

for dev in $DEVICES; do
 ### Retrieve root qdisc options
 DEFAULT=""; DCACHE=""; R2Q=""
 eval `htb_filter_file $dev| grep "^\($HTB_QDISC\)="`
 [ "$DCACHE" = "yes" ] && DCACHE="dcache" || DCACHE=""

 ### Remove old root qdisc from device
 htb_device_off $dev

 ### Setup root qdisc for the device
 tc qdisc add dev $dev root handle 1 htb \
 default ${DEFAULT:-0} ${R2Q:+r2q $R2Q} $DCACHE ||
  htb_fail_off "failed to set root qdisc on $dev!"

 [ "$1" = "compile" ] && echo
done # dev


### Setup traffic classes (if configured)
for classfile in `htb_class_list`; do
 htb_load_class $classfile

 ### Create the class
 tc class add dev $DEVICE parent 1:$PARENT classid 1:$CLASS \
 htb rate $RATE ${CEIL:+ceil $CEIL} ${BURST:+burst $BURST} \
 ${PRIO:+prio $PRIO} ${CBURST:+cburst $CBURST} ${MTU:+mtu $MTU} ||
  htb_fail_off "failed to add class $CLASS with parent $PARENT on $DEVICE!"

 ### Create leaf qdisc if set
 if [ "$LEAF" != "none" ]; then
  if [ "$LEAF" = "sfq" ]; then
   LEAFPARM="${PERTURB:+perturb $PERTURB} ${QUANTUM:+quantum $QUANTUM}"
  elif [ "$LEAF" = "pfifo" -o "$LEAF" = "bfifo" ]; then
   LEAFPARM="${LIMIT:+limit $LIMIT}"
  else
   htb_fail_off "unknown leaf qdisc ($LEAF) in $classfile!"
  fi

  tc qdisc add dev $DEVICE \
  parent 1:$CLASS handle $CLASS $LEAF $LEAFPARM ||
   htb_fail_off "failed to add leaf qdisc to class $CLASS on $DEVICE!"
 fi


 ### Create fw filter for MARK fields
 for mark in `htb_cfile_rules MARK`; do
  ### Attach fw filter to root class
  tc filter add dev $DEVICE parent 1:0 protocol ip \
  prio $PRIO_MARK handle $mark fw classid 1:$CLASS
 done ### mark

 ### Create route filter for REALM fields
 for realm in `htb_cfile_rules REALM`; do
  ### Split realm into source & destination realms
  SREALM=${realm%%,*}; DREALM=${realm##*,}
  [ "$SREALM" = "$DREALM" ] && SREALM=""

  ### Convert asterisks to empty strings
  SREALM=${SREALM#\*}; DREALM=${DREALM#\*}

  ### Attach route filter to the root class
  tc filter add dev $DEVICE parent 1:0 protocol ip \
  prio $PRIO_REALM route ${SREALM:+from $SREALM} \
  ${DREALM:+to $DREALM} classid 1:$CLASS
 done ### realm

 ### Create u32 filter for RULE fields
 for rule in `htb_cfile_rules RULE`; do
  ### Split rule into source & destination
  SRC=${rule%%,*}; DST=${rule##*,}
  [ "$SRC" = "$rule" ] && SRC=""


  ### Split destination into address, port & mask fields
  DADDR=${DST%%:*}; DTEMP=${DST##*:}
  [ "$DADDR" = "$DST" ] && DTEMP=""

  DPORT=${DTEMP%%/*}; DMASK=${DTEMP##*/}
  [ "$DPORT" = "$DTEMP" ] && DMASK="0xffff"


  ### Split up source (if specified)
  SADDR=""; SPORT=""
  if [ -n "$SRC" ]; then
   SADDR=${SRC%%:*}; STEMP=${SRC##*:}
   [ "$SADDR" = "$SRC" ] && STEMP=""

   SPORT=${STEMP%%/*}; SMASK=${STEMP##*/}
   [ "$SPORT" = "$STEMP" ] && SMASK="0xffff"
  fi


  ### Convert asterisks to empty strings
  SADDR=${SADDR#\*}; DADDR=${DADDR#\*}

  ### Compose u32 filter rules
  u32_s="${SPORT:+match ip sport $SPORT $SMASK}"
  u32_s="${SADDR:+match ip src $SADDR} $u32_s"
  u32_d="${DPORT:+match ip dport $DPORT $DMASK}"
  u32_d="${DADDR:+match ip dst $DADDR} $u32_d"

  ### Uncomment the following if you want to see parsed rules
  #echo "$rule: $u32_s $u32_d"

  ### Attach u32 filter to the appropriate class
  tc filter add dev $DEVICE parent 1:0 protocol ip \
  prio $PRIO_RULE u32 $u32_s $u32_d classid 1:$CLASS
 done ### rule

 [ "$1" = "compile" ] && echo
done ### classfile
;;


#############################################################################
################################# TIME CHECK ################################
#############################################################################

timecheck)

### Get time + weekday
TIME_TMP=`date +%w/%k:%M`
TIME_DOW=${TIME_TMP%%/*}
TIME_NOW=${TIME_TMP##*/}
TIME_ABS=`htb_time2abs $TIME_NOW`

### Check all classes (if configured)
for classfile in `htb_class_list`; do
 ### Load class and gather all TIME rules
 htb_load_class $classfile
 TIMESET=`htb_cfile_rules TIME`
 [ -z "$TIMESET" ] && continue

 MATCH=0; CHANGE=0
 for timerule in $TIMESET; do
  ### Split TIME rule to pieces
  TIMESPEC=${timerule%%;*}; PARAMS=${timerule##*;}
  WEEKDAYS=${TIMESPEC%%/*}; INTERVAL=${TIMESPEC##*/}
  BEG_TIME=${INTERVAL%%-*}; END_TIME=${INTERVAL##*-}

  ### Check the day-of-week (if present)
  [ "$WEEKDAYS" != "$INTERVAL" -a \
    -n "${WEEKDAYS##*$TIME_DOW*}" ] && continue

  ### Compute interval boundaries
  BEG_ABS=`htb_time2abs $BEG_TIME`
  END_ABS=`htb_time2abs $END_TIME`

  ### Midnight wrap fixup
  if [ $BEG_ABS -gt $END_ABS ]; then
   [ $TIME_ABS -le $END_ABS ] &&
    TIME_ABS=$[TIME_ABS + 24*60]

   END_ABS=$[END_ABS + 24*60]
  fi

  ### If time period matches, remember params and set MATCH flag
  if [ $TIME_ABS -ge $BEG_ABS -a $TIME_ABS -lt $END_ABS ]; then
   RATESPEC=${PARAMS%%,*}; CEILSPEC=${PARAMS##*,}
   [ "$RATESPEC" = "$CEILSPEC" ] && CEILSPEC=""

   NEW_RATE=${RATESPEC%%/*}; NEW_BURST=${RATESPEC##*/}
   [ "$NEW_RATE" = "$NEW_BURST" ] && NEW_BURST=""

   NEW_CEIL=${CEILSPEC%%/*}; NEW_CBURST=${CEILSPEC##*/}
   [ "$NEW_CEIL" = "$NEW_CBURST" ] && NEW_CBURST=""

   MATCH=1
  fi
 done ### timerule


 ### Get current RATE and CEIL of a class
 read RATE_NOW JUNK CEIL_NOW <<-EOT
 `htb_class_state $DEVICE $CLASS`
 EOT

 [ -z "$RATE_NOW" -o -z "$CEIL_NOW" ] && continue


 ### Fill empty values if matched
 if [ $MATCH -ne 0 ]; then
  NEW_RATE=${NEW_RATE:-$RATE_NOW}
  NEW_CEIL=${NEW_CEIL:-$CEIL_NOW}

  NEW_BURST=${NEW_BURST:-$BURST}
  NEW_CBURST=${NEW_CBURST:-$CBURST}

 ### Force configured values if not matched
 else
  NEW_RATE=$RATE; NEW_CEIL=$CEIL
  NEW_BURST=$BURST; NEW_CBURST=$CBURST
 fi

 

 ### Check for RATE and CEIL changes
 [ "$RATE_NOW" != "$NEW_RATE" ] && CHANGE=1
 [ "$CEIL_NOW" != "$NEW_CEIL" ] && CHANGE=1

 ### If there are no changes, go for next class
 [ $CHANGE -eq 0 ] && continue


 ### Replace HTB class
 tc class change dev $DEVICE classid 1:$CLASS htb \
 prio $PRIO rate $NEW_RATE ${NEW_CEIL:+ceil $NEW_CEIL} \
 ${NEW_BURST:+burst $NEW_BURST} ${NEW_CBURST:+cburst $NEW_CBURST}

 htb_message "$TIME_NOW: change on $DEVICE:$CLASS ($RATE_NOW/$CEIL_NOW -> $NEW_RATE/$NEW_CEIL)"
done ### class file
;;


#############################################################################
################################## THE REST #################################
#############################################################################

stop)
 htb_off
 ;;

list)
 htb_show
 ;;

stats)
 htb_show -s
 ;;

restart)
 shift
 $0 stop
 $0 start "$@"
 ;;

*)
 echo "Usage: `basename $0` {start|compile|stop|restart|timecheck|list|stats}"
esac


À̸§ Æнº¿öµå
ºñ¹Ð±Û (üũÇÏ¸é ±Û¾´À̸¸ ³»¿ëÀ» È®ÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù.)
¿ÞÂÊÀÇ ±ÛÀÚ¸¦ ÀÔ·ÂÇϼ¼¿ä.
   

 



 
»çÀÌÆ®¸í : ¸ðÁö¸®³× | ´ëÇ¥ : ÀÌ°æÇö | °³ÀÎÄ¿¹Â´ÏƼ : ·©Å°´åÄÄ ¿î¿µÃ¼Á¦(OS) | °æ±âµµ ¼º³²½Ã ºÐ´ç±¸ | ÀüÀÚ¿ìÆí : mojily°ñ¹ðÀÌchonnom.com Copyright ¨Ï www.chonnom.com www.kyunghyun.net www.mojily.net. All rights reserved.