diff options
author | Ermal Luçi <eri@pfsense.org> | 2009-03-29 21:18:34 +0000 |
---|---|---|
committer | Ermal Luçi <eri@pfsense.org> | 2009-03-29 21:18:34 +0000 |
commit | b991e3b54ffaa67f39add10783d7a0fd0ea67d46 (patch) | |
tree | 7b3f8d3e8cdd483f9831070f8aa94b07cabd2578 | |
parent | 5f1e1d2617c211ac680a6f56a202d504cdcb6991 (diff) | |
download | pfsense-b991e3b54ffaa67f39add10783d7a0fd0ea67d46.zip pfsense-b991e3b54ffaa67f39add10783d7a0fd0ea67d46.tar.gz |
Add GUI pages for QinQ missed in previous commit.
-rwxr-xr-x | usr/local/www/interfaces_qinq.php | 153 | ||||
-rwxr-xr-x | usr/local/www/interfaces_qinq_edit.php | 406 |
2 files changed, 559 insertions, 0 deletions
diff --git a/usr/local/www/interfaces_qinq.php b/usr/local/www/interfaces_qinq.php new file mode 100755 index 0000000..f14d91a --- /dev/null +++ b/usr/local/www/interfaces_qinq.php @@ -0,0 +1,153 @@ +<?php +/* $Id$ */ +/* + interfaces_qinq.php + Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +##|+PRIV +##|*IDENT=page-interfaces-qinq +##|*NAME=Interfaces: QinQ page +##|*DESCR=Allow access to the 'Interfaces: QinQ' page. +##|*MATCH=interfaces_qinq.php* +##|-PRIV + + +require("guiconfig.inc"); + +if (!is_array($config['qinqs']['qinqentry'])) + $config['qinqs']['qinqentry'] = array(); + +$a_qinqs = &$config['qinqs']['qinqentry']; + +function qinq_inuse($num) { + global $config, $g; + + $iflist = get_configured_interface_list(false, true); + foreach ($iflist as $if) { + if ($config['interfaces'][$if]['if'] == $a_qinqs[$num]['qinqif']) + return true; + } + + return false; +} + +if ($_GET['act'] == "del") { + /* check if still in use */ + if (qinq_inuse($_GET['id'])) { + $input_errors[] = "This QinQ cannot be deleted because it is still being used as an interface."; + } else { + $id = $_GET['id']; + $qinq =& $a_qinqs[$id]; + + $delmembers = explode(" ", $qinq['members']); + if (count($delmembers) > 0) { + foreach ($delmembers as $tag) + mwexec("/usr/sbin/ngctl shutdown vlan{$qinq['tag']}h{$tag}:"); + } + mwexec("/usr/sbin/ngctl shutdown {$qinq['if']}qinq:"); + unset($a_qinqs[$id]); + + write_config(); + + header("Location: interfaces_qinq.php"); + exit; + } +} + + +$pgtitle = array("Interfaces","QinQ"); +include("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td> +<?php + $tab_array = array(); + $tab_array[0] = array("Interface assignments", false, "interfaces_assign.php"); + $tab_array[1] = array("Interface Groups", false, "interfaces_groups.php"); + $tab_array[2] = array("VLANs", false, "interfaces_qinq.php"); + $tab_array[3] = array("QinQs", true, "interfaces_qinq.php"); + $tab_array[4] = array("PPP", false, "interfaces_ppp.php"); + $tab_array[5] = array("GRE", false, "interfaces_gre.php"); + $tab_array[6] = array("GIF", false, "interfaces_gif.php"); + $tab_array[7] = array("Bridges", false, "interfaces_bridge.php"); + $tab_array[8] = array("LAGG", false, "interfaces_lagg.php"); + display_top_tabs($tab_array); +?> + </td></tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="15%" class="listhdrr">Interface</td> + <td width="10%" class="listhdrr">Tag</td> + <td width="20%" class="listhdrr">QinQ members</td> + <td width="45%" class="listhdr">Description</td> + <td width="10%" class="list"></td> + </tr> + <?php $i = 0; foreach ($a_qinqs as $qinq): ?> + <tr> + <td class="listlr"> + <?=htmlspecialchars($qinq['if']);?> + </td> + <td class="listlr"> + <?=htmlspecialchars($qinq['tag']);?> + </td> + <td class="listr"> + <?=htmlspecialchars($qinq['members']);?> + </td> + <td class="listbg"> + <?=htmlspecialchars($qinq['descr']);?> + </td> + <td valign="middle" nowrap class="list"> <a href="interfaces_qinq_edit.php?id=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a> + <a href="interfaces_qinq.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this QinQ?')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + <?php $i++; endforeach; ?> + <tr> + <td class="list" colspan="4"> </td> + <td class="list"> <a href="interfaces_qinq_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + <tr> + <td colspan="3" class="list"><p class="vexpl"><span class="red"><strong> + Note:<br> + </strong></span> + Not all drivers/NICs support 802.1Q QinQ tagging properly. On cards that do not explicitly support it, QinQ tagging will still work, but the reduced MTU may cause problems. See the <?=$g['product_name']?> handbook for information on supported cards. </p> + </td> + <td class="list"> </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/usr/local/www/interfaces_qinq_edit.php b/usr/local/www/interfaces_qinq_edit.php new file mode 100755 index 0000000..aed5d0e --- /dev/null +++ b/usr/local/www/interfaces_qinq_edit.php @@ -0,0 +1,406 @@ +<?php +/* + Copyright (C) 2009 Ermal Luçi + Copyright (C) 2004 Scott Ullrich + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +##|+PRIV +##|*IDENT=page-interfacess-qinq +##|*NAME=Interfaces: QinQ: Edit page +##|*DESCR=Edit Interface qinq +##|*MATCH=interfaces_qinq_edit.php* +##|-PRIV + + +$pgtitle = array("Interfaces","QinQ", "Edit"); + +require("guiconfig.inc"); + +if (!is_array($config['qinqs']['qinqentry'])) + $config['qinqs']['qinqentry'] = array(); + +$a_qinqs = &$config['qinqs']['qinqentry']; + +$portlist = get_interface_list(); + +/* add LAGG interfaces */ +if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) { + foreach ($config['laggs']['lagg'] as $lagg) + $portlist[$lagg['laggif']] = $lagg; +} + +if (count($portlist) < 1) { + header("Location: interfaces_qinq.php"); + exit; +} + +$id = $_GET['id']; +if (isset($_POST['id'])) + $id = $_POST['id']; + +if (isset($id) && $a_qinqs[$id]) { + $pconfig['if'] = $a_qinqs[$id]['if']; + $pconfig['tag'] = $a_qinqs[$id]['tag']; + $pconfig['members'] = $a_qinqs[$id]['members']; + $pconfig['descr'] = html_entity_decode($a_qinqs[$id]['descr']); +/* + $pconfig['autoassign'] = isset($a_qinqs[$id]['autoassign']); + $pconfig['autoenable'] = isset($a_qinqs[$id]['autoenable']); +*/ + $pconfig['autogroup'] = isset($a_qinqs[$id]['autogroup']); + $pconfig['autoadjustmtu'] = isset($a_qinqs[$id]['autoadjustmtu']); +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + if (empty($_POST['tag'])) + $input_errors[] = "First level tag cannot be empty."; + if (isset($id) && $a_qinqs[$id]['tag'] != $_POST['tag']) + $input_errors[] = "You are editing an existing entry and modifying the first level tag is not allowed."; + if (isset($id) && $a_qinqs[$id]['if'] != $_POST['if']) + $input_errors[] = "You are editing an existing entry and modifying the interface is not allowed."; + if (!isset($id)) { + foreach ($a_qinqs as $qinqentry) + if ($qinqentry['tag'] == $_POST['tag'] && $qinqentry['if'] == $_POST['if']) + $input_errors[] = "QinQ level already exists for this interface, edit it!"; + if (is_array($config['vlans']['vlan'])) { + foreach ($config['vlans']['vlan'] as $vlan) + if ($vlan['tag'] == $_POST['tag'] && $vlan['if'] == $_POST['if']) + $input_errors[] = "A normal VLAN exists with this tag please remove it to use this tag for QinQ first level."; + } + } + + $qinqentry = array(); + $qinqentry['if'] = $_POST['if']; + $qinqentry['tag'] = $_POST['tag']; +/* + if ($_POST['autoassign'] == "yes") { + $qinqentry['autoassign'] = true; + if ($_POST['autoenable'] == "yes") + $qinqentry['autoenable'] = true; + if ($_POST['autoadjust'] == "yes") + $qinqentry['autoadjustmtu'] = true; +*/ + if ($_POST['autogroup'] == "yes") + $qinqentry['autogroup'] = true; + + $members = ""; + $isfirst = 0; + /* item is a normal qinqentry type */ + for($x=0; $x<9999; $x++) { + if($_POST["members{$x}"] <> "") { + $member = explode("-", $_POST["members{$x}"]); + if (count($member) > 1) { + if (preg_match("/([^0-9])+/", $member[0], $match) || + preg_match("/([^0-9])+/", $member[1], $match)) + $input_errors[] = "Tags can contain only numbers or a range in format #-#."; + + for ($i = $member[0]; $i < $member[1]; $i++) { + if ($isfirst > 0) + $members .= " "; + $members .= $i; + $isfirst++; + } + } else { + if (preg_match("/([^0-9])+/", $_POST["members{$x}"], $match)) + $input_errors[] = "Tags can contain only numbers or a range in format #-#."; + + if ($isfirst > 0) + $members .= " "; + $members .= $_POST["members{$x}"]; + $isfirst++; + } + } + } + + if (!$input_errors) { + $qinqentry['members'] = $members; + $qinqentry['descr'] = mb_convert_encoding($_POST['descr'],"HTML-ENTITIES","auto"); + $qinqentry['vlanif'] = "vlan{$_POST['tag']}"; + $nmembers = explode(" ", $members); + + if (isset($id) && $a_qinqs[$id]) { + $omembers = explode(" ", $a_qinqs[$id]['members']); + $delmembers = array_diff($omembers, $nmembers); + if (count($delmembers) > 0) { + foreach ($delmembers as $tag) { + mwexec("/usr/sbin/ngctl shutdown vlan{$_POST['tag']}h{$tag}:"); + mwexec("/usr/sbin/ngctl msg vlan{$_POST['tag']}qinq: delfilter \\\"vlan{$_POST['tag']}{$tag}\\\""); + } + } + $addmembers = array_diff($nmembers, $omembers); + if (count($addmembers) > 0) { + foreach ($addmembers as $member) { + $vlan = array(); + $vlan['if'] = "vlan{$_POST['tag']}"; + $vlan['tag'] = $member; + interface_qinq2_configure($vlan); + } + } + $a_qinqs[$id] = $qinqentry; + } else { + interface_qinq_configure($qinqentry); + $a_qinqs[] = $qinqentry; + } + if ($_POST['autogroup'] == "yes") { + if (!is_array($config['ifgroups']['ifgroupentry'])) + $config['ifgroups']['ifgroupentry'] = array(); + foreach ($config['ifgroups']['ifgroupentry'] as $gid => $group) { + if ($group['ifname'] == "QinQ") { + $found = true; + break; + } + } + $additions = ""; + foreach($nmembers as $qtag) + $additions .= "vlan{$qinqentry['tag']}_{$qtag} "; + $additions .= "vlan{$qinqentry['tag']} "; + if ($found == true) + $config['ifgroups']['ifgroupentry'][$gid]['members'] .= " {$additions}"; + else { + $gentry = array(); + $gentry['ifname'] = "QinQ"; + $gentry['members'] = "{$additions}"; + $gentry['descr'] = "QinQ VLANs group"; + $config['ifgroup']['ifgroupentry'][] = $gentry; + } + } + + write_config(); + + header("Location: interfaces_qinq.php"); + exit; + } else { + $pconfig['descr'] = mb_convert_encoding($_POST['descr'],"HTML-ENTITIES","auto"); + $pconfig['tag'] = $_POST['tag']; + $pconfig['members'] = $members; + } +} + +include("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC" onload="<?= $jsevents["body"]["onload"] ?>"> +<?php + include("fbegin.inc"); +?> + +<script type="text/javascript"> +// Global Variables +var rowname = new Array(9999); +var rowtype = new Array(9999); +var newrow = new Array(9999); +var rowsize = new Array(9999); + +for (i = 0; i < 9999; i++) { + rowname[i] = ''; + rowtype[i] = 'select'; + newrow[i] = ''; + rowsize[i] = '30'; +} + +var field_counter_js = 0; +var loaded = 0; +var is_streaming_progress_bar = 0; +var temp_streaming_text = ""; + +var addRowTo = (function() { + return (function (tableId) { + var d, tbody, tr, td, bgc, i, ii, j; + d = document; + tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0); + tr = d.createElement("tr"); + for (i = 0; i < field_counter_js; i++) { + td = d.createElement("td"); + td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input size='" + rowsize[i] + "' class='formfld unknown' name='" + rowname[i] + totalrows + "'></input> "; + tr.appendChild(td); + } + td = d.createElement("td"); + td.rowSpan = "1"; + + td.innerHTML = '<input type="image" src="/themes/' + theme + '/images/icons/icon_x.gif" onclick="removeRow(this);return false;" value="Delete">'; + tr.appendChild(td); + tbody.appendChild(tr); + totalrows++; + }); +})(); + +function removeRow(el) { + var cel; + while (el && el.nodeName.toLowerCase() != "tr") + el = el.parentNode; + + if (el && el.parentNode) { + cel = el.getElementsByTagName("td").item(0); + el.parentNode.removeChild(el); + } +} + + rowname[0] = "members"; + rowtype[0] = "textbox"; + rowsize[0] = "30"; + + rowname[2] = "detail"; + rowtype[2] = "textbox"; + rowsize[2] = "50"; +</script> +<input type='hidden' name='members_type' value='textbox' class="formfld unknown" /> + +<?php if ($input_errors) print_input_errors($input_errors); ?> +<div id="inputerrors"></div> + +<form action="interfaces_qinq_edit.php" method="post" name="iform" id="iform"> +<table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td colspan="2" valign="top" class="listtopic">Interface QinQ Edit</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Parent interface</td> + <td width="78%" class="vtable"> + <select name="if" id="if" class="formselect"> + <?php + foreach ($portlist as $ifn => $ifinfo) { + if (is_jumbo_capable($ifn)) { + echo "<option value=\"{$ifn}\""; + if ($ifn == $pconfig['if']) + echo "selected"; + echo ">"; + echo htmlspecialchars($ifn . " (" . $ifinfo['mac'] . ")"); + echo "</option>"; + } + } + ?> + </select> + <br/> + <span class="vexpl">Only QinQ capable interfaces will be shown.</span></td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">First level tag</td> + <td width="78%" class="vtable"> + <input name="tag" type="text" class="formfld unknown" id="tag" size="10" value="<?=$pconfig['tag'];?>" /> + <br /> + <span class="vexpl"> + This is the first level VLAN tag. On top of this are stacked the member VLANs defined below. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Options</td> + <td width="78%" class="vtable"> +<?php /* ?> + <br/> + <input type="checkbox" value="yes" name="autoassign" id="autoassign" <? if ($pconfig['autoassign']) echo checked;?>/> + <span class="vexpl"> Auto assign interface so it can be configured with ip etc...</span> + <br/> + <input type="checkbox" value="yes" name="autoenable" id="autoenable" <? if ($pconfig['autoenable']) echo checked;?>/> + <span class="vexpl"> Auto enable interface so it can be used on filter rules.</span> + <br/> + <input type="checkbox" value="yes" name="autoadjustmtu" id="autoadjustmtu" <? if ($pconfig['autoadjustmtu']) echo "checked";?>> + <span class="vexpl"> Allows to keep clients mtu unchanged(1500). <br/>NOTE: if you are using jumbo frames this option is not needed and may produce incorrect results!</span> +<?php */ ?> + <br/> + <input name="autogroup" type="checkbox" value="yes" id="autogroup" <? if ($pconfig['autogroup']) echo "checked";?>> + <span class="vexpl"> Adds interface to QinQ interface groups so you can write filter rules easily.</span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Description</td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=$pconfig['descr'];?>" /> + <br /> + <span class="vexpl"> + You may enter a description here for your reference (not parsed). + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq"><div id="membersnetworkport">Member (s)</div></td> + <td width="78%" class="vtable"> + <table id="maintable"> + <tbody> + <tr> + <td><div id="onecolumn">Tag</div></td> + </tr> + + <?php + $counter = 0; + $members = $pconfig['members']; + if ($members <> "") { + $item = explode(" ", $members); + foreach($item as $ww) { + $members = $item[$counter]; + $tracker = $counter; + ?> + <tr> + <td class="vtable"> + <input name="members<?php echo $tracker; ?>" class="formselect" id="members<?php echo $tracker; ?>" value="<? echo $members;?>"> + </td> + <td> + <input type="image" src="/themes/<?echo $g['theme'];?>/images/icons/icon_x.gif" onclick="removeRow(this); return false;" value="Delete" /> + </td> + </tr> +<?php + $counter++; + + } // end foreach + } // end if +?> + </tbody> + <tfoot> + + </tfoot> + </table> + <a onclick="javascript:addRowTo('maintable'); return false;" href="#"> + <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" /> + </a> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="submit" type="submit" class="formbtn" value="Save" /> + <a href="interfaces_qinq.php"><input id="cancelbutton" name="cancelbutton" type="button" class="formbtn" value="Cancel" /></a> + <?php if (isset($id) && $a_qinqs[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>" /> + <?php endif; ?> + </td> + </tr> +</table> +</form> + +<script type="text/javascript"> + field_counter_js = 1; + rows = 1; + totalrows = <?php echo $counter; ?>; + loaded = <?php echo $counter; ?>; +</script> + +<?php include("fend.inc"); ?> +</body> +</html> |