Реализация связки Dlink DGS-3610-26G + DES-1228G(vlan на клиента) на основе схемы Cisco2 + Zyxel ( DGS-3610-26G + DES-1228G )

Материал из BiTel WiKi

(Различия между версиями)
Перейти к: навигация, поиск
(Новая: <source lang="java"> import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import...)
м (переименовал «Пример 2. реализации шлюза Cisco2( DGS-3610-26G) на BeanShell c управлением telnet» в «[[Реализация связки Dlink DGS-3610-26G + DES-1228G(vlan на клиента) на о)
 
(4 промежуточные версии не показаны)
Строка 1: Строка 1:
 +
Подключение абонентов по схеме "vlan-на-клиента", Это замена стандартной схему Cisco2 +  Zyxel ( DGS-3610-26G + DES-1228G ).
 +
При этом используется оборудование D-Link - на уровне доступа свитчи DES-1228G, в ядре - DGS-3610-26G. 
 +
И еще в отличи от стандартной схемы порты берутся ни из редактора шлюза Zyxel, а универсальный со вкладки порты в договоре .
 +
 +
 +
Управление осуществляется по telnet. К сожалению в используемом
 +
оборудовании функционал "ip unnumbered" реализован не так как в
 +
коммутаторах Cisco, поэтому использовать его не получится. Работать
 +
необходимо используя технологию supervlan. В кратце - эта технология
 +
позволяет задавать допустимые IP-адреса для конкретного vlan, при этом
 +
закрепить можно только диапазон состоящий минимум из 2-х адресов. Например:
 +
            DGS-3610# configure
 +
            DGS-3610(config)# vlan 1000
 +
            DGS-3610(config-vlan)# subvlan-address-range 192.168.100.10 192.168.100.11
 +
            DGS-3610(config-vlan)# end
 +
 +
 +
 +
 +
 +
конфигурация шлюза DGS-3610-26G
 +
 +
<source lang="bash">
 +
user_rule.editor.class=bitel.billing.module.services.ipn.editor.vlan.CiscoVlanContactRuleEditor
 +
gate_manager.class=bitel.billing.server.ipn.vlan.CiscoVlanGateWorker
 +
use.script=1
 +
</source>
 +
 +
Команды шлюза DGS-3610-26G
 +
 +
<source lang="bash">
 +
[DEFAULT]
 +
 +
[REMOVE]
 +
no vlan {VID}
 +
[/REMOVE]
 +
 +
[OPEN]
 +
 +
vlan {VID}
 +
exit
 +
vlan 100
 +
subvlan {VID}
 +
exit
 +
vlan {VID}
 +
subvlan-address-range {addr1} {addr2}
 +
exit
 +
 +
ip access-list extended 101
 +
<LOOP>
 +
no deny ip host {A} any
 +
no deny ip any host {A}
 +
</LOOP>
 +
exit
 +
[/OPEN]
 +
 +
[CLOSE]
 +
interface gigabitethernet 0/22
 +
no ip access-group 101 in
 +
exit
 +
ip access-list extended 101
 +
no permit ip any any
 +
<LOOP>
 +
deny ip host {A} any
 +
deny ip any host {A}
 +
</LOOP>
 +
permit ip any any
 +
exit
 +
interface gigabitethernet 0/22
 +
ip access-group 101 in
 +
exit
 +
[/CLOSE]
 +
[/DEFAULT]
 +
 +
</source>
 +
 +
скрпит шлюза DGS-3610-26G
<source lang="java">
<source lang="java">
import java.io.IOException;
import java.io.IOException;
Строка 22: Строка 99:
import bitel.billing.server.util.telnet.OperationTimedoutException;
import bitel.billing.server.util.telnet.OperationTimedoutException;
import bitel.billing.server.util.telnet.TelnetSession;
import bitel.billing.server.util.telnet.TelnetSession;
-
 
+
import ru.bitel.bgbilling.modules.ipn.common.bean.*;
 +
import bitel.billing.server.util.telnet.ansi.TelnetAnsiSession;
   
   
//includeBGBS( "bgbs://ru.bitel.bgbilling.kernel.script.common.bean.ScriptLibrary/manad" );  
//includeBGBS( "bgbs://ru.bitel.bgbilling.kernel.script.common.bean.ScriptLibrary/manad" );  
Строка 29: Строка 107:
{
{
log.info( "start of cisco........................................................");
log.info( "start of cisco........................................................");
 +
host = gate.getHost();
host = gate.getHost();
port = gate.getPort();
port = gate.getPort();
Строка 49: Строка 128:
   
   
  log.debug("before connect");
  log.debug("before connect");
-
session = new TelnetSession( host, port);
+
session = new TelnetAnsiSession( host, port);
       session.setTimeout( timeout );
       session.setTimeout( timeout );
session.setLoginPromptSequence( ":" );
session.setLoginPromptSequence( ":" );
-
session.connect();
+
result.append( session.connect() );
log.debug("after connect");
log.debug("after connect");
   
   
Строка 76: Строка 155:
   
   
-
log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+
log.info("!!!!!!!!!!!start of log!!!!!!!!!!!!!!!!!!!!!");
log.info( result );
log.info( result );
-
log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+
log.info("!!!!!!!!!!!!!!! end of log !!!!!!!!!!!!!!!!!");
   
   
log.debug( "ok" );
log.debug( "ok" );
Строка 84: Строка 163:
   
   
log.info( "end of cisco........................................................");
log.info( "end of cisco........................................................");
 +
}
}
   
   
Строка 92: Строка 172:
   
   
   
   
-
private void doCommands( TelnetSession session, StringBuffer result, gateSetup) throws IOException, OperationTimedoutException
+
private void doCommands( session, result, gateSetup) throws IOException, OperationTimedoutException
{
{
acl = gateSetup.getStringValue( "acl");
acl = gateSetup.getStringValue( "acl");
-
vlanResult = getVlanResult( session );
+
vlanResult = getVlanResult( session );
 +
    log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!vlanResult!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
 +
log.info( vlanResult );
 +
log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!vlanResult!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
 +
 
aclResult = getAclResult( session, acl );
aclResult = getAclResult( session, acl );
Строка 107: Строка 191:
VlanManager manager = new VlanManager(status.mid, con);  
VlanManager manager = new VlanManager(status.mid, con);  
gateId  = gate.getId();
gateId  = gate.getId();
-
log.info("gateId=" + gateId);
+
//log.info("gateId=" + gateId);
vid = manager.getVlan( gateId, status.contractId );
vid = manager.getVlan( gateId, status.contractId );
-
log.info("vid=" + vid);
+
//log.info("vid=" + vid);
 +
log.debug( "status=" + status.status);
   
   
Строка 124: Строка 209:
addr1 = IPUtils.convertIpToString( range.getAddr1() );
addr1 = IPUtils.convertIpToString( range.getAddr1() );
addr2 = IPUtils.convertIpToString( range.getAddr2() );
addr2 = IPUtils.convertIpToString( range.getAddr2() );
 +
}
 +
else
 +
{
 +
log.info( "empty adress on cid = " + status.contractId );
 +
continue;
}
}
Строка 132: Строка 222:
rules = getOpenRules( status, vid, gateSetup, addr1, addr2, acl );  
rules = getOpenRules( status, vid, gateSetup, addr1, addr2, acl );  
}
}
-
else if (status.status == IPNContractStatus.STATUS_REMOVED && vlanExists(vid, vlanResult) )
+
else if (status.status == IPNContractStatus.STATUS_REMOVED && ( vlanExists(vid, vlanResult) || isUserDenied( addr1, addr2,aclResult)  ) )
{
{
rules = getRemoveRules( status, vid, gateSetup, addr1, addr2, acl );
rules = getRemoveRules( status, vid, gateSetup, addr1, addr2, acl );
}
}
//if closed and etc  
//if closed and etc  
-
else if ( !vlanExists(vid, vlanResult) || !isUserDenied( addr1, addr2, aclResult) )
+
else if ( status.status != IPNContractStatus.STATUS_OPEN && status.status != IPNContractStatus.STATUS_REMOVED && !isUserDenied( addr1, addr2, aclResult) )
{
{
rules = getCloseRules( status, vid, gateSetup, addr1, addr2, acl );
rules = getCloseRules( status, vid, gateSetup, addr1, addr2, acl );
Строка 146: Строка 236:
for ( String rule : rules )
for ( String rule : rules )
{
{
-
log.debug  ("command=" + rule );
+
//log.debug  ("command=" + rule );
result.append(  session.doCommand( rule ) );
result.append(  session.doCommand( rule ) );
}
}
Строка 157: Строка 247:
getOpenRules( status, vid, gateSetup, addr1, addr2, acl )
getOpenRules( status, vid, gateSetup, addr1, addr2, acl )
{
{
-
    return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]", vid, gateSetup, addr1, addr2, acl );
+
  log.debug( "geting open rules...");
 +
return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]", vid, gateSetup, addr1, addr2, acl );
}
}
   
   
getCloseRules( status, vid, gateSetup, addr1, addr2, acl )
getCloseRules( status, vid, gateSetup, addr1, addr2, acl )
{
{
-
    return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]", vid, gateSetup, addr1, addr2, acl );
+
  log.debug( "geting close rules..."); 
 +
return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]", vid, gateSetup, addr1, addr2, acl );
}
}
   
   
getRemoveRules( UserStatus status, vid, gateSetup, addr1, addr2, acl )
getRemoveRules( UserStatus status, vid, gateSetup, addr1, addr2, acl )
-
{
+
{  
-
    return getRules( status, "\\[REMOVE\\](.*)\\[/REMOVE\\]", vid, gateSetup, addr1, addr2, acl );
+
  log.debug( "geting remove rules..."); 
 +
return getRules( status, "\\[REMOVE\\](.*)\\[/REMOVE\\]", vid, gateSetup, addr1, addr2, acl );
}
}
   
   
Строка 173: Строка 266:
{
{
// пользовательское правило, без типа - то все оставляем как есть
// пользовательское правило, без типа - то все оставляем как есть
-
rule = status.rule.getRuleText();
+
CiscoRule  ciscoRule = new CiscoRule ( status.rule.getRuleText() );
-
log.info("rule=" + rule);
+
rule = ciscoRule.getAddresses();
 +
 
 +
//log.info("rule=" + rule);
   
   
//типизированное правило
//типизированное правило
Строка 183: Строка 278:
}
}
   
   
-
log.info("rule=" + rule);
+
//log.info("rule=" + rule);
   
   
   
   
Строка 236: Строка 331:
{
{
//эскейпируем точки в адресе
//эскейпируем точки в адресе
-
String address = addr1.replace( ".", "\\." );
+
String address1 = addr1.replace( ".", "\\." );
-
log.debug( "aaddr1=" + address );
+
String address2 = addr2.replace( ".", "\\." );
 +
 
 +
return isUserDeniedForAddress( address1, buffer ) &&  isUserDeniedForAddress( address2, buffer );
 +
}
 +
 
 +
private isUserDeniedForAddress ( address, buffer)
 +
{
 +
//эскейпируем точки в адресе
 +
//String address = addr1.replace( ".", "\\." );
 +
//log.debug( "aaddr1=" + address );
String template = ".*deny ip host\\s+" + address + "\\s+any.*$";
String template = ".*deny ip host\\s+" + address + "\\s+any.*$";
-
log.debug( "template=" + template );
+
//log.debug( "template=" + template );
Pattern pattern = Pattern.compile( template, Pattern.DOTALL );
Pattern pattern = Pattern.compile( template, Pattern.DOTALL );
Matcher m = pattern.matcher( buffer );
Matcher m = pattern.matcher( buffer );
Строка 260: Строка 364:
}
}
 +
private vlanExists ( vlan, buffer)
private vlanExists ( vlan, buffer)
Строка 281: Строка 386:
return session.doCommand( "show access-lists " + acl );  
return session.doCommand( "show access-lists " + acl );  
}
}
 +
 +
</source>
 +
 +
конфигурация шлюза  Доступа Dlink
 +
 +
<source  lang="bash">
 +
user_rule.editor.class=bitel.billing.module.services.ipn.editor.vlan.CiscoSSHSwitchRuleEditor
 +
gate_manager.class=bitel.billing.server.ipn.vlan.CiscoSSHSwitchGateWorker
 +
use.script=1
 +
</source>
 +
 +
Команды шлюза доступа
 +
<source  lang="bash">
 +
[DEFAULT]
 +
 +
[OPEN]
 +
create vlan vlan{VID} tag {VID}
 +
config vlan vlan{VID} add tagged {UPLINK_PORT}
 +
 +
<LOOP_PORT>
 +
config vlan vlan{VID} add untagged {PORT}
 +
config ports {PORT} description {CONTRACT_NAME}
 +
</LOOP_PORT>
 +
save config
 +
[/OPEN]
 +
 +
[CLOSE]
 +
[/CLOSE]
 +
 +
[REMOVE]
 +
delete vlan vlan{VID}
 +
<LOOP_PORT>
 +
config ports {PORT} clear_description
 +
</LOOP_PORT>
 +
save config
 +
[/REMOVE]
 +
 +
[/DEFAULT]
 +
 +
</source>
 +
 +
Скрипт шлюза доступа
 +
<source  lang="bash">
 +
import java.io.IOException;
 +
import java.util.ArrayList;
 +
import java.util.HashMap;
 +
import java.util.List;
 +
import java.util.Map;
 +
import java.util.StringTokenizer;
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 +
import bitel.billing.common.IPUtils;
 +
import bitel.billing.common.module.ipn.IPNContractStatus;
 +
import bitel.billing.server.ipn.UserStatus;
 +
import bitel.billing.server.ipn.dlink.UserPortStatus;
 +
import bitel.billing.server.util.DefaultServerSetup;
 +
import bitel.billing.server.util.Utils;
 +
import bitel.billing.server.util.telnet.OperationTimedoutException;
 +
import bitel.billing.server.util.telnet.TelnetSession;
 +
import bitel.billing.server.ipn.bean.*;
 +
import bitel.billing.server.contract.bean.*;
 +
import bitel.billing.server.util.telnet.ansi.TelnetAnsiSession;
 +
import ru.bitel.bgbilling.modules.ipn.server.bean.GatePortManager;
 +
 +
protected void doSync()
 +
{
 +
String host = gate.getHost();
 +
int port = gate.getPort();
 +
 +
 +
DefaultServerSetup gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );       
 +
 +
 +
String pswd = gate.getKeyword();
 +
String login = gateSetup.getStringValue( "login");
 +
 +
 +
 +
StringBuffer result = new StringBuffer();
 +
 +
 +
if( log.isDebugEnabled() )
 +
{
 +
    log.debug( gate.getId() + " gate: " + host + ":" + port  + " login: " + login + " pswd: " + pswd );
 +
}
 +
 +
 +
TelnetAnsiSession session = new TelnetAnsiSession( host, port);
 +
session.setLoginPromptSequence( "UserName:" );
 +
 +
log.debug( "before connect" );
 +
result.append( session.connect() );
 +
log.debug( "after connect" );
 +
 +
session.setLoginPromptSequence( ":" );
 +
result.append( session.doCommand( login ) );
 +
log.debug( "after command" );
 +
 +
 +
session.setLoginPromptSequence( "#" );
 +
result.append( session.doCommand( pswd ) );
 +
log.debug( "before pswd" );
 +
 +
log.debug( "execute commands" );
 +
doCommands( session, result, gateSetup);
 +
 +
 +
 +
session.setLoginPromptSequence( "****" );
 +
result.append( session.doCommand( "logout" ) );
 +
 +
 +
log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!! Dlink 3028 !!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
 +
log.info( result.toString() );
 +
log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!! end of Dlink 3028 !!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
 +
 +
 +
 +
log.debug( "ok" );
 +
 +
}
 +
 +
 +
 +
private void doCommands( session, result, DefaultServerSetup gateSetup )
 +
throws IOException, OperationTimedoutException
 +
{
 +
 +
VlanManager manager = new VlanManager(mid, con);
 +
ContractManager cm = new ContractManager( con );
 +
 +
StringBuilder resultCheck = new StringBuilder();
 +
 +
session.setLoginPromptSequence( "All" );
 +
resultCheck.append( session.doCommand("show vlan ports 1-28" ) );
 +
session.setLoginPromptSequence( "#" );
 +
resultCheck.append( session.doCommand("all" ) );
 +
 +
 +
Map vlanPortMap = readPortVlanMap( resultCheck.toString() );
 +
log.debug("!!!!!!!!vlan-port check!!!!!!!!!!!!");
 +
for ( entry : vlanPortMap.entrySet() )
 +
{
 +
log.debug("port " + entry.getKey() );
 +
for ( s :  entry.getValue() )
 +
{
 +
log.debug("vlan " + s );
 +
}
 +
}
 +
log.debug( "!!!!!!!!end vlan-port check!!!!!!!!!!!!" );
 +
 +
 +
 +
  for( UserStatus status : statusList )
 +
{
 +
 +
String addrs = null;
 +
int port = -1 ;
 +
List ports = new GatePortManager( con, mid ).getGatePorts( status.contractId, gate.getId() );
 +
//типизированное правило
 +
if( status.ruleType != null )
 +
{          
 +
rule = status.rule.getRuleText();
 +
 +
addrs = getAddresses( rule );
 +
 +
if ( ports.size() > 0 )
 +
{
 +
          port = ports.get(0);
 +
log.debug( "port=" + port );
 +
          }
 +
}
 +
 +
//берем vlan у родительской циски
 +
int vid = manager.getVlan( gate.getParentId(), status.contractId );
 +
//провереям только один порт
 +
Set vlans = vlanPortMap.get( port );
 +
boolean exists = vlans != null && vlans.contains( vid );
 +
 +
log.debug( "exists=" + exists );
 +
 +
String[] rules = new String[0];
 +
 +
Contract c = cm.getContractByID( status.contractId );
 +
String title = c.getTitle();
 +
 +
if ( status.status == IPNContractStatus.STATUS_OPEN && !exists )
 +
{
 +
rules  = getOpenRules( status, vid, title, gateSetup, addrs, ports );
 +
 +
}
 +
else if ( status.status == IPNContractStatus.STATUS_REMOVED && exists )
 +
{
 +
rules  = getRemoveRules( status, vid, title, gateSetup, addrs, ports );
 +
      }
 +
      //close and etc..пока плевать. т.к они все равно пустые
 +
else
 +
{
 +
rules = getCloseRules( status, vid, title, gateSetup, addrs, ports );
 +
}
 +
 +
for ( String rule : rules )
 +
{
 +
log.debug( "command=" + rule );
 +
          result.append( session.doCommand( rule ) );
 +
}
 +
 +
}   
 +
 +
 +
}
 +
 
 +
private String[]  getOpenRules( UserStatus status, int vid, title, gateSetup, addrs, ports )
 +
{
 +
 +
return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]", vid, title, gateSetup, addrs, ports );
 +
}
 +
 +
private String[]  getCloseRules( UserStatus status, int vid, title, gateSetup, addrs, ports )
 +
{
 +
return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]", vid, title, gateSetup, addrs, ports );
 +
}
 +
 +
private String[]  getRemoveRules( UserStatus status, int vid, title, gateSetup, addrs, ports )
 +
{
 +
return getRules( status, "\\[REMOVE\\](.*)\\[/REMOVE\\]", vid, title, gateSetup, addrs, ports);
 +
}
 +
 +
getRules(  status, template, vid, title, gateSetup, addrs, ports )
 +
{
 +
// пользовательское правило, без типа - то все оставляем как есть
 +
rule = status.rule.getRuleText();
 +
 +
//типизированное правило
 +
if( status.ruleType != null )
 +
{          
 +
      rule = generateRule( addrs, ports, vid, status.gateType, status.ruleType, title, gateSetup );
 +
}
 +
 
 +
  pattern = Pattern.compile( template, Pattern.DOTALL );
 +
m = pattern.matcher( rule );
 +
if (m.find())
 +
{
 +
    rule = m.group( 1 );
 +
}
 +
 +
rule.replaceAll( "\r", "" );
 +
parts  = rule.split( "\n" );
 +
 +
return parts;
 +
}
 +
 +
  generateRule(  addreses, ports, vid, gateType, ruleType, title, gateSetup  )
 +
{
 +
ruleText = ManadUtils.getRule( gateType, ruleType );
 +
 +
replacements =  new HashMap();
 +
 +
if ( vid > 0)
 +
{
 +
replacements.put( "\\{VID\\}", String.valueOf( vid ) );
 +
}
 +
uplink = gateSetup.getIntValue( "uplink.port", 0 );
 +
replacements.put( "\\{UPLINK_PORT\\}", String.valueOf( uplink ) );
 +
replacements.put( "\\{CONTRACT_NAME\\}", title );
 +
 +
loops = ManadUtils.getAddresLoops( addreses );
 +
 +
String [] portArray = new String[ports.size()];
 +
for ( int i = 0; i <  ports.size(); i++ )
 +
{
 +
portArray[i] = String.valueOf( ports.get(i) );
 +
}
 +
 +
//адреса
 +
p = new LoopPattern();
 +
p.setLoopPatern( "LOOP_PORT" );
 +
p.setReplace( "\\{PORT\\}" );
 +
p.setObjects( portArray );
 +
loops.add( p );
 +
 +
 +
 +
return ManadUtils.generateRule( ruleText, replacements, ruleType, loops );
 +
}
 +
 +
 +
String getAddresses( rule  )
 +
{
 +
Map result = new HashMap();
 +
 +
    //порты идут до #, а адреса идут после 
 +
String [] parts  = rule.split( "#" );
 +
 +
addresesStr = "";
 +
 +
if ( parts.length > 1 )
 +
{
 +
  addresesStr = parts[1];
 +
}
 +
 +
/*
 +
portsStr = "";
 +
if ( parts.length > 0 )
 +
{
 +
portsStr = parts[0];
 +
}
 +
 +
 +
portList = new ArrayList();
 +
parts  = portsStr.split( ";" );
 +
 +
for (String part : parts )
 +
{
 +
parts2  = part.split( ":" );
 +
if ( parts2.length <  2)
 +
{
 +
continue;
 +
}
 +
port = parts2 [1];
 +
portList.add( port );
 +
}
 +
 +
String [] ports_ = new String [portList.size()];
 +
for (int i = 0; i < ports_.length; i++)
 +
{
 +
ports_[i] = portList.get( i );
 +
}
 +
 +
result.put( "ports",  ports_);
 +
result.put( "addrs",  addresesStr);
 +
*/
 +
return addresesStr;
 +
}
 +
 +
readPortVlanMap( String data )
 +
{
 +
Map result = new HashMap();
 +
String [] lines = data.split( "\n" );
 +
 +
String templatePort = ".*?Port\\s(\\d+).*?$";
 +
Pattern patternPort = Pattern.compile( templatePort, Pattern.DOTALL );
 +
Matcher m = patternPort.matcher( data );
 +
 +
String templateVlan = ".*?(\\d+)\\s+X.*?$";
 +
Pattern patternVlan = Pattern.compile( templateVlan, Pattern.DOTALL );
 +
 +
 +
 +
int port = 1;
 +
 +
 +
for ( String line : lines )
 +
{
 +
m = patternPort.matcher( line );
 +
if ( m.find() )
 +
{
 +
port = Integer.valueOf( m.group( 1 ) );
 +
continue;
 +
}
 +
 +
m = patternVlan.matcher( line );
 +
if ( m.find() )
 +
{
 +
int vlan = Integer.valueOf( m.group( 1 ) );
 +
Set vlans = result.get( port );
 +
if ( vlans == null )
 +
{
 +
vlans = new HashSet();
 +
result.put( port, vlans );
 +
}
 +
vlans.add( vlan );
 +
}
 +
 +
//2          -        X
 +
 +
 +
}
 +
return result;
 +
}
 +
</source>
</source>

Текущая версия на 06:43, 16 апреля 2010

Подключение абонентов по схеме "vlan-на-клиента", Это замена стандартной схему Cisco2 + Zyxel ( DGS-3610-26G + DES-1228G ). При этом используется оборудование D-Link - на уровне доступа свитчи DES-1228G, в ядре - DGS-3610-26G. И еще в отличи от стандартной схемы порты берутся ни из редактора шлюза Zyxel, а универсальный со вкладки порты в договоре .


Управление осуществляется по telnet. К сожалению в используемом оборудовании функционал "ip unnumbered" реализован не так как в коммутаторах Cisco, поэтому использовать его не получится. Работать необходимо используя технологию supervlan. В кратце - эта технология позволяет задавать допустимые IP-адреса для конкретного vlan, при этом закрепить можно только диапазон состоящий минимум из 2-х адресов. Например:

            DGS-3610# configure
            DGS-3610(config)# vlan 1000
            DGS-3610(config-vlan)# subvlan-address-range 192.168.100.10 192.168.100.11
            DGS-3610(config-vlan)# end



конфигурация шлюза DGS-3610-26G

user_rule.editor.class=bitel.billing.module.services.ipn.editor.vlan.CiscoVlanContactRuleEditor
gate_manager.class=bitel.billing.server.ipn.vlan.CiscoVlanGateWorker
use.script=1

Команды шлюза DGS-3610-26G

[DEFAULT]
 
[REMOVE]
no vlan {VID}
[/REMOVE]
 
[OPEN]
 
vlan {VID}
exit
vlan 100
subvlan {VID}
exit
vlan {VID}
subvlan-address-range {addr1} {addr2}
exit
 
ip access-list extended 101
<LOOP>
no deny ip host {A} any
no deny ip any host {A}
</LOOP>
exit
[/OPEN]
 
[CLOSE]
interface gigabitethernet 0/22
no ip access-group 101 in
exit
ip access-list extended 101
no permit ip any any
<LOOP>
deny ip host {A} any
deny ip any host {A}
</LOOP>
permit ip any any
exit
interface gigabitethernet 0/22
ip access-group 101 in
exit
[/CLOSE]
[/DEFAULT]

скрпит шлюза DGS-3610-26G

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.StringTokenizer;
 
import bitel.billing.common.module.ipn.IPNContractStatus;
import bitel.billing.server.ipn.GateWorker;
import bitel.billing.server.ipn.UserStatus;
import bitel.billing.server.ipn.bean.*;
import bitel.billing.server.util.DefaultServerSetup;
import bitel.billing.server.util.Utils;
import bitel.billing.server.util.telnet.OperationTimedoutException;
import bitel.billing.server.util.telnet.TelnetSession;
import ru.bitel.bgbilling.common.DefaultSetup;
import bitel.billing.common.IPUtils;
import bitel.billing.server.util.Utils;
import bitel.billing.server.util.telnet.OperationTimedoutException;
import bitel.billing.server.util.telnet.TelnetSession;
import ru.bitel.bgbilling.modules.ipn.common.bean.*;
import bitel.billing.server.util.telnet.ansi.TelnetAnsiSession;
 
//includeBGBS( "bgbs://ru.bitel.bgbilling.kernel.script.common.bean.ScriptLibrary/manad" ); 
 
protected void doSync()
{
		log.info( "start of cisco........................................................");
 
		host = gate.getHost();
		port = gate.getPort();
 
 
		DefaultServerSetup gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );        
 
		pswd = gate.getKeyword();		
		login = gateSetup.getStringValue( "login");
       timeout = gateSetup.getIntValue( "timeout", 0 );		
 
		result = new StringBuffer();
 
 
		if( log.isDebugEnabled() )
		{
		    log.debug( gate.getId() + " gate: " + host + ":" + port  + " login: " + login + " passwd: " + 		 pswd );
		}
 
 
 		log.debug("before connect");
		session = new TelnetAnsiSession( host, port);
       session.setTimeout( timeout );
		session.setLoginPromptSequence( ":" );						
		result.append( session.connect() );
		log.debug("after connect");
 
		result.append( session.doCommand( login ) );
		log.debug("after login");
		session.setLoginPromptSequence( "#" );
		result.append( session.doCommand( pswd ) );
		log.debug("after pswd");
 
		result.append( session.doCommand( "terminal length 0" ) );
		result.append( session.doCommand( "terminal width 0" ) );
 
		log.debug("after terminal");
 
		result.append( session.doCommand( "configure terminal" ) );
 
		log.debug( "execute commands" );
		doCommands( session, result, gateSetup );
 
		result.append( session.doCommand( "exit" ) );
		result.append( session.doCommand( "write memory" ) );
		session.doCommandAsync( "exit" );
 
 
		log.info("!!!!!!!!!!!start of log!!!!!!!!!!!!!!!!!!!!!");
		log.info( result );
		log.info("!!!!!!!!!!!!!!! end of log !!!!!!!!!!!!!!!!!");		
 
		log.debug( "ok" );
 
 
	log.info( "end of cisco........................................................");
 
}
 
protected void add()
{
 
}
 
 
private void doCommands( session, result, gateSetup) throws IOException, OperationTimedoutException
{		
	acl = gateSetup.getStringValue( "acl");
 
	vlanResult = getVlanResult( session );	
    log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!vlanResult!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );	
	log.info( vlanResult );	
	log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!vlanResult!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );	
 
	aclResult = getAclResult( session, acl );
 
	log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!aclResult!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );	
	log.info( aclResult );	
	log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!! end aclResult!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );	
 
	for( UserStatus status : statusList )
	{
		VlanManager manager = new VlanManager(status.mid, con); 
		gateId  = gate.getId();
		//log.info("gateId=" + gateId);
		vid = manager.getVlan( gateId, status.contractId );
		//log.info("vid=" + vid);	
		log.debug( "status=" + status.status);	
 
 
		String addr1 = null;
		String addr2 = null;
 
   		date = new GregorianCalendar();
 
		AddressRangeManager man = new AddressRangeManager( con, mid );
   		addressList = man.getContractAddressRange( status.contractId , date, -1 );
   		if ( addressList.size() > 0 )
   		{
        	AddressRange range =  addressList.get(0);
			addr1 = IPUtils.convertIpToString( range.getAddr1() );
			addr2 = IPUtils.convertIpToString( range.getAddr2() );	
		}
		else
		{
			log.info( "empty adress on cid = " + status.contractId );
			continue;
		}
 
 
		rules = null;
		if (status.status == IPNContractStatus.STATUS_OPEN && (!vlanExists(vid, vlanResult) ||  isUserDenied( addr1, addr2, aclResult) ) )
		{ 
			rules = getOpenRules( status, vid, gateSetup, addr1, addr2, acl ); 
		} 			
		else if (status.status == IPNContractStatus.STATUS_REMOVED && ( vlanExists(vid, vlanResult) || isUserDenied( addr1, addr2,aclResult)  ) )
		{
			rules = getRemoveRules( status, vid, gateSetup, addr1, addr2, acl );	
		}
		//if closed and etc 
		else if ( status.status != IPNContractStatus.STATUS_OPEN && status.status != IPNContractStatus.STATUS_REMOVED &&  !isUserDenied( addr1, addr2, aclResult) )
		{
			rules = getCloseRules( status, vid, gateSetup, addr1, addr2, acl );
		}
 
		if (vid > 0 && rules != null )
		{
			for ( String rule : rules )
			{					
				//log.debug  ("command=" + rule );
				result.append(  session.doCommand( rule ) );				
			}
		}
 
	}		
 
}
 
getOpenRules( status, vid, gateSetup, addr1, addr2, acl )
{
   log.debug( "geting open rules..."); 
	return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]", vid, gateSetup, addr1, addr2, acl );
}
 
getCloseRules( status, vid, gateSetup, addr1, addr2, acl )
{
   log.debug( "geting close rules...");  
	return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]", vid, gateSetup, addr1, addr2, acl );
}
 
getRemoveRules( UserStatus status, vid, gateSetup, addr1, addr2, acl )
{    
   log.debug( "geting remove rules...");  
	return getRules( status, "\\[REMOVE\\](.*)\\[/REMOVE\\]", vid, gateSetup, addr1, addr2, acl );
}
 
getRules(  status, template, vid, gateSetup, addr1, addr2, acl )
{
	// пользовательское правило, без типа - то все оставляем как есть
	CiscoRule  ciscoRule = new CiscoRule ( status.rule.getRuleText() );
	rule = ciscoRule.getAddresses();
 
	//log.info("rule=" + rule);
 
	//типизированное правило
	if( status.ruleType != null )
 
	{	
	    rule = generateRule( rule, status.gateType, status.ruleType, vid, status.contractId, gateSetup, addr1, addr2, acl );
	}
 
	//log.info("rule=" + rule);
 
 
 
	pattern = Pattern.compile( template, Pattern.DOTALL );
	m = pattern.matcher( rule );
	if (m.find())
	{
	    rule = m.group( 1 );
	}		
 
	rule.replaceAll( "\r", "" );
 
 
	parts  = rule.split( "\n" );
 
	result = new ArrayList();
	for ( String part : parts )
	{
		if ( !Utils.isEmptyString( part ))
		{
			result.add( part );
		}
	}
 
	return result;
}		
 
generateRule( addresses, gateType, ruleType, int vid, int cid, gateSetup, addr1, addr2, acl )
{		
 		 supervlan = gateSetup.getIntValue( "supervlan", 0 );
 
		 Map replacements = new HashMap();
 
        if ( addr1 != null && addr2 != null )
		 {
			replacements.put( "\\{addr1\\}", addr1 );
			replacements.put( "\\{addr2\\}", addr2 );
			replacements.put( "\\{SUPERVLAN\\}", String.valueOf( supervlan) );
			replacements.put( "\\{ACL\\}", acl );
		 }
 
    ruleText = ManadUtils.getRule( gateType, ruleType );
    if ( vid > 0)
    {
        replacements.put( "\\{VID\\}", String.valueOf( vid ) );
    }
    return ManadUtils.generateRule( ruleText, addresses, replacements, ruleType );		
}
 
private isUserDenied ( addr1, addr2, buffer)
{
	//эскейпируем точки в адресе
	String address1 = addr1.replace( ".", "\\." );
	String address2 = addr2.replace( ".", "\\." );
 
	return isUserDeniedForAddress( address1, buffer ) &&  isUserDeniedForAddress( address2, buffer );
}
 
private isUserDeniedForAddress ( address, buffer)
{
	//эскейпируем точки в адресе
	//String address = addr1.replace( ".", "\\." );
	//log.debug( "aaddr1=" + address );
	String template = ".*deny ip host\\s+" + address + "\\s+any.*$";
	//log.debug( "template=" + template );
	Pattern pattern = Pattern.compile( template, Pattern.DOTALL );
	Matcher m = pattern.matcher( buffer );
	boolean found = m.find();
	if ( found ) 
	{
		log.debug( "user2 denied" );
		return true;
	}
 
 
 
	pattern = Pattern.compile( ".*deny ip any host\\s" + address + "\\s.*$", Pattern.DOTALL );
	m = pattern.matcher( buffer );
	found = m.find();
	log.debug( found ? "user denied" :"user not denied" );	
 
 
	return found;
 
}
 
 
private vlanExists ( vlan, buffer)
{
	Pattern pattern = Pattern.compile( ".*" + vlan + "\\s+ON\\s+.*", Pattern.DOTALL );
	Matcher m = pattern.matcher( buffer );
	found = m.find();
	log.debug( found ? "vlan found" : "vlan not found" );
 
 
	return found;
}
 
private getVlanResult( session )
{
	return session.doCommand( "show supervlan"); 
}
 
private getAclResult( session, acl )
{
	return session.doCommand( "show access-lists " + acl ); 
}

конфигурация шлюза Доступа Dlink

user_rule.editor.class=bitel.billing.module.services.ipn.editor.vlan.CiscoSSHSwitchRuleEditor
gate_manager.class=bitel.billing.server.ipn.vlan.CiscoSSHSwitchGateWorker
use.script=1

Команды шлюза доступа

[DEFAULT]
 
[OPEN]
create vlan vlan{VID} tag {VID}
config vlan vlan{VID} add tagged {UPLINK_PORT}
 
<LOOP_PORT>
config vlan vlan{VID} add untagged {PORT}
config ports {PORT} description {CONTRACT_NAME}
</LOOP_PORT>
save config
[/OPEN]
 
[CLOSE]
[/CLOSE]
 
[REMOVE]
delete vlan vlan{VID}
<LOOP_PORT>
config ports {PORT} clear_description
</LOOP_PORT>
save config
[/REMOVE]
 
[/DEFAULT]

Скрипт шлюза доступа

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import bitel.billing.common.IPUtils;
import bitel.billing.common.module.ipn.IPNContractStatus;
import bitel.billing.server.ipn.UserStatus;
import bitel.billing.server.ipn.dlink.UserPortStatus;
import bitel.billing.server.util.DefaultServerSetup;
import bitel.billing.server.util.Utils;
import bitel.billing.server.util.telnet.OperationTimedoutException;
import bitel.billing.server.util.telnet.TelnetSession;
import bitel.billing.server.ipn.bean.*;
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.util.telnet.ansi.TelnetAnsiSession;
import ru.bitel.bgbilling.modules.ipn.server.bean.GatePortManager;
 
protected void doSync()
{
		String host = gate.getHost();
		int port = gate.getPort();
 
 
		DefaultServerSetup gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );        
 
 
		String pswd = gate.getKeyword();
		String login = gateSetup.getStringValue( "login");
 
 
 
		StringBuffer result = new StringBuffer();
 
 
		if( log.isDebugEnabled() )
		{
		    log.debug( gate.getId() + " gate: " + host + ":" + port  + " login: " + login + " pswd: " + 		pswd );
		}
 
 
		TelnetAnsiSession session = new TelnetAnsiSession( host, port);
		session.setLoginPromptSequence( "UserName:" );						
 
		log.debug( "before connect" );
		result.append( session.connect() );
		log.debug( "after connect" );
 
 		session.setLoginPromptSequence( ":" );						
		result.append( session.doCommand( login ) );
		log.debug( "after command" );
 
 
		session.setLoginPromptSequence( "#" );
		result.append( session.doCommand( pswd ) );
		log.debug( "before pswd" );
 
		log.debug( "execute commands" );
		doCommands( session, result, gateSetup);
 
 
 
		session.setLoginPromptSequence( "****" );
		result.append( session.doCommand( "logout" ) );
 
 
		log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!! Dlink 3028 !!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
		log.info( result.toString() );
		log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!! end of Dlink 3028 !!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
 
 
 
		log.debug( "ok" );
 
}
 
 
 
private void doCommands( session, result, DefaultServerSetup gateSetup ) 
throws IOException, OperationTimedoutException
{
 
	VlanManager manager = new VlanManager(mid, con); 
	ContractManager cm = new ContractManager( con );
 
	StringBuilder resultCheck = new StringBuilder();			
 
	session.setLoginPromptSequence( "All" );
	resultCheck.append( session.doCommand("show vlan ports 1-28" ) );
	session.setLoginPromptSequence( "#" );
	resultCheck.append( session.doCommand("all" ) );
 
 
	Map vlanPortMap = readPortVlanMap( resultCheck.toString() );
	log.debug("!!!!!!!!vlan-port check!!!!!!!!!!!!");		
	for ( entry : vlanPortMap.entrySet() )
	{
		log.debug("port " + entry.getKey() );
		for ( s :  entry.getValue() )
		{
			log.debug("vlan " + s );
		}
	}
	log.debug( "!!!!!!!!end vlan-port check!!!!!!!!!!!!" );
 
 
 
   for( UserStatus status : statusList )
	{
 
		String addrs = null;
		int port = -1 ;
		List ports = new GatePortManager( con, mid ).getGatePorts( status.contractId, gate.getId() );
		//типизированное правило
		if( status.ruleType != null )	
		{			       	    
			rule = status.rule.getRuleText();
 
			addrs = getAddresses( rule );
 
			if ( ports.size() > 0 )
			{
          		port = ports.get(0);
				log.debug( "port=" + port );
          }
		}
 
		//берем vlan у родительской циски 
		int vid = manager.getVlan( gate.getParentId(), status.contractId );
		//провереям только один порт
		Set vlans = vlanPortMap.get( port );
		boolean exists = vlans != null && vlans.contains( vid );
 
		log.debug( "exists=" + exists );
 
		String[] rules = new String[0];
 
		Contract c = cm.getContractByID( status.contractId );
		String title = c.getTitle();
 
		if ( status.status == IPNContractStatus.STATUS_OPEN && !exists )
		{
			rules  = getOpenRules( status, vid, title, gateSetup, addrs, ports );
 
		}
		else if ( status.status == IPNContractStatus.STATUS_REMOVED && exists )
		{
			rules  = getRemoveRules( status, vid, title, gateSetup, addrs, ports );
       }
       //close and etc..пока плевать. т.к они все равно пустые 
		else 
		{
			rules = getCloseRules( status, vid, title, gateSetup, addrs, ports ); 
		}										
 
		for ( String rule : rules )
		{
			log.debug( "command=" + rule );
          result.append( session.doCommand( rule ) );	
		}
 
	}     
 
 
}
 
private String[]  getOpenRules( UserStatus status, int vid, title, gateSetup, addrs, ports )
{
 
	return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]", vid, title, gateSetup, addrs, ports );
}
 
private String[]  getCloseRules( UserStatus status, int vid, title, gateSetup, addrs, ports )
{
	return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]", vid, title, gateSetup, addrs, ports );
}
 
private String[]  getRemoveRules( UserStatus status, int vid, title, gateSetup, addrs, ports )
{
	return getRules( status, "\\[REMOVE\\](.*)\\[/REMOVE\\]", vid, title, gateSetup, addrs, ports);
}
 
getRules(  status, template, vid, title, gateSetup, addrs, ports )
{
	// пользовательское правило, без типа - то все оставляем как есть
	rule = status.rule.getRuleText();	
 
	//типизированное правило
	if( status.ruleType != null )	
	{			       	    
       rule = generateRule( addrs, ports, vid, status.gateType, status.ruleType, title, gateSetup );
	}
 
   pattern = Pattern.compile( template, Pattern.DOTALL );
	m = pattern.matcher( rule );
	if (m.find())
	{
	    rule = m.group( 1 );
	}		
 
	rule.replaceAll( "\r", "" );
	parts  = rule.split( "\n" );
 
	return parts;
}		
 
   generateRule(  addreses, ports, vid, gateType, ruleType, title, gateSetup  )
	{		
		ruleText = ManadUtils.getRule( gateType, ruleType );
 
		replacements =  new HashMap();
 
		if ( vid > 0)
		{
			replacements.put( "\\{VID\\}", String.valueOf( vid ) );				
		}
		uplink = gateSetup.getIntValue( "uplink.port", 0 );
		replacements.put( "\\{UPLINK_PORT\\}", String.valueOf( uplink ) );
		replacements.put( "\\{CONTRACT_NAME\\}", title );
 
		loops = ManadUtils.getAddresLoops( addreses );
 
		String [] portArray = new String[ports.size()];
		for ( int i = 0; i <  ports.size(); i++ )
		{
			portArray[i] = String.valueOf( ports.get(i) );
		}
 
		//адреса
		p = new LoopPattern();		
		p.setLoopPatern( "LOOP_PORT" );
		p.setReplace( "\\{PORT\\}" );
		p.setObjects( portArray );		
		loops.add( p );
 
 
 
		return ManadUtils.generateRule( ruleText, replacements, ruleType, loops );		
	}
 
 
	String getAddresses( rule  )
	{
		Map result = new HashMap();		 
 
		    //порты идут до #, а адреса идут после  
		String [] parts  = rule.split( "#" );
 
		addresesStr = "";	 
 
		if ( parts.length > 1 )
		{
		   addresesStr = parts[1];
		}
 
		/*
		portsStr = "";
		if ( parts.length > 0 )
		{
			portsStr = parts[0];
		}
 
 
		portList = new ArrayList();
		parts  = portsStr.split( ";" );
 
		for (String part : parts )
		{
			parts2  = part.split( ":" );
			if ( parts2.length <  2)
			{
				continue;
			}
			port = parts2 [1];
			portList.add( port );
		}
 
		String [] ports_ = new String [portList.size()];
		for (int i = 0; i < ports_.length; i++)
		{
			ports_[i] = portList.get( i );
		}
 
		result.put( "ports",  ports_);
		result.put( "addrs",  addresesStr);
		*/
		return addresesStr;
	}
 
	readPortVlanMap( String data )
	{
		Map result = new HashMap();
		String [] lines = data.split( "\n" );
 
		String templatePort = ".*?Port\\s(\\d+).*?$";		
		Pattern patternPort = Pattern.compile( templatePort, Pattern.DOTALL );
		Matcher m = patternPort.matcher( data );
 
		String templateVlan = ".*?(\\d+)\\s+X.*?$";	
		Pattern patternVlan = Pattern.compile( templateVlan, Pattern.DOTALL );
 
 
 
		int port = 1;
 
 
		for ( String line : lines )
		{
			m = patternPort.matcher( line );
			if ( m.find() ) 
			{						
				 port = Integer.valueOf( m.group( 1 ) );
				 continue;
			}
 
			m = patternVlan.matcher( line );
			if ( m.find() )
			{
				int vlan = Integer.valueOf( m.group( 1 ) );
				Set vlans = result.get( port );
				if ( vlans == null )
				{
					vlans = new HashSet();
					result.put( port, vlans );
				}
				vlans.add( vlan );
			}
 
			 //2          -        X 
 
 
		}
		return result;
	}
Личные инструменты