Changeset 2f0141c49bb55157f24738404aa77367a6a45fed

Show
Ignore:
Timestamp:
06/08/09 18:29:43 (3 years ago)
Author:
Neutron Soutmun <neo.neutron@…>
Children:
5987af1b79b0c1fbd4aa9d30a53ec6879853ece3
Parents:
03dc5e370ef4fbf66e34cbe5bc5b878ed764149c
git-committer:
Neutron Soutmun <neo.neutron@…> (06/08/09 18:29:43)
Message:

Implement IFB to replace the IMQ

  • IFB (Intermediate Functional Block) is more clearly work in the SMP.
  • Implement IFB on config, bandwidth task and support scripts.
  • IMQ is now deprecated. (not support).
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • src/rh-config.c

    rebf1b31 r2f0141c  
    1313#include "rahunasd.h" 
    1414#include "rh-config.h" 
     15 
     16GList *interfaces_list = NULL; 
     17static unsigned long ifb_reserved = 0; 
    1518 
    1619enum lcfg_status rahunas_visitor(const char *key, void *data, size_t size,  
     
    346349  return 0; 
    347350} 
     351 
     352 
     353GList *append_interface (GList *inf,  
     354                         const char *inf_name) 
     355{ 
     356  GList *runner = NULL; 
     357  struct interfaces *iface = NULL; 
     358  struct interfaces *item  = NULL; 
     359  int    ifb_ifno; 
     360 
     361  if (!inf_name) 
     362    return inf; 
     363 
     364  item = (struct interfaces *) malloc (sizeof (struct interfaces)); 
     365  if (!item) 
     366    return inf; 
     367 
     368  runner = g_list_first (inf); 
     369  while (runner != NULL) 
     370    { 
     371      iface = (struct interfaces *)runner->data; 
     372      if (strncmp(iface->dev_internal, inf_name, strlen(inf_name)) == 0) 
     373        { 
     374          // Already in the list 
     375          (iface->hit)++; 
     376          free(item);  
     377          return inf; 
     378        } 
     379      runner = g_list_next (runner); 
     380    } 
     381 
     382done: 
     383  ifb_ifno = ifb_interface_reserve (); 
     384  if (ifb_ifno < 0) 
     385    { 
     386      free (item); 
     387      return inf; 
     388    } 
     389 
     390  strncpy(item->dev_internal, inf_name, 32); 
     391  sprintf(item->dev_ifb, "ifb%d", ifb_ifno); 
     392  item->init = 0; 
     393  item->hit  = 1; 
     394  DP ("Interface append: %s, %s", item->dev_internal, item->dev_ifb); 
     395   
     396  return g_list_append (inf, item); 
     397} 
     398 
     399GList *remove_interface (GList *inf, 
     400                         const char *inf_name) 
     401{ 
     402  GList *runner = NULL; 
     403  struct interfaces *iface = NULL; 
     404  int    ifb_ifno; 
     405 
     406  if (!inf_name || !inf) 
     407    return inf; 
     408 
     409  runner = g_list_first (inf); 
     410  while (runner != NULL) 
     411    { 
     412      iface = (struct interfaces *)runner->data; 
     413      if (strncmp (iface->dev_internal, inf_name, strlen (inf_name)) == 0) 
     414        { 
     415          iface->hit--; 
     416          if (iface->hit <=0 ) 
     417            { 
     418              sscanf (iface->dev_ifb, "ifb%d", &ifb_ifno); 
     419              ifb_interface_release (ifb_ifno); 
     420              if (iface) 
     421                free (iface); 
     422 
     423              return g_list_delete_link (inf, runner); 
     424            } 
     425        } 
     426 
     427      runner = g_list_next (runner); 
     428    } 
     429 
     430  return inf; 
     431} 
     432 
     433 
     434struct interfaces *get_interface (GList *inf, 
     435                                  const char *inf_name) 
     436{ 
     437  GList *runner = NULL; 
     438  struct interfaces *iface = NULL; 
     439   
     440  if (!inf_name || !inf) 
     441    return NULL; 
     442 
     443  runner = g_list_first (inf); 
     444 
     445  while (runner != NULL) 
     446    { 
     447      iface = (struct interfaces *) runner->data; 
     448      if (strncmp (iface->dev_internal, inf_name, strlen (inf_name)) == 0) 
     449        return iface; 
     450 
     451      runner = g_list_next (runner); 
     452    }  
     453 
     454  return NULL; 
     455} 
     456 
     457int ifb_interface_reserve (void) 
     458{ 
     459  int i; 
     460  unsigned long mask = 1; 
     461 
     462  for (i=0; i < MAX_IFB_IFACE; i++) 
     463    { 
     464      mask <<= i; 
     465      if (!(ifb_reserved & mask)) 
     466        { 
     467          ifb_reserved |= mask; 
     468          return i; 
     469        }  
     470    } 
     471 
     472  return -1; 
     473} 
     474 
     475void ifb_interface_release (int ifno) 
     476{ 
     477  unsigned long mask = 1; 
     478 
     479  mask <<= ifno; 
     480  mask = ~mask; 
     481  ifb_reserved &= mask; 
     482} 
  • src/rh-config.h

    raace70f r2f0141c  
    2020#define XMLSERVICE_URL  "/rahunas_service/xmlrpc_service.php" 
    2121 
     22#define MAX_IFB_IFACE   64 
     23 
    2224#define CONFIG_FILE RAHUNAS_CONF_DIR "rahunas.conf" 
    2325#define DEFAULT_PID RAHUNAS_RUN_DIR "rahunasd.pid" 
    2426#define DB_NAME "rahunas" 
     27 
     28struct interfaces { 
     29  char dev_internal[32]; 
     30  char dev_ifb[32]; 
     31  int  hit; 
     32  int  init; 
     33}; 
    2534 
    2635struct rahunas_main_config { 
     
    4049  char *dev_external; 
    4150  char *dev_internal; 
     51  struct interfaces *iface; 
    4252  char *vlan; 
    4353  char *vlan_raw_dev_external; 
     
    91101}; 
    92102 
     103extern GList *interfaces_list; 
     104 
    93105int get_config(const char *cfg_file, union rahunas_config *config); 
    94106int get_value(const char *cfg_file, const char *key, void **data, size_t *len); 
     
    98110enum lcfg_status rahunas_visitor(const char *key, void *data, size_t size,  
    99111                                 void *user_data); 
     112 
     113GList *append_interface (GList *inf,  
     114                         const char *inf_name); 
     115GList *remove_interface (GList *inf, 
     116                         const char *inf_name); 
     117struct interfaces *get_interface (GList *inf, 
     118                                  const char *inf_name); 
     119int    ifb_interface_reserve (void); 
     120void    ifb_interface_release (int ifno); 
    100121#endif // __RH_CONFIG_H  
  • src/rh-task-bandwidth.c

    rebf1b31 r2f0141c  
    1818#include "rh-task-memset.h" 
    1919#include "rh-utils.h" 
    20  
    21  
    2220 
    2321#define BANDWIDTH_WRAPPER "/etc/rahunas/bandwidth.sh" 
     
    136134} 
    137135 
    138 int bandwidth_start(void) 
    139 { 
    140   char *args[3]; 
     136int bandwidth_start(struct vserver *vs) 
     137{ 
     138  char *args[5]; 
     139  struct interfaces *iface = vs->vserver_config->iface; 
     140  int  ret; 
    141141 
    142142  DP("Bandwidth: start"); 
     
    144144  args[0] = BANDWIDTH_WRAPPER; 
    145145  args[1] = "start"; 
    146   args[2] = (char *) 0; 
    147  
    148   return bandwidth_exec(NULL, args); 
    149 } 
    150  
    151 int bandwidth_stop(void) 
    152 { 
    153   char *args[3]; 
     146  args[2] = iface->dev_internal; 
     147  args[3] = iface->dev_ifb; 
     148  args[4] = (char *) 0; 
     149 
     150  ret = bandwidth_exec(vs, args); 
     151  return ret;  
     152} 
     153 
     154int bandwidth_stop(struct vserver *vs) 
     155{ 
     156  char *args[5]; 
     157  struct interfaces *iface = vs->vserver_config->iface; 
     158  int  ret; 
    154159 
    155160  DP("Bandwidth: stop"); 
     
    157162  args[0] = BANDWIDTH_WRAPPER; 
    158163  args[1] = "stop"; 
    159   args[2] = (char *) 0; 
    160  
    161   return bandwidth_exec(NULL, args); 
     164  args[2] = iface->dev_internal; 
     165  args[3] = iface->dev_ifb; 
     166  args[4] = (char *) 0; 
     167 
     168  ret = bandwidth_exec(vs, args); 
     169  return ret;  
    162170} 
    163171 
    164172int bandwidth_add(struct vserver *vs, struct bandwidth_req *bw_req) 
    165173{ 
    166   char *args[7]; 
     174  char *args[9]; 
     175  struct interfaces *iface = vs->vserver_config->iface; 
    167176 
    168177  DP("Bandwidth: request %s %s %s %s", bw_req->slot_id,  
     
    175184  args[4] = bw_req->bandwidth_max_down; 
    176185  args[5] = bw_req->bandwidth_max_up; 
    177   args[6] = (char *) 0; 
     186  args[6] = iface->dev_internal; 
     187  args[7] = iface->dev_ifb; 
     188  args[8] = (char *) 0; 
    178189 
    179190  return bandwidth_exec(vs, args); 
     
    182193int bandwidth_del(struct vserver *vs, struct bandwidth_req *bw_req) 
    183194{ 
    184   char *args[4]; 
     195  char *args[6]; 
     196  struct interfaces *iface = vs->vserver_config->iface; 
    185197 
    186198  DP("Bandwidth: request %s", bw_req->slot_id); 
     
    189201  args[1] = "del"; 
    190202  args[2] = bw_req->slot_id; 
    191   args[3] = (char *) 0; 
     203  args[3] = iface->dev_internal; 
     204  args[4] = iface->dev_ifb; 
     205  args[5] = (char *) 0; 
    192206 
    193207  return bandwidth_exec(vs, args); 
     
    197211static int startservice (void) 
    198212{ 
    199   return bandwidth_start(); 
     213  /* Do nothing */ 
    200214} 
    201215 
     
    203217static int stopservice (void) 
    204218{ 
    205   return bandwidth_stop(); 
     219  /* Do nothing */ 
    206220} 
    207221 
     
    209223static void init (struct vserver *vs) 
    210224{ 
    211   /* Do nothing */ 
     225  struct interfaces *iface = NULL; 
     226  if (!vs) 
     227    return; 
     228 
     229  if (vs->vserver_config->init_flag == VS_RELOAD) 
     230    return; 
     231 
     232  interfaces_list = append_interface (interfaces_list,  
     233                                      vs->vserver_config->dev_internal); 
     234  vs->vserver_config->iface = get_interface (interfaces_list,  
     235                                             vs->vserver_config->dev_internal); 
     236  iface = vs->vserver_config->iface; 
     237  if (!iface->init) 
     238    if (bandwidth_start(vs) >= 0) 
     239      iface->init = 1; 
    212240} 
    213241 
     
    215243static int cleanup (struct vserver *vs) 
    216244{ 
    217   /* Do nothing */ 
     245  struct interfaces *iface = NULL; 
     246  if (!vs) 
     247    return; 
     248 
     249  if (vs->vserver_config->init_flag == VS_RELOAD) 
     250    return; 
     251 
     252  iface = vs->vserver_config->iface; 
     253  DP ("Bandwidth Cleanup: init=%d, hit=%d", iface->init, iface->hit); 
     254  if (iface->init && iface->hit <= 1) 
     255    if (bandwidth_stop(vs) >= 0) 
     256      iface->init = 0; 
     257 
     258  interfaces_list = remove_interface (interfaces_list,  
     259                                      vs->vserver_config->dev_internal); 
    218260} 
    219261 
  • tools/bandwidth.sh.in

    r9679928 r2f0141c  
    99TC=/sbin/tc 
    1010IP=/sbin/ip 
     11IFCONFIG=/sbin/ifconfig 
    1112 
    1213INIT=@sysconfdir@/default/rahunas 
     
    1617INTERFACE_SPEED=102400 
    1718 
    18 SHAPING_DOWN_INF=imq0 
    19 SHAPING_UP_INF=imq1 
    20  
    2119INTERFACE_ID=9999 
    2220BITTORRENT_ID=9998 
     
    2927test "$RUN_DAEMON" = "yes" || exit 0 
    3028test -f $RAHUNAS_CONFIG || exit 1 
     29 
     30SHAPING_DOWN_INF="" 
     31SHAPING_UP_INF="" 
    3132 
    3233set -e 
     
    5657 
    5758      # Interface Uplink 
     59      $IFCONFIG $SHAPING_UP_INF up 
    5860      $TC qdisc add dev $SHAPING_UP_INF root handle 2: htb \ 
    5961        default ${INTERFACE_ID}  
    6062      $TC class add dev $SHAPING_UP_INF parent 2: classid 2:${INTERFACE_ID} \ 
    6163        htb rate ${INTERFACE_SPEED}Kbit 
     64 
     65      # Redirect incoming traffic to IFB 
     66      $TC qdisc add dev $SHAPING_DOWN_INF ingress 
     67      $TC filter add dev $SHAPING_DOWN_INF parent ffff: protocol ip prio 2 u32 \ 
     68        match u32 0 0 flowid 1:${INTERFACE_ID} \ 
     69        action mirred egress redirect dev $SHAPING_UP_INF 
    6270      ;; 
    6371  stop) 
     72      # Redirect incoming traffic to IFB 
     73      $TC filter del dev $SHAPING_DOWN_INF parent ffff: protocol ip prio 2 u32 \ 
     74        match u32 0 0 flowid 1:${INTERFACE_ID} \ 
     75        action mirred egress redirect dev $SHAPING_UP_INF 
     76      $TC qdisc del dev $SHAPING_DOWN_INF ingress 
     77 
    6478      # Interface Downlink 
    6579      $TC qdisc del dev $SHAPING_DOWN_INF root 
     
    6781      # Interface Uplink 
    6882      $TC qdisc del dev $SHAPING_UP_INF root 
     83 
     84      $IFCONFIG $SHAPING_UP_INF down 
    6985      ;; 
    7086  esac 
     
    114130 
    115131usage_add() { 
    116   echo "Usage: $1 add ID IP DOWNSPEED UPSPEED" 
     132  echo "Usage: $1 add ID IP DOWNSPEED UPSPEED DOWN_IF UP_IF" 
    117133  echo "         ID - ID number from 1 to 9900" 
    118134  echo "         IP - IPv4 Address" 
    119135  echo "  DOWNSPEED - Download speed (bits/s)" 
    120136  echo "    UPSPEED - Upload speed (bits/s)" 
     137  echo "    DOWN_IF - Downstream interface (eth0, eth1, vlan1, ...)" 
     138  echo "      UP_IF - Upstream interface (ifb0, ifb1, ...)" 
    121139} 
    122140 
    123141usage_del() { 
    124   echo "Usage: $1 del ID" 
     142  echo "Usage: $1 del ID DOWN_IF UP_IF" 
    125143  echo "         ID - ID number from 1 to 9900" 
     144  echo "    DOWN_IF - Downstream interface (eth0, eth1, vlan1, ...)" 
     145  echo "      UP_IF - Upstream interface (ifb0, ifb1, ...)" 
    126146} 
    127147 
     
    175195case "$1" in 
    176196  start) 
    177     start || true  
     197    if [ -z "$2" ] || [ -z "$3" ]; then 
     198      MESSAGE="NOT COMPLETED"   
     199    else 
     200      SHAPING_DOWN_INF=$2 
     201      SHAPING_UP_INF=$3 
     202      RUN=${RUN}-${SHAPING_DOWN_INF}-${SHAPING_UP_INF} 
     203      start || true  
     204    fi 
     205 
    178206    test -n "$MESSAGE" || MESSAGE="NOT COMPLETED" 
    179207    echo $MESSAGE 
    180208    ;; 
    181209  stop) 
    182     stop || true 
     210    if [ -z "$2" ] || [ -z "$3" ]; then 
     211      MESSAGE="NOT COMPLETED"   
     212    else 
     213      SHAPING_DOWN_INF=$2 
     214      SHAPING_UP_INF=$3 
     215      RUN=${RUN}-${SHAPING_DOWN_INF}-${SHAPING_UP_INF} 
     216      stop || true 
     217    fi 
     218 
    183219    test -n "$MESSAGE" || MESSAGE="NOT COMPLETED" 
    184220    echo $MESSAGE 
     
    186222    ;; 
    187223  restart) 
    188     stop || true 
    189     test -n "$MESSAGE" || MESSAGE="NOT COMPLETED" 
    190     echo $MESSAGE 
    191  
    192     start || true 
     224    if [ -z "$2" ] || [ -z "$3" ]; then 
     225      MESSAGE="NOT COMPLETED"   
     226    else 
     227      SHAPING_DOWN_INF=$2 
     228      SHAPING_UP_INF=$3 
     229      RUN=${RUN}-${SHAPING_DOWN_INF}-${SHAPING_UP_INF} 
     230      stop || true 
     231      start || true 
     232    fi 
     233 
    193234    test -n "$MESSAGE" || MESSAGE="NOT COMPLETED" 
    194235    echo $MESSAGE 
     
    201242    fi 
    202243 
    203     if [ $# != 5 ]; then 
     244    if [ $# != 7 ]; then 
    204245      echo "Error: too few arguments" 
    205246      usage_add $N 
     
    207248    fi 
    208249 
    209     bw_add $2 $3 $4 $5 || true 
     250    if [ -z "$6" ] || [ -z "$7" ]; then 
     251      MESSAGE="NOT COMPLETED"   
     252    else 
     253      SHAPING_DOWN_INF=$6 
     254      SHAPING_UP_INF=$7 
     255      RUN=${RUN}-${SHAPING_DOWN_INF}-${SHAPING_UP_INF} 
     256      bw_add $2 $3 $4 $5 || true 
     257    fi 
    210258    echo $MESSAGE 
    211259    ;; 
     
    216264    fi 
    217265 
    218     if [ $# != 2 ]; then 
     266    if [ $# != 4 ]; then 
    219267      echo "Error: too few arguments" 
    220268      usage_del $N 
    221269      exit 1 
    222270    fi 
    223  
    224     bw_del $2 || true 
     271    if [ -z "$3" ] || [ -z "$4" ]; then 
     272      MESSAGE="NOT COMPLETED"   
     273    else 
     274      SHAPING_DOWN_INF=$3 
     275      SHAPING_UP_INF=$4 
     276      RUN=${RUN}-${SHAPING_DOWN_INF}-${SHAPING_UP_INF} 
     277      bw_del $2 || true 
     278    fi 
    225279    echo $MESSAGE 
    226280    ;; 
  • tools/firewall.sh.in

    r03dc5e3 r2f0141c  
    585585      -j CONNMARK --set-mark 2 
    586586  done  
    587    
    588   ## 
    589   # Bandwidth Shaping: IMQ - Intermediate Queueing Device 
    590   ## 
    591   if [ "$BANDWIDTH_SHAPE" = "yes" ]; then 
    592     $IPTABLES -t mangle -I $CHAIN_MANGLE_POSTROUTING $DEV_OUT_PARAM $DEV_INTERNAL -j IMQ --todev 0 
    593     $IPTABLES -t mangle -I $CHAIN_MANGLE_PREROUTING $DEV_IN_PARAM $DEV_INTERNAL -j IMQ --todev 1 
    594   fi 
    595587 
    596588  ##